commit dfd50a0b241fa31c63db680999f464b36e73ace9 Author: Joachim Schoeberl Date: Thu Jan 9 09:19:48 2014 +0000 create 5.2 branch diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..d91a2489 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Joachim Schoeberl diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..02a4a074 --- /dev/null +++ b/INSTALL @@ -0,0 +1,167 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +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. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Type `make install' to install the programs and any data files and + documentation. + + 4. You can remove the program binaries and object files from the + source code directory by typing `make clean'. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as 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 `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + 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 +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +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. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..8df03fd9 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,10 @@ +ACLOCAL_AMFLAGS = -I m4 + +METASOURCES = AUTO + +SUBDIRS = libsrc ng tutorials doc windows nglib +# nglib +# TESTS = ng/netgen -batchmode + + + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 00000000..db92bb22 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,802 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = . +DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure AUTHORS ChangeLog INSTALL NEWS TODO \ + config.guess config.sub depcomp install-sh ltmain.sh missing \ + mkinstalldirs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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@ +ACLOCAL_AMFLAGS = -I m4 +METASOURCES = AUTO +SUBDIRS = libsrc ng tutorials doc windows nglib +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then rm -f stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \ + dist-zip distcheck distclean distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck 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 \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-recursive uninstall uninstall-am + +# nglib +# TESTS = ng/netgen -batchmode + +# 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/NEWS b/NEWS new file mode 100644 index 00000000..e69de29b diff --git a/TODO b/TODO new file mode 100644 index 00000000..e69de29b diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 00000000..d972e15f --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,977 @@ +# generated automatically by aclocal 1.11.3 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file 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. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file 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. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.3], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.3])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file 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. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file 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. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file 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. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file 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. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file 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. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file 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. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file 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. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file 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. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file 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. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file 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. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file 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. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file 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. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file 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. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) +m4_include([m4/tcl.m4]) diff --git a/config.guess b/config.guess new file mode 100755 index 00000000..d622a44e --- /dev/null +++ b/config.guess @@ -0,0 +1,1530 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..1b506b31 --- /dev/null +++ b/config.h.in @@ -0,0 +1,80 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `floor' function. */ +#undef HAVE_FLOOR + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the `matherr' function. */ +#undef HAVE_MATHERR + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `pow' function. */ +#undef HAVE_POW + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Are we building against Mac OS X TkAqua? */ +#undef MAC_OSX_TK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/config.sub b/config.sub new file mode 100755 index 00000000..c894da45 --- /dev/null +++ b/config.sub @@ -0,0 +1,1773 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 00000000..4b978a7b --- /dev/null +++ b/configure @@ -0,0 +1,19190 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.68 for netgen 5.2-dev. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='netgen' +PACKAGE_TARNAME='netgen' +PACKAGE_VERSION='5.2-dev' +PACKAGE_STRING='netgen 5.2-dev' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' + +ac_default_prefix="/opt/netgen" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +NGMKL_FALSE +NGMKL_TRUE +NGGUI_FALSE +NGGUI_TRUE +NGLIB_FALSE +NGLIB_TRUE +LIBGLU +TOGL_WINDOWINGSYSTEM +TOGLLIBDIR +TK_INCLUDES +TCL_INCLUDES +TK_XINCLUDES +TK_LIBS +TK_STUB_LIB_SPEC +TK_STUB_LIB_FLAG +TK_STUB_LIB_FILE +TK_LIB_SPEC +TK_LIB_FLAG +TK_LIB_FILE +TK_SRC_DIR +TK_BIN_DIR +TK_VERSION +TCL_SHLIB_LD_LIBS +TCL_LD_FLAGS +TCL_EXTRA_CFLAGS +TCL_DEFS +TCL_LIBS +CLEANFILES +TCL_STUB_LIB_SPEC +TCL_STUB_LIB_FLAG +TCL_STUB_LIB_FILE +TCL_LIB_SPEC +TCL_LIB_FLAG +TCL_LIB_FILE +TCL_SRC_DIR +TCL_BIN_DIR +TCL_PATCH_LEVEL +TCL_VERSION +PKG_CFLAGS +PKG_LIBS +PKG_INCLUDES +PKG_HEADERS +PKG_TCL_SOURCES +PKG_STUB_OBJECTS +PKG_STUB_SOURCES +PKG_STUB_LIB_FILE +PKG_LIB_FILE +CYGPATH +FFMPEG_LIBS +FFMPEG_INCLUDES +JPEGLIB_LIBS +JPEGLIB_INCLUDES +MPI_LIBS +MPI_INCLUDES +OCCLIBS +OCCFLAGS +CXXCPP +CPP +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +DLLTOOL +OBJDUMP +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +EGREP +GREP +SED +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +ac_ct_CC +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +LIBTOOL +OPENMP_CXXFLAGS +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CXX +CPPFLAGS +LDFLAGS +CXXFLAGS +CXX +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_static +enable_dependency_tracking +enable_openmp +enable_shared +with_pic +enable_fast_install +with_gnu_ld +with_sysroot +enable_libtool_lock +enable_occ +with_occ +with_togl +enable_nglib +enable_gui +with_metis +enable_parallel +enable_jpeglib +enable_ffmpeg +enable_mkl +with_tcl +with_tk +with_tclinclude +with_tkinclude +' + ac_precious_vars='build_alias +host_alias +target_alias +CXX +CXXFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCC +CC +CFLAGS +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures netgen 5.2-dev to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/netgen] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of netgen 5.2-dev:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-static[=PKGS] build static libraries [default=no] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --disable-openmp do not use OpenMP + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --enable-occ compile with OpenCascade geometry kernel + --enable-nglib generate shared library nglib + --disable-gui don't build netgen with GUI + --enable-parallel enable mpi parallelization + --enable-jpeglib enable snapshots using library libjpeg + --enable-ffmpeg enable video recording with FFmpeg, uses libavcodec + --enable-mkl link Intel's mkl library, necessary for ngsolve and + mkl 11.x + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot=DIR Search for dependent libraries within DIR + (or the compiler's sysroot if not specified). + --with-occ=dir use OpenCascade installed in directory dir + --with-togl=dir directory containing libTogl1.7 + --with-metis=dir path to metis 5.x + --with-tcl directory containing tcl configuration + (tclConfig.sh) + --with-tk directory containing tk configuration (tkConfig.sh) + --with-tclinclude directory containing the public Tcl header files + --with-tkinclude directory containing the public Tk header files + +Some influential environment variables: + CXX C++ compiler command + CXXFLAGS C++ compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CC C compiler command + CFLAGS C compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +netgen configure 5.2-dev +generated by GNU Autoconf 2.68 + +Copyright (C) 2010 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_cxx_try_compile LINENO +# ---------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_compile + +# ac_fn_cxx_try_link LINENO +# ------------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_link + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_cxx_try_cpp LINENO +# ------------------------ +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_cxx_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_cxx_try_cpp + +# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES +# --------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_cxx_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_header_mongrel + +# ac_fn_cxx_check_func LINENO FUNC VAR +# ------------------------------------ +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_cxx_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_cxx_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by netgen $as_me 5.2-dev, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='netgen' + VERSION='5.2-dev' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + + + + + + + + + +# AC_HEADER_STDC +ac_config_headers="$ac_config_headers config.h" + +# Check whether --enable-static was given. +if test "${enable_static+set}" = set; then : + enableval=$enable_static; p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_static=no +fi + + + + + + + + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 +$as_echo_n "checking whether the C++ compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C++ compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 +$as_echo_n "checking for C++ compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C++ compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if ${ac_cv_cxx_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if ${ac_cv_prog_cxx_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +else + CXXFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + +else + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + ac_cv_prog_cxx_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CXX_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + + + OPENMP_CXXFLAGS= + # Check whether --enable-openmp was given. +if test "${enable_openmp+set}" = set; then : + enableval=$enable_openmp; +fi + + if test "$enable_openmp" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CXX option to support OpenMP" >&5 +$as_echo_n "checking for $CXX option to support OpenMP... " >&6; } +if ${ac_cv_prog_cxx_openmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifndef _OPENMP + choke me +#endif +#include +int main () { return omp_get_num_threads (); } + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_prog_cxx_openmp='none needed' +else + ac_cv_prog_cxx_openmp='unsupported' + for ac_option in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp; do + ac_save_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $ac_option" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifndef _OPENMP + choke me +#endif +#include +int main () { return omp_get_num_threads (); } + +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_prog_cxx_openmp=$ac_option +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CXXFLAGS=$ac_save_CXXFLAGS + if test "$ac_cv_prog_cxx_openmp" != unsupported; then + break + fi + done +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_openmp" >&5 +$as_echo "$ac_cv_prog_cxx_openmp" >&6; } + case $ac_cv_prog_cxx_openmp in #( + "none needed" | unsupported) + ;; #( + *) + OPENMP_CXXFLAGS=$ac_cv_prog_cxx_openmp ;; + esac + fi + + +CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" +# LDFLAGS="$LDFLAGS $OPENMP_CXXFLAGS" + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n $lt_cv_sys_max_cmd_len ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 +$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 +$as_echo "$xsi_shell" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 +$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } +lt_shell_append=no +( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 +$as_echo "$lt_shell_append" >&6; } + + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test "$GCC" != yes; then + reload_cmds=false + fi + ;; + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. + if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&6 +else + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 +$as_echo "${with_sysroot}" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf + + + + + +# Set options + + + + enable_dlopen=no + + + enable_win32_dll=no + + + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + pic_mode=default +fi + + +test -z "$pic_mode" && pic_mode=default + + + + + + + + # Check whether --enable-fast-install was given. +if test "${enable_fast_install+set}" = set; then : + enableval=$enable_fast_install; p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/${ac_tool_prefix}file; then + lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/file; then + lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac +fi + +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC="$CC" +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test "$GCC" = yes; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='${wl}--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = no; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + link_all_deplibs=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' ${wl}-bernotok' + allow_undefined_flag=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test "$GCC" = yes; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test x"$lt_cv_prog_compiler__b" = xyes; then + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test "$lt_cv_irix_exported_symbol" = yes; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='${wl}-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test "$ld_shlibs" = no && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([A-Za-z]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test "X$hardcode_automatic" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test "$hardcode_action" = relink || + test "$inherit_rpath" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report which library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +CC="$lt_save_CC" + + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if ${ac_cv_prog_CXXCPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_cxx_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +else + _lt_caught_CXX_error=yes +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + +archive_cmds_need_lc_CXX=no +allow_undefined_flag_CXX= +always_export_symbols_CXX=no +archive_expsym_cmds_CXX= +compiler_needs_object_CXX=no +export_dynamic_flag_spec_CXX= +hardcode_direct_CXX=no +hardcode_direct_absolute_CXX=no +hardcode_libdir_flag_spec_CXX= +hardcode_libdir_separator_CXX= +hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported +hardcode_automatic_CXX=no +inherit_rpath_CXX=no +module_cmds_CXX= +module_expsym_cmds_CXX= +link_all_deplibs_CXX=unknown +old_archive_cmds_CXX=$old_archive_cmds +reload_flag_CXX=$reload_flag +reload_cmds_CXX=$reload_cmds +no_undefined_flag_CXX= +whole_archive_flag_spec_CXX= +enable_shared_with_static_runtimes_CXX=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +objext_CXX=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + + # save warnings/boilerplate of simple test code + ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + + ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + compiler_CXX=$CC + for cc_temp in $compiler""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' + else + lt_prog_compiler_no_builtin_flag_CXX= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + whole_archive_flag_spec_CXX= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + ld_shlibs_CXX=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds_CXX='' + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + file_list_spec_CXX='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct_CXX=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L_CXX=yes + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_libdir_separator_CXX= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + export_dynamic_flag_spec_CXX='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + always_export_symbols_CXX=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag_CXX='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath__CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath__CXX"; then + lt_cv_aix_libpath__CXX="/usr/lib:/lib" + fi + +fi + + aix_libpath=$lt_cv_aix_libpath__CXX +fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag_CXX=' ${wl}-bernotok' + allow_undefined_flag_CXX=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec_CXX='$convenience' + fi + archive_cmds_need_lc_CXX=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec_CXX=' ' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=yes + file_list_spec_CXX='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' + enable_shared_with_static_runtimes_CXX=yes + # Don't use ranlib + old_postinstall_cmds_CXX='chmod 644 $oldlib' + postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec_CXX='-L$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + allow_undefined_flag_CXX=unsupported + always_export_symbols_CXX=no + enable_shared_with_static_runtimes_CXX=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs_CXX=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + + + archive_cmds_need_lc_CXX=no + hardcode_direct_CXX=no + hardcode_automatic_CXX=yes + hardcode_shlibpath_var_CXX=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec_CXX='' + fi + link_all_deplibs_CXX=yes + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi + + else + ld_shlibs_CXX=no + fi + + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + ld_shlibs_CXX=no + ;; + + freebsd-elf*) + archive_cmds_need_lc_CXX=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + ld_shlibs_CXX=yes + ;; + + gnu*) + ;; + + haiku*) + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + link_all_deplibs_CXX=yes + ;; + + hpux9*) + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_direct_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + export_dynamic_flag_spec_CXX='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + ;; + *) + hardcode_direct_CXX=yes + hardcode_direct_absolute_CXX=yes + hardcode_minus_L_CXX=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + link_all_deplibs_CXX=yes + ;; + esac + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + inherit_rpath_CXX=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + archive_cmds_need_lc_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [1-5].* | *pgcpp\ [1-5].*) + prelink_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + old_archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + archive_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + compiler_needs_object_CXX=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + ld_shlibs_CXX=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + ld_shlibs_CXX=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + hardcode_direct_absolute_CXX=yes + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + ld_shlibs_CXX=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_separator_CXX=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + cxx*) + case $host in + osf3*) + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + ;; + *) + allow_undefined_flag_CXX=' -expect_unresolved \*' + archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + hardcode_libdir_flag_spec_CXX='-rpath $libdir' + ;; + esac + + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + hardcode_libdir_flag_spec_CXX='-R$libdir' + hardcode_shlibpath_var_CXX=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' + ;; + esac + link_all_deplibs_CXX=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ + '"$old_archive_cmds_CXX" + reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ + '"$reload_cmds_CXX" + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + + *) + # FIXME: insert proper C++ library support + ld_shlibs_CXX=no + ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } + test "$ld_shlibs_CXX" = no && can_build_shared=no + + GCC_CXX="$GXX" + LD_CXX="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + # Dependencies to place before and after the object being linked: +predep_objects_CXX= +postdep_objects_CXX= +predeps_CXX= +postdeps_CXX= +compiler_lib_search_path_CXX= + +cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF + + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$compiler_lib_search_path_CXX"; then + compiler_lib_search_path_CXX="${prev}${p}" + else + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$postdeps_CXX"; then + postdeps_CXX="${prev}${p}" + else + postdeps_CXX="${postdeps_CXX} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$predep_objects_CXX"; then + predep_objects_CXX="$p" + else + predep_objects_CXX="$predep_objects_CXX $p" + fi + else + if test -z "$postdep_objects_CXX"; then + postdep_objects_CXX="$p" + else + postdep_objects_CXX="$postdep_objects_CXX $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling CXX test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + + +case " $postdeps_CXX " in +*" -lc "*) archive_cmds_need_lc_CXX=no ;; +esac + compiler_lib_search_dirs_CXX= +if test -n "${compiler_lib_search_path_CXX}"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + lt_prog_compiler_wl_CXX= +lt_prog_compiler_pic_CXX= +lt_prog_compiler_static_CXX= + + + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic_CXX='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic_CXX='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + lt_prog_compiler_pic_CXX= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static_CXX= + ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic_CXX=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + *) + lt_prog_compiler_pic_CXX='-fPIC' + ;; + esac + else + case $host_os in + aix[4-9]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static_CXX='-Bstatic' + else + lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + ;; + dgux*) + case $cc_basename in + ec++*) + lt_prog_compiler_pic_CXX='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + lt_prog_compiler_pic_CXX='+Z' + fi + ;; + aCC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic_CXX='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_static_CXX='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + lt_prog_compiler_wl_CXX='--backend -Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fPIC' + lt_prog_compiler_static_CXX='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-fpic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-qpic' + lt_prog_compiler_static_CXX='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + lt_prog_compiler_pic_CXX='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic_CXX='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + lt_prog_compiler_wl_CXX='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + lt_prog_compiler_pic_CXX='-pic' + ;; + cxx*) + # Digital/Compaq C++ + lt_prog_compiler_wl_CXX='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + lt_prog_compiler_pic_CXX= + lt_prog_compiler_static_CXX='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + lt_prog_compiler_pic_CXX='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + lt_prog_compiler_pic_CXX='-pic' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + lcc*) + # Lucid + lt_prog_compiler_pic_CXX='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + lt_prog_compiler_pic_CXX='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + lt_prog_compiler_can_build_shared_CXX=no + ;; + esac + fi + +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic_CXX= + ;; + *) + lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic_CXX"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works_CXX=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then + case $lt_prog_compiler_pic_CXX in + "" | " "*) ;; + *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; + esac +else + lt_prog_compiler_pic_CXX= + lt_prog_compiler_can_build_shared_CXX=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o_CXX=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o_CXX=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } + + + + +hard_links="nottested" +if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test "$hard_links" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + case $host_os in + aix[4-9]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + export_symbols_cmds_CXX="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + link_all_deplibs_CXX=no + ;; + *) + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +$as_echo "$ld_shlibs_CXX" >&6; } +test "$ld_shlibs_CXX" = no && can_build_shared=no + +with_gnu_ld_CXX=$with_gnu_ld + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc_CXX" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc_CXX=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $archive_cmds_CXX in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag_CXX + allow_undefined_flag_CXX= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc_CXX=no + else + lt_cv_archive_cmds_need_lc_CXX=yes + fi + allow_undefined_flag_CXX=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } + archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[89] | openbsd2.[89].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action_CXX= +if test -n "$hardcode_libdir_flag_spec_CXX" || + test -n "$runpath_var_CXX" || + test "X$hardcode_automatic_CXX" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$hardcode_direct_CXX" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && + test "$hardcode_minus_L_CXX" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action_CXX=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action_CXX=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action_CXX=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +$as_echo "$hardcode_action_CXX" >&6; } + +if test "$hardcode_action_CXX" = relink || + test "$inherit_rpath_CXX" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + + + +# OpenCASCADE configuration + +occon=false +# Check whether --enable-occ was given. +if test "${enable_occ+set}" = set; then : + enableval=$enable_occ; occon=true +fi + + + +# Check whether --with-occ was given. +if test "${with_occ+set}" = set; then : + withval=$with_occ; occdir=$withval + occon=true +else + occdir=/opt/OpenCASCADE + +fi + + + + +if test a$occon = atrue ; then + + OCCFLAGS="-DOCCGEOMETRY -I$occdir/inc -I/usr/include/opencascade" + + OCCLIBS="-L$occdir/lib -lTKernel -lTKGeomBase -lTKMath -lTKG2d -lTKG3d -lTKXSBase -lTKOffset -lTKFillet -lTKShHealing -lTKMesh -lTKMeshVS -lTKTopAlgo -lTKGeomAlgo -lTKBool -lTKPrim -lTKBO -lTKIGES -lTKBRep -lTKSTEPBase -lTKSTEP -lTKSTL -lTKSTEPAttr -lTKSTEP209 -lTKXDESTEP -lTKXDEIGES -lTKXCAF -lTKLCAF -lFWOSPlugin" + + +# -lTKDCAF + + if test a$build_cpu = ax86_64 ; then + OCCFLAGS="$OCCFLAGS -D_OCC64" + + fi + + + +ac_fn_cxx_check_header_mongrel "$LINENO" "iostream" "ac_cv_header_iostream" "$ac_includes_default" +if test "x$ac_cv_header_iostream" = xyes; then : + OCCFLAGS="$OCCFLAGS -DHAVE_IOSTREAM" +fi + + + ac_fn_cxx_check_header_mongrel "$LINENO" "iostream.h" "ac_cv_header_iostream_h" "$ac_includes_default" +if test "x$ac_cv_header_iostream_h" = xyes; then : + OCC_FLAGS="$OCCFLAGS -DHAVE_IOSTREAM_H" +fi + + + ac_fn_cxx_check_header_mongrel "$LINENO" "limits" "ac_cv_header_limits" "$ac_includes_default" +if test "x$ac_cv_header_limits" = xyes; then : + OCCFLAGS="$OCCFLAGS -DHAVE_LIMITS" +fi + + + ac_fn_cxx_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_limits_h" = xyes; then : + OCCFLAGS="$OCCFLAGS -DHAVE_LIMITS_H" +fi + + + ac_fn_cxx_check_header_mongrel "$LINENO" "iomanip" "ac_cv_header_iomanip" "$ac_includes_default" +if test "x$ac_cv_header_iomanip" = xyes; then : + OCCFLAGS="$OCCFLAGS -DHAVE_IOMANIP" +fi + + + ac_fn_cxx_check_header_mongrel "$LINENO" "iomanip.h" "ac_cv_header_iomanip_h" "$ac_includes_default" +if test "x$ac_cv_header_iomanip_h" = xyes; then : + OCCFLAGS="$OCCFLAGS -DHAVE_IOMANIP_H" +fi + + + + + echo "OCCFLAGS = $OCCFLAGS" + echo "OCCLIBS = $OCCLIBS" +fi + + + + + + + + +# Check whether --with-togl was given. +if test "${with_togl+set}" = set; then : + withval=$with_togl; togldir=$withval + togllibfl="-L$withval$" + +fi + +# [togllibfl="-L$(TK_BIN_DIR)/Togl1.7"] +# [togllibfl="-L/usr/local/lib/Togl1.7"] + + +nglibon=true +# Check whether --enable-nglib was given. +if test "${enable_nglib+set}" = set; then : + enableval=$enable_nglib; if test "$enableval" = yes; then nglibon=true; else nglibon=false; fi +fi + + +ngguion=true +# Check whether --enable-gui was given. +if test "${enable_gui+set}" = set; then : + enableval=$enable_gui; if test "$enableval" = yes; then ngguion=true; else ngguion=false; fi +fi + + +metisdir=/usr/local + +# Check whether --with-metis was given. +if test "${with_metis+set}" = set; then : + withval=$with_metis; metisdir=$withval +else + metisdir=/usr/local + +fi + + +# Check whether --enable-parallel was given. +if test "${enable_parallel+set}" = set; then : + enableval=$enable_parallel; MPI_INCLUDES="-I$metisdir/include -DMETIS" + + CXXFLAGS="$CXXFLAGS -DPARALLEL" + MPI_LIBS="-L$metisdir/lib -lmetis" + + +fi + +# -DVTRACE +# -lvt-hyb + +# [AC_SUBST([MPI_INCLUDES], "-I/opt/mpich/include -I/usr/include/mpich2 -I/usr/include/metis -DPARALLEL -I/usr/share/metis/Lib -DMETIS -DVTRACE -I/usr/local/include/vampirtrace") +# AC_SUBST([MPI_LIBS], "-lmetis -L/opt/mpich/ch-p4/lib -lmpich") + +# -lvt -lvt-mpi -lvt-mpi-unify") +# [AC_SUBST([MPI_INCLUDES], "-I/opt/mpich/include -DPARALLEL -I/usr/include/metis -DMETIS") +# AC_SUBST([MPI_LIBS], " -L/opt/mpich/ch-p4/lib64 -lmpich -lmetis") +# [AC_SUBST([MPI_INCLUDES], "-DPARALLEL -DNO_PARALLEL_THREADS -I/opt/mpich/include") +# AC_SUBST([MPI_LIBS], "") +# -lmetis +# [AC_SUBST([MPI_INCLUDES], "-I/opt/mpich/include -DPARALLEL -I/home/joachim/download/metis-4.0/Lib -DMETIS") +# AC_SUBST([MPI_LIBS], "-L/home/joachim/download/metis-4.0 -lmetis -L/opt/mpich/ch-p4/lib64 -lmpich") + + +jpeglibon=false +# Check whether --enable-jpeglib was given. +if test "${enable_jpeglib+set}" = set; then : + enableval=$enable_jpeglib; JPEGLIB_INCLUDES="-DJPEGLIB" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jpeg_start_compress in -ljpeg" >&5 +$as_echo_n "checking for jpeg_start_compress in -ljpeg... " >&6; } +if ${ac_cv_lib_jpeg_jpeg_start_compress+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ljpeg $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char jpeg_start_compress (); +int +main () +{ +return jpeg_start_compress (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_jpeg_jpeg_start_compress=yes +else + ac_cv_lib_jpeg_jpeg_start_compress=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jpeg_jpeg_start_compress" >&5 +$as_echo "$ac_cv_lib_jpeg_jpeg_start_compress" >&6; } +if test "x$ac_cv_lib_jpeg_jpeg_start_compress" = xyes; then : + JPEGLIB_LIBS="-ljpeg" + +else + as_fn_error $? "no usable library libjpeg found" "$LINENO" 5 +fi + + if test "$enableval" = yes; then jpeglibon=true; else jpeglibon=false; fi + + +fi + + +ffmpegon=false +# Check whether --enable-ffmpeg was given. +if test "${enable_ffmpeg+set}" = set; then : + enableval=$enable_ffmpeg; FFMPEG_INCLUDES="-DFFMPEG -D__STDC_CONSTANT_MACROS" + + FFMPEG_LIBS="-lavutil -lavformat -lavcodec -lavutil -lswscale -lz -lbz2" + + if test "$enableval" = yes; then ffmpegon=true; else ffmpegon=false; fi + + +fi + + + +mklon=false +# Check whether --enable-mkl was given. +if test "${enable_mkl+set}" = set; then : + enableval=$enable_mkl; if test "$enableval" = yes; then mklon=true; else mklon=false; fi + +fi + + +# only for GUI version + +if test a$ngguion = atrue ; then +# Tcl/Tk configuration: + + # TEA extensions pass this us the version of TEA they think they + # are compatible with. + TEA_VERSION="3.9" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct TEA configuration" >&5 +$as_echo_n "checking for correct TEA configuration... " >&6; } + if test x"${PACKAGE_NAME}" = x ; then + as_fn_error $? " +The PACKAGE_NAME variable must be defined by your TEA configure.in" "$LINENO" 5 + fi + if test x"3.9" = x ; then + as_fn_error $? " +TEA version not specified." "$LINENO" 5 + elif test "3.9" != "${TEA_VERSION}" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&5 +$as_echo "warning: requested TEA version \"3.9\", have \"${TEA_VERSION}\"" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok (TEA ${TEA_VERSION})" >&5 +$as_echo "ok (TEA ${TEA_VERSION})" >&6; } + fi + case "`uname -s`" in + *win32*|*WIN32*|*MINGW32_*) + # Extract the first word of "cygpath", so it can be a program name with args. +set dummy cygpath; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CYGPATH+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CYGPATH"; then + ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CYGPATH="cygpath -w" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" +fi +fi +CYGPATH=$ac_cv_prog_CYGPATH +if test -n "$CYGPATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5 +$as_echo "$CYGPATH" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + EXEEXT=".exe" + TEA_PLATFORM="windows" + ;; + *CYGWIN_*) + CYGPATH=echo + EXEEXT=".exe" + # TEA_PLATFORM is determined later in LOAD_TCLCONFIG + ;; + *) + CYGPATH=echo + # Maybe we are cross-compiling.... + case ${host_alias} in + *mingw32*) + EXEEXT=".exe" + TEA_PLATFORM="windows" + ;; + *) + EXEEXT="" + TEA_PLATFORM="unix" + ;; + esac + ;; + esac + + # Check if exec_prefix is set. If not use fall back to prefix. + # Note when adjusted, so that TEA_PREFIX can correct for this. + # This is needed for recursive configures, since autoconf propagates + # $prefix, but not $exec_prefix (doh!). + if test x$exec_prefix = xNONE ; then + exec_prefix_default=yes + exec_prefix=$prefix + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&5 +$as_echo "$as_me: configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}" >&6;} + + + + + # This package name must be replaced statically for AC_SUBST to work + + # Substitute STUB_LIB_FILE in case package creates a stub library too. + + + # We AC_SUBST these here to ensure they are subst'ed, + # in case the user doesn't call TEA_ADD_... + + + + + + + + + + + # + # Ok, lets find the tcl configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tcl + # + + if test x"${no_tcl}" = x ; then + # we reset no_tcl in case something fails here + no_tcl=true + +# Check whether --with-tcl was given. +if test "${with_tcl+set}" = set; then : + withval=$with_tcl; with_tclconfig="${withval}" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 +$as_echo_n "checking for Tcl configuration... " >&6; } + if ${ac_cv_c_tclconfig+:} false; then : + $as_echo_n "(cached) " >&6 +else + + + # First check to see if --with-tcl was specified. + if test x"${with_tclconfig}" != x ; then + case "${with_tclconfig}" in + */tclConfig.sh ) + if test -f "${with_tclconfig}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&5 +$as_echo "$as_me: WARNING: --with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself" >&2;} + with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" + fi ;; + esac + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" + else + as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 + fi + fi + + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tcl.framework/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`" + break + fi + done + fi + + # TEA specific: on Windows, check in common installation locations + if test "${TEA_PLATFORM}" = "windows" \ + -a x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + `ls -d /usr/lib64 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + +fi + + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + as_fn_error $? "Can't find Tcl configuration definitions" "$LINENO" 5 + else + no_tcl= + TCL_BIN_DIR="${ac_cv_c_tclconfig}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TCL_BIN_DIR}/tclConfig.sh" >&5 +$as_echo "found ${TCL_BIN_DIR}/tclConfig.sh" >&6; } + fi + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TCL_BIN_DIR}/tclConfig.sh" >&5 +$as_echo_n "checking for existence of ${TCL_BIN_DIR}/tclConfig.sh... " >&6; } + + if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 +$as_echo "loading" >&6; } + . "${TCL_BIN_DIR}/tclConfig.sh" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TCL_BIN_DIR}/tclConfig.sh" >&5 +$as_echo "could not find ${TCL_BIN_DIR}/tclConfig.sh" >&6; } + fi + + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" + eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" + + # If the TCL_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TCL_LIB_SPEC will be set to the value + # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC + # instead of TCL_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TCL_BIN_DIR}/Makefile" ; then + TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}" + TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}" + TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}" + elif test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tcl.framework installed in an arbitrary location. + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then + for i in "`cd "${TCL_BIN_DIR}"; pwd`" \ + "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do + if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then + TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}" + break + fi + done + fi + if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then + TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}" + TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" + fi + ;; + esac + fi + + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" + eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" + eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" + + + + + + + + + + + + + + + case "`uname -s`" in + *CYGWIN_*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cygwin variant" >&5 +$as_echo_n "checking for cygwin variant... " >&6; } + case ${TCL_EXTRA_CFLAGS} in + *-mwin32*|*-mno-cygwin*) + TEA_PLATFORM="windows" + CFLAGS="$CFLAGS -mwin32" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: win32" >&5 +$as_echo "win32" >&6; } + ;; + *) + TEA_PLATFORM="unix" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unix" >&5 +$as_echo "unix" >&6; } + ;; + esac + EXEEXT=".exe" + ;; + *) + ;; + esac + + # The BUILD_$pkg is to define the correct extern storage class + # handling when making this package + +cat >>confdefs.h <<_ACEOF +#define BUILD_${PACKAGE_NAME} /**/ +_ACEOF + + # Do this here as we have fully defined TEA_PLATFORM now + if test "${TEA_PLATFORM}" = "windows" ; then + CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp" + fi + + # TEA specific: + + + + + + + + + # + # Ok, lets find the tk configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tk + # + + if test x"${no_tk}" = x ; then + # we reset no_tk in case something fails here + no_tk=true + +# Check whether --with-tk was given. +if test "${with_tk+set}" = set; then : + withval=$with_tk; with_tkconfig="${withval}" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk configuration" >&5 +$as_echo_n "checking for Tk configuration... " >&6; } + if ${ac_cv_c_tkconfig+:} false; then : + $as_echo_n "(cached) " >&6 +else + + + # First check to see if --with-tkconfig was specified. + if test x"${with_tkconfig}" != x ; then + case "${with_tkconfig}" in + */tkConfig.sh ) + if test -f "${with_tkconfig}"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&5 +$as_echo "$as_me: WARNING: --with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself" >&2;} + with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" + fi ;; + esac + if test -f "${with_tkconfig}/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" + else + as_fn_error $? "${with_tkconfig} directory doesn't contain tkConfig.sh" "$LINENO" 5 + fi + fi + + # then check for a private Tk library + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ../tk \ + `ls -dr ../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../tk[8-9].[0-9]* 2>/dev/null` \ + ../../tk \ + `ls -dr ../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../tk[8-9].[0-9]* 2>/dev/null` \ + ../../../tk \ + `ls -dr ../../../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ../../../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ../../../tk[8-9].[0-9]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tk.framework/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`" + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + `ls -d /usr/lib64 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # TEA specific: on Windows, check in common installation locations + if test "${TEA_PLATFORM}" = "windows" \ + -a x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ${srcdir}/../tk \ + `ls -dr ${srcdir}/../tk[8-9].[0-9].[0-9]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[8-9].[0-9] 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[8-9].[0-9]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + +fi + + + if test x"${ac_cv_c_tkconfig}" = x ; then + TK_BIN_DIR="# no Tk configs found" + as_fn_error $? "Can't find Tk configuration definitions" "$LINENO" 5 + else + no_tk= + TK_BIN_DIR="${ac_cv_c_tkconfig}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: found ${TK_BIN_DIR}/tkConfig.sh" >&5 +$as_echo "found ${TK_BIN_DIR}/tkConfig.sh" >&6; } + fi + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of ${TK_BIN_DIR}/tkConfig.sh" >&5 +$as_echo_n "checking for existence of ${TK_BIN_DIR}/tkConfig.sh... " >&6; } + + if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 +$as_echo "loading" >&6; } + . "${TK_BIN_DIR}/tkConfig.sh" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${TK_BIN_DIR}/tkConfig.sh" >&5 +$as_echo "could not find ${TK_BIN_DIR}/tkConfig.sh" >&6; } + fi + + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" + eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" + + # If the TK_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TK_LIB_SPEC will be set to the value + # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC + # instead of TK_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TK_BIN_DIR}/Makefile" ; then + TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}" + TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}" + TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}" + elif test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tk.framework installed in an arbitrary location. + case ${TK_DEFS} in + *TK_FRAMEWORK*) + if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then + for i in "`cd "${TK_BIN_DIR}"; pwd`" \ + "`cd "${TK_BIN_DIR}"/../..; pwd`"; do + if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then + TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}" + break + fi + done + fi + if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then + TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}" + TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" + fi + ;; + esac + fi + + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" + eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" + eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" + eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" + + # TEA specific: Ensure windowingsystem is defined + if test "${TEA_PLATFORM}" = "unix" ; then + case ${TK_DEFS} in + *MAC_OSX_TK*) + +$as_echo "#define MAC_OSX_TK 1" >>confdefs.h + + TEA_WINDOWINGSYSTEM="aqua" + ;; + *) + TEA_WINDOWINGSYSTEM="x11" + ;; + esac + elif test "${TEA_PLATFORM}" = "windows" ; then + TEA_WINDOWINGSYSTEM="win32" + fi + + + + + + + + + + + + + + # TEA specific: + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl public headers" >&5 +$as_echo_n "checking for Tcl public headers... " >&6; } + + +# Check whether --with-tclinclude was given. +if test "${with_tclinclude+set}" = set; then : + withval=$with_tclinclude; with_tclinclude=${withval} +fi + + + if ${ac_cv_c_tclh+:} false; then : + $as_echo_n "(cached) " >&6 +else + + # Use the value from --with-tclinclude, if it was given + + if test x"${with_tclinclude}" != x ; then + if test -f "${with_tclinclude}/tcl.h" ; then + ac_cv_c_tclh=${with_tclinclude} + else + as_fn_error $? "${with_tclinclude} directory does not contain tcl.h" "$LINENO" 5 + fi + else + list="" + if test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use + # the framework's Headers directory + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" + ;; + esac + fi + + # Look in the source dir only if Tcl is not installed, + # and in that situation, look there before installed locations. + if test -f "${TCL_BIN_DIR}/Makefile" ; then + list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" + fi + + # Check order: pkg --prefix location, Tcl's --prefix location, + # relative to directory of tclConfig.sh. + + eval "temp_includedir=${includedir}" + list="$list \ + `ls -d ${temp_includedir} 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" + if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then + list="$list /usr/local/include /usr/include" + if test x"${TCL_INCLUDE_SPEC}" != x ; then + d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` + list="$list `ls -d ${d} 2>/dev/null`" + fi + fi + for i in $list ; do + if test -f "$i/tcl.h" ; then + ac_cv_c_tclh=$i + break + fi + done + fi + +fi + + + # Print a message based on how we determined the include path + + if test x"${ac_cv_c_tclh}" = x ; then + as_fn_error $? "tcl.h not found. Please specify its location with --with-tclinclude" "$LINENO" 5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tclh}" >&5 +$as_echo "${ac_cv_c_tclh}" >&6; } + fi + + # Convert to a native path and substitute into the output files. + + INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` + + TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tk public headers" >&5 +$as_echo_n "checking for Tk public headers... " >&6; } + + +# Check whether --with-tkinclude was given. +if test "${with_tkinclude+set}" = set; then : + withval=$with_tkinclude; with_tkinclude=${withval} +fi + + + if ${ac_cv_c_tkh+:} false; then : + $as_echo_n "(cached) " >&6 +else + + # Use the value from --with-tkinclude, if it was given + + if test x"${with_tkinclude}" != x ; then + if test -f "${with_tkinclude}/tk.h" ; then + ac_cv_c_tkh=${with_tkinclude} + else + as_fn_error $? "${with_tkinclude} directory does not contain tk.h" "$LINENO" 5 + fi + else + list="" + if test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use + # the framework's Headers directory. + case ${TK_DEFS} in + *TK_FRAMEWORK*) + list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" + ;; + esac + fi + + # Look in the source dir only if Tk is not installed, + # and in that situation, look there before installed locations. + if test -f "${TK_BIN_DIR}/Makefile" ; then + list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" + fi + + # Check order: pkg --prefix location, Tk's --prefix location, + # relative to directory of tkConfig.sh, Tcl's --prefix location, + # relative to directory of tclConfig.sh. + + eval "temp_includedir=${includedir}" + list="$list \ + `ls -d ${temp_includedir} 2>/dev/null` \ + `ls -d ${TK_PREFIX}/include 2>/dev/null` \ + `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" + if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then + list="$list /usr/local/include /usr/include" + if test x"${TK_INCLUDE_SPEC}" != x ; then + d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'` + list="$list `ls -d ${d} 2>/dev/null`" + fi + fi + for i in $list ; do + if test -f "$i/tk.h" ; then + ac_cv_c_tkh=$i + break + fi + done + fi + +fi + + + # Print a message based on how we determined the include path + + if test x"${ac_cv_c_tkh}" = x ; then + as_fn_error $? "tk.h not found. Please specify its location with --with-tkinclude" "$LINENO" 5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ac_cv_c_tkh}" >&5 +$as_echo "${ac_cv_c_tkh}" >&6; } + fi + + # Convert to a native path and substitute into the output files. + + INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` + + TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + + + if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then + # On Windows and Aqua, we need the X compat headers + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11 header files" >&5 +$as_echo_n "checking for X11 header files... " >&6; } + if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then + INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" + TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${INCLUDE_DIR_NATIVE}" >&5 +$as_echo "${INCLUDE_DIR_NATIVE}" >&6; } + fi + + +TOGLLIBDIR="$togllibfl" + +ac_fn_cxx_check_header_mongrel "$LINENO" "togl.h" "ac_cv_header_togl_h" "$ac_includes_default" +if test "x$ac_cv_header_togl_h" = xyes; then : + +fi + + +ac_fn_cxx_check_header_mongrel "$LINENO" "GL/gl.h" "ac_cv_header_GL_gl_h" "$ac_includes_default" +if test "x$ac_cv_header_GL_gl_h" = xyes; then : + +fi + + + + + +#-------------------------------------------------------------------- +# __CHANGE__ +# Choose OpenGL platform (borrowed from Togl1.7) +#-------------------------------------------------------------------- + +case "${TEA_WINDOWINGSYSTEM}" in + aqua) + TOGL_WINDOWINGSYSTEM=TOGL_AGL + + + vars="-framework AGL -framework OpenGL -framework ApplicationServices" + for i in $vars; do + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then + # Convert foo.lib to -lfoo for GCC. No-op if not *.lib + i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` + fi + PKG_LIBS="$PKG_LIBS $i" + done + + + # libGLU is implicit in OpenGL framework + LIBGLU= + ;; + x11) + TOGL_WINDOWINGSYSTEM=TOGL_X11 + + + vars="-lGL -lXmu" + for i in $vars; do + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then + # Convert foo.lib to -lfoo for GCC. No-op if not *.lib + i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` + fi + PKG_LIBS="$PKG_LIBS $i" + done + + + LIBGLU=-lGLU + ;; + win32) + TOGL_WINDOWINGSYSTEM=TOGL_WGL + + + vars="opengl32.lib user32.lib gdi32.lib" + for i in $vars; do + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then + # Convert foo.lib to -lfoo for GCC. No-op if not *.lib + i=`echo "$i" | sed -e 's/^\([^-].*\)\.lib$/-l\1/i'` + fi + PKG_LIBS="$PKG_LIBS $i" + done + + + if test "$GCC" = "yes" ; then + LIBGLU=-lglu32 + else + LIBGLU=glu32.lib + fi + ;; + *) + as_fn_error $? "Unsupported windowing system: ${TEA_WINDOWINGSYSTEM}" "$LINENO" 5 + ;; +esac + + +fi + + + + if test x$nglibon = xtrue; then + NGLIB_TRUE= + NGLIB_FALSE='#' +else + NGLIB_TRUE='#' + NGLIB_FALSE= +fi + + if test x$ngguion = xtrue; then + NGGUI_TRUE= + NGGUI_FALSE='#' +else + NGGUI_TRUE='#' + NGGUI_FALSE= +fi + + if test x$mklon = xtrue; then + NGMKL_TRUE= + NGMKL_FALSE='#' +else + NGMKL_TRUE='#' + NGMKL_FALSE= +fi + + +ac_fn_cxx_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_h" = xyes; then : + +fi + + + +for ac_func in pow +do : + ac_fn_cxx_check_func "$LINENO" "pow" "ac_cv_func_pow" +if test "x$ac_cv_func_pow" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_POW 1 +_ACEOF + +fi +done + +for ac_func in floor +do : + ac_fn_cxx_check_func "$LINENO" "floor" "ac_cv_func_floor" +if test "x$ac_cv_func_floor" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FLOOR 1 +_ACEOF + +fi +done + +for ac_func in matherr +do : + ac_fn_cxx_check_func "$LINENO" "matherr" "ac_cv_func_matherr" +if test "x$ac_cv_func_matherr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MATHERR 1 +_ACEOF + +fi +done + +for ac_header in limits.h +do : + ac_fn_cxx_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_limits_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIMITS_H 1 +_ACEOF + +fi + +done + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +$as_echo_n "checking for pthread_create in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_create=yes +else + ac_cv_lib_pthread_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPTHREAD 1 +_ACEOF + + LIBS="-lpthread $LIBS" + +fi + + + + + +ac_config_files="$ac_config_files Makefile libsrc/Makefile libsrc/csg/Makefile libsrc/general/Makefile libsrc/geom2d/Makefile libsrc/gprim/Makefile libsrc/include/Makefile libsrc/interface/Makefile libsrc/linalg/Makefile libsrc/meshing/Makefile libsrc/occ/Makefile libsrc/stlgeom/Makefile libsrc/visualization/Makefile ng/Makefile nglib/Makefile tutorials/Makefile doc/Makefile windows/Makefile" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NGLIB_TRUE}" && test -z "${NGLIB_FALSE}"; then + as_fn_error $? "conditional \"NGLIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NGGUI_TRUE}" && test -z "${NGGUI_FALSE}"; then + as_fn_error $? "conditional \"NGGUI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NGMKL_TRUE}" && test -z "${NGMKL_FALSE}"; then + as_fn_error $? "conditional \"NGMKL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by netgen $as_me 5.2-dev, which was +generated by GNU Autoconf 2.68. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +netgen config.status 5.2-dev +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2010 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' +predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' +postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' +predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' +postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +OBJDUMP \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +DLLTOOL \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +nm_file_list_spec \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib \ +compiler_lib_search_dirs \ +predep_objects \ +postdep_objects \ +predeps \ +postdeps \ +compiler_lib_search_path \ +LD_CXX \ +reload_flag_CXX \ +compiler_CXX \ +lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_CXX \ +compiler_needs_object_CXX \ +with_gnu_ld_CXX \ +allow_undefined_flag_CXX \ +no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_CXX \ +exclude_expsyms_CXX \ +include_expsyms_CXX \ +file_list_spec_CXX \ +compiler_lib_search_dirs_CXX \ +predep_objects_CXX \ +postdep_objects_CXX \ +predeps_CXX \ +postdeps_CXX \ +compiler_lib_search_path_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +sys_lib_dlsearch_path_spec \ +reload_cmds_CXX \ +old_archive_cmds_CXX \ +old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_CXX \ +archive_cmds_CXX \ +archive_expsym_cmds_CXX \ +module_cmds_CXX \ +module_expsym_cmds_CXX \ +export_symbols_cmds_CXX \ +prelink_cmds_CXX \ +postlink_cmds_CXX; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' +xsi_shell='$xsi_shell' +lt_shell_append='$lt_shell_append' + +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile' + + + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "libsrc/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/Makefile" ;; + "libsrc/csg/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/csg/Makefile" ;; + "libsrc/general/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/general/Makefile" ;; + "libsrc/geom2d/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/geom2d/Makefile" ;; + "libsrc/gprim/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/gprim/Makefile" ;; + "libsrc/include/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/include/Makefile" ;; + "libsrc/interface/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/interface/Makefile" ;; + "libsrc/linalg/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/linalg/Makefile" ;; + "libsrc/meshing/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/meshing/Makefile" ;; + "libsrc/occ/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/occ/Makefile" ;; + "libsrc/stlgeom/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/stlgeom/Makefile" ;; + "libsrc/visualization/Makefile") CONFIG_FILES="$CONFIG_FILES libsrc/visualization/Makefile" ;; + "ng/Makefile") CONFIG_FILES="$CONFIG_FILES ng/Makefile" ;; + "nglib/Makefile") CONFIG_FILES="$CONFIG_FILES nglib/Makefile" ;; + "tutorials/Makefile") CONFIG_FILES="$CONFIG_FILES tutorials/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "windows/Makefile") CONFIG_FILES="$CONFIG_FILES windows/Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +# The names of the tagged configurations supported by this script. +available_tags="CXX " + +# ### BEGIN LIBTOOL CONFIG + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# An object symbol dumper. +OBJDUMP=$lt_OBJDUMP + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and in which our libraries should be installed. +lt_sysroot=$lt_sysroot + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects +postdep_objects=$lt_postdep_objects +predeps=$lt_predeps +postdeps=$lt_postdeps + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path + +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain="$ac_aux_dir/ltmain.sh" + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + if test x"$xsi_shell" = xyes; then + sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ +func_dirname ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_basename ()$/,/^} # func_basename /c\ +func_basename ()\ +{\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ +func_dirname_and_basename ()\ +{\ +\ case ${1} in\ +\ */*) func_dirname_result="${1%/*}${2}" ;;\ +\ * ) func_dirname_result="${3}" ;;\ +\ esac\ +\ func_basename_result="${1##*/}"\ +} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ +func_stripname ()\ +{\ +\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ +\ # positional parameters, so assign one to ordinary parameter first.\ +\ func_stripname_result=${3}\ +\ func_stripname_result=${func_stripname_result#"${1}"}\ +\ func_stripname_result=${func_stripname_result%"${2}"}\ +} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ +func_split_long_opt ()\ +{\ +\ func_split_long_opt_name=${1%%=*}\ +\ func_split_long_opt_arg=${1#*=}\ +} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ +func_split_short_opt ()\ +{\ +\ func_split_short_opt_arg=${1#??}\ +\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ +} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ +func_lo2o ()\ +{\ +\ case ${1} in\ +\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ +\ *) func_lo2o_result=${1} ;;\ +\ esac\ +} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_xform ()$/,/^} # func_xform /c\ +func_xform ()\ +{\ + func_xform_result=${1%.*}.lo\ +} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_arith ()$/,/^} # func_arith /c\ +func_arith ()\ +{\ + func_arith_result=$(( $* ))\ +} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_len ()$/,/^} # func_len /c\ +func_len ()\ +{\ + func_len_result=${#1}\ +} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + +fi + +if test x"$lt_shell_append" = xyes; then + sed -e '/^func_append ()$/,/^} # func_append /c\ +func_append ()\ +{\ + eval "${1}+=\\${2}"\ +} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ +func_append_quoted ()\ +{\ +\ func_quote_for_eval "${2}"\ +\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ +} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: + + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 +$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} +fi + + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: CXX + +# The linker used to build libraries. +LD=$lt_LD_CXX + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_CXX +reload_cmds=$lt_reload_cmds_CXX + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_CXX + +# A language specific compiler. +CC=$lt_compiler_CXX + +# Is the compiler the GNU compiler? +with_gcc=$GCC_CXX + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_CXX + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_CXX + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_CXX + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_CXX + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_CXX + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_CXX +archive_expsym_cmds=$lt_archive_expsym_cmds_CXX + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_CXX +module_expsym_cmds=$lt_module_expsym_cmds_CXX + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_CXX + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_CXX + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_CXX + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_CXX + +# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_CXX + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_CXX + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_CXX + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_CXX + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_CXX + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_CXX + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_CXX + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_CXX + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_CXX + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_CXX + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_CXX + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_CXX + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_CXX + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_CXX +postdep_objects=$lt_postdep_objects_CXX +predeps=$lt_predeps_CXX +postdeps=$lt_postdeps_CXX + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_CXX + +# ### END LIBTOOL TAG CONFIG: CXX +_LT_EOF + + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: +------------------------------------------------------------------------ + $PACKAGE $VERSION: Automatic configuration OK. + + Enabled functionality: + + OCC: ............... $occon + JPEGlib: ........... $jpeglibon + FFMPEG: ............ $ffmpegon + NGLIB: ............. $nglibon + GUI: ............... $ngguion + + + Building: + + Type 'make' to compile $PACKAGE. + + Type 'make install' to install $PACKAGE. + + Example programs will be built but not installed. +------------------------------------------------------------------------ +" >&5 +$as_echo " +------------------------------------------------------------------------ + $PACKAGE $VERSION: Automatic configuration OK. + + Enabled functionality: + + OCC: ............... $occon + JPEGlib: ........... $jpeglibon + FFMPEG: ............ $ffmpegon + NGLIB: ............. $nglibon + GUI: ............... $ngguion + + + Building: + + Type 'make' to compile $PACKAGE. + + Type 'make install' to install $PACKAGE. + + Example programs will be built but not installed. +------------------------------------------------------------------------ +" >&6; } diff --git a/configure.ac b/configure.ac new file mode 100644 index 00000000..6f32a86a --- /dev/null +++ b/configure.ac @@ -0,0 +1,255 @@ +AC_INIT([netgen],[5.2-alpha],[],[]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) + +AC_CONFIG_MACRO_DIR([m4]) + +AC_PREFIX_DEFAULT(["/opt/netgen"]) + + + + + +# AC_HEADER_STDC +AC_CONFIG_HEADERS(config.h) +AC_DISABLE_STATIC + +AC_LANG([C++]) +AC_PROG_CXX + +AC_OPENMP +CXXFLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" +# LDFLAGS="$LDFLAGS $OPENMP_CXXFLAGS" + +AC_PROG_LIBTOOL +LT_INIT + +# OpenCASCADE configuration + +occon=false +AC_ARG_ENABLE([occ], + [AC_HELP_STRING([--enable-occ],[compile with OpenCascade geometry kernel])], + [occon=true]) + +AC_ARG_WITH([occ], + [AC_HELP_STRING([--with-occ=dir],[use OpenCascade installed in directory dir])], + [occdir=$withval] + [occon=true], + [occdir=/opt/OpenCASCADE] + ) + + + +if test a$occon = atrue ; then + + AC_SUBST([OCCFLAGS], ["-DOCCGEOMETRY -I$occdir/inc -I/usr/include/opencascade"]) + AC_SUBST([OCCLIBS], ["-L$occdir/lib -lTKernel -lTKGeomBase -lTKMath -lTKG2d -lTKG3d -lTKXSBase -lTKOffset -lTKFillet -lTKShHealing -lTKMesh -lTKMeshVS -lTKTopAlgo -lTKGeomAlgo -lTKBool -lTKPrim -lTKBO -lTKIGES -lTKBRep -lTKSTEPBase -lTKSTEP -lTKSTL -lTKSTEPAttr -lTKSTEP209 -lTKXDESTEP -lTKXDEIGES -lTKXCAF -lTKLCAF -lFWOSPlugin"]) + +# -lTKDCAF + + if test a$build_cpu = ax86_64 ; then + AC_SUBST([OCCFLAGS],["$OCCFLAGS -D_OCC64"]) + fi + + + AC_CHECK_HEADER([iostream],[OCCFLAGS="$OCCFLAGS -DHAVE_IOSTREAM"]) + AC_CHECK_HEADER([iostream.h],[OCC_FLAGS="$OCCFLAGS -DHAVE_IOSTREAM_H"]) + AC_CHECK_HEADER([limits],[OCCFLAGS="$OCCFLAGS -DHAVE_LIMITS"]) + AC_CHECK_HEADER([limits.h],[OCCFLAGS="$OCCFLAGS -DHAVE_LIMITS_H"]) + AC_CHECK_HEADER([iomanip],[OCCFLAGS="$OCCFLAGS -DHAVE_IOMANIP"]) + AC_CHECK_HEADER([iomanip.h],[OCCFLAGS="$OCCFLAGS -DHAVE_IOMANIP_H"]) + + + echo "OCCFLAGS = $OCCFLAGS" + echo "OCCLIBS = $OCCLIBS" +fi + + + + + + + +AC_ARG_WITH([togl], + [AC_HELP_STRING([--with-togl=dir],[directory containing libTogl1.7])], + [togldir=$withval] + [togllibfl="-L$withval$"] + ) +# [togllibfl="-L$(TK_BIN_DIR)/Togl1.7"] +# [togllibfl="-L/usr/local/lib/Togl1.7"] + + +nglibon=true +AC_ARG_ENABLE([nglib], + [AC_HELP_STRING([--enable-nglib],[generate shared library nglib])], + [if test "$enableval" = yes; then nglibon=true; else nglibon=false; fi]) + +ngguion=true +AC_ARG_ENABLE([gui], + [AC_HELP_STRING([--disable-gui],[don't build netgen with GUI])], + [if test "$enableval" = yes; then ngguion=true; else ngguion=false; fi]) + +metisdir=/usr/local +AC_ARG_WITH([metis], + [AC_HELP_STRING([--with-metis=dir],[path to metis 5.x])], + [metisdir=$withval], + [metisdir=/usr/local] + ) + +AC_ARG_ENABLE([parallel], + [AC_HELP_STRING([--enable-parallel],[enable mpi parallelization])], + [AC_SUBST([MPI_INCLUDES], "-I$metisdir/include -DMETIS")] + [CXXFLAGS="$CXXFLAGS -DPARALLEL"] + [AC_SUBST([MPI_LIBS], "-L$metisdir/lib -lmetis")] + ) +# -DVTRACE +# -lvt-hyb + +# [AC_SUBST([MPI_INCLUDES], "-I/opt/mpich/include -I/usr/include/mpich2 -I/usr/include/metis -DPARALLEL -I/usr/share/metis/Lib -DMETIS -DVTRACE -I/usr/local/include/vampirtrace") +# AC_SUBST([MPI_LIBS], "-lmetis -L/opt/mpich/ch-p4/lib -lmpich") + +# -lvt -lvt-mpi -lvt-mpi-unify") +# [AC_SUBST([MPI_INCLUDES], "-I/opt/mpich/include -DPARALLEL -I/usr/include/metis -DMETIS") +# AC_SUBST([MPI_LIBS], " -L/opt/mpich/ch-p4/lib64 -lmpich -lmetis") +# [AC_SUBST([MPI_INCLUDES], "-DPARALLEL -DNO_PARALLEL_THREADS -I/opt/mpich/include") +# AC_SUBST([MPI_LIBS], "") +# -lmetis +# [AC_SUBST([MPI_INCLUDES], "-I/opt/mpich/include -DPARALLEL -I/home/joachim/download/metis-4.0/Lib -DMETIS") +# AC_SUBST([MPI_LIBS], "-L/home/joachim/download/metis-4.0 -lmetis -L/opt/mpich/ch-p4/lib64 -lmpich") + + +jpeglibon=false +AC_ARG_ENABLE([jpeglib], + [AS_HELP_STRING([--enable-jpeglib],[enable snapshots using library libjpeg])], + [AC_SUBST([JPEGLIB_INCLUDES], "-DJPEGLIB") + AC_CHECK_LIB(jpeg, jpeg_start_compress, + AC_SUBST([JPEGLIB_LIBS], "-ljpeg") , + AC_MSG_ERROR([no usable library libjpeg found])) + [if test "$enableval" = yes; then jpeglibon=true; else jpeglibon=false; fi] + ] + ) + +ffmpegon=false +AC_ARG_ENABLE([ffmpeg], + [AS_HELP_STRING([--enable-ffmpeg],[enable video recording with FFmpeg, uses libavcodec])], + [AC_SUBST([FFMPEG_INCLUDES], "-DFFMPEG -D__STDC_CONSTANT_MACROS") + AC_SUBST([FFMPEG_LIBS], "-lavutil -lavformat -lavcodec -lavutil -lswscale -lz -lbz2") + [if test "$enableval" = yes; then ffmpegon=true; else ffmpegon=false; fi] + ] + ) + + +mklon=false +AC_ARG_ENABLE([mkl], + [AS_HELP_STRING([--enable-mkl],[link Intel's mkl library, necessary for ngsolve and mkl 11.x])], + [if test "$enableval" = yes; then mklon=true; else mklon=false; fi] + ) + +# only for GUI version + +if test a$ngguion = atrue ; then +# Tcl/Tk configuration: +TEA_INIT([3.9]) +TEA_PATH_TCLCONFIG +TEA_LOAD_TCLCONFIG +TEA_PATH_TKCONFIG +TEA_LOAD_TKCONFIG +TEA_PUBLIC_TCL_HEADERS +TEA_PUBLIC_TK_HEADERS + +AC_SUBST([TOGLLIBDIR], ["$togllibfl"]) +AC_CHECK_HEADER([togl.h]) +AC_CHECK_HEADER([GL/gl.h]) + + + +#-------------------------------------------------------------------- +# __CHANGE__ +# Choose OpenGL platform (borrowed from Togl1.7) +#-------------------------------------------------------------------- + +case "${TEA_WINDOWINGSYSTEM}" in + aqua) + AC_SUBST(TOGL_WINDOWINGSYSTEM,TOGL_AGL) + TEA_ADD_LIBS([-framework AGL -framework OpenGL -framework ApplicationServices]) + # libGLU is implicit in OpenGL framework + LIBGLU= + ;; + x11) + AC_SUBST(TOGL_WINDOWINGSYSTEM,TOGL_X11) + TEA_ADD_LIBS([-lGL -lXmu]) + LIBGLU=-lGLU + ;; + win32) + AC_SUBST(TOGL_WINDOWINGSYSTEM,TOGL_WGL) + TEA_ADD_LIBS([opengl32.lib user32.lib gdi32.lib]) + if test "$GCC" = "yes" ; then + LIBGLU=-lglu32 + else + LIBGLU=glu32.lib + fi + ;; + *) + AC_MSG_ERROR([Unsupported windowing system: ${TEA_WINDOWINGSYSTEM}]) + ;; +esac +AC_SUBST(LIBGLU) + +fi + + + +AM_CONDITIONAL([NGLIB], [test x$nglibon = xtrue]) +AM_CONDITIONAL([NGGUI], [test x$ngguion = xtrue]) +AM_CONDITIONAL([NGMKL], [test x$mklon = xtrue]) + +AC_CHECK_HEADER(pthread.h) + +AC_CHECK_FUNCS([pow]) +AC_CHECK_FUNCS([floor]) +AC_CHECK_FUNCS([matherr]) +AC_CHECK_HEADERS([limits.h]) + +AC_CHECK_LIB(pthread, pthread_create) + + + + +AC_CONFIG_FILES(Makefile libsrc/Makefile libsrc/csg/Makefile +libsrc/general/Makefile libsrc/geom2d/Makefile libsrc/gprim/Makefile +libsrc/include/Makefile libsrc/interface/Makefile +libsrc/linalg/Makefile libsrc/meshing/Makefile libsrc/occ/Makefile + libsrc/stlgeom/Makefile + libsrc/visualization/Makefile ng/Makefile nglib/Makefile + tutorials/Makefile doc/Makefile windows/Makefile ) + +AC_OUTPUT + + + + + + + + +AC_MSG_RESULT([ +------------------------------------------------------------------------ + $PACKAGE $VERSION: Automatic configuration OK. + + Enabled functionality: + + OCC: ............... $occon + JPEGlib: ........... $jpeglibon + FFMPEG: ............ $ffmpegon + NGLIB: ............. $nglibon + GUI: ............... $ngguion + + + Building: + + Type 'make' to compile $PACKAGE. + + Type 'make install' to install $PACKAGE. + + Example programs will be built but not installed. +------------------------------------------------------------------------ +]) diff --git a/depcomp b/depcomp new file mode 100755 index 00000000..4c20c6c9 --- /dev/null +++ b/depcomp @@ -0,0 +1,441 @@ +#! /bin/sh + +# depcomp - compile a program generating dependencies as side-effects +# Copyright 1999, 2000 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi +# `libtool' can also be set to `yes' or `no'. + +depfile=${depfile-`echo "$object" | sed 's,\([^/]*\)$,.deps/\1,;s/\.\([^.]*\)$/.P\1/'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. This file always lives in the current directory. + # Also, the AIX compiler puts `$object:' at the start of each line; + # $object doesn't have directory information. + stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + outname="$stripped.o" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Must come before tru64. + + # Intel's C compiler understands `-MD -MF file'. However + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^[^:]*: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 AIX compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + + tmpdepfile1="$object.d" + tmpdepfile2=`echo "$object" | sed -e 's/.o$/.d/'` + if test "$libtool" = yes; then + "$@" -Wc,-MD + else + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + else + tmpdepfile="$tmpdepfile2" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a space and a tab in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + test -z "$dashmflag" && dashmflag=-M + ( IFS=" " + case " $* " in + *" --mode=compile "*) # this is libtool, let us make it quiet + for arg + do # cycle over the arguments + case "$arg" in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + # X makedepend + ( + shift + cleared=no + for arg in "$@"; do + case $cleared in no) + set ""; shift + cleared=yes + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift;; + -*) + ;; + *) + set fnord "$@" "$arg"; shift;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tail +3 "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the proprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + ( IFS=" " + case " $* " in + *" --mode=compile "*) + for arg + do # cycle over the arguments + case $arg in + "--mode=compile") + # insert --quiet before "--mode=compile" + set fnord "$@" --quiet + shift # fnord + ;; + esac + set fnord "$@" "$arg" + shift # fnord + shift # "$arg" + done + ;; + esac + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + ) & + proc=$! + "$@" + stat=$? + wait "$proc" + if test "$stat" != 0; then exit $stat; fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 00000000..969d9515 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1 @@ +dist_doc_DATA = ng4.pdf diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 00000000..0b42f0f7 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,468 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = doc +DIST_COMMON = $(dist_doc_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(docdir)" +DATA = $(dist_doc_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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@ +dist_doc_DATA = ng4.pdf +all: all-am + +.SUFFIXES: +$(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) --foreign doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign doc/Makefile +.PRECIOUS: 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): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-dist_docDATA: $(dist_doc_DATA) + @$(NORMAL_INSTALL) + test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ + done + +uninstall-dist_docDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir) +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +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 $(DATA) +installdirs: + for dir in "$(DESTDIR)$(docdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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 mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-dist_docDATA + +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 -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-dist_docDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dist_docDATA 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-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + uninstall uninstall-am uninstall-dist_docDATA + + +# 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/doc/ng4.pdf b/doc/ng4.pdf new file mode 100644 index 00000000..8e1a6619 Binary files /dev/null and b/doc/ng4.pdf differ diff --git a/install-sh b/install-sh new file mode 100755 index 00000000..6781b987 --- /dev/null +++ b/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# 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 +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/libsrc/Makefile.am b/libsrc/Makefile.am new file mode 100644 index 00000000..8337b4b7 --- /dev/null +++ b/libsrc/Makefile.am @@ -0,0 +1,5 @@ +AM_CPPFLAGS = + +METASOURCES = AUTO + +SUBDIRS = general gprim linalg include meshing interface csg geom2d occ stlgeom visualization diff --git a/libsrc/Makefile.in b/libsrc/Makefile.in new file mode 100644 index 00000000..4c4a9758 --- /dev/null +++ b/libsrc/Makefile.in @@ -0,0 +1,619 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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@ +AM_CPPFLAGS = +METASOURCES = AUTO +SUBDIRS = general gprim linalg include meshing interface csg geom2d occ stlgeom visualization +all: all-recursive + +.SUFFIXES: +$(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) --foreign libsrc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/Makefile +.PRECIOUS: 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): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean 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 installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# 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/libsrc/csg/Makefile.am b/libsrc/csg/Makefile.am new file mode 100644 index 00000000..2c9f9b75 --- /dev/null +++ b/libsrc/csg/Makefile.am @@ -0,0 +1,32 @@ +noinst_HEADERS = algprim.hpp csgparser.hpp extrusion.hpp manifold.hpp \ +singularref.hpp surface.hpp brick.hpp curve2d.hpp gencyl.hpp \ +meshsurf.hpp solid.hpp triapprox.hpp csgeom.hpp edgeflw.hpp geoml.hpp \ +polyhedra.hpp specpoin.hpp csg.hpp explicitcurve2d.hpp identify.hpp \ +revolution.hpp spline3d.hpp vscsg.hpp + + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(TCL_INCLUDES) +METASOURCES = AUTO + +lib_LTLIBRARIES = libcsg.la + +if NGGUI +lib_LTLIBRARIES += libcsgvis.la +endif + + +libcsg_la_SOURCES = algprim.cpp brick.cpp \ +bspline2d.cpp csgeom.cpp csgparser.cpp curve2d.cpp edgeflw.cpp \ +explicitcurve2d.cpp extrusion.cpp gencyl.cpp genmesh.cpp identify.cpp \ +manifold.cpp meshsurf.cpp polyhedra.cpp revolution.cpp singularref.cpp \ +solid.cpp specpoin.cpp spline3d.cpp surface.cpp triapprox.cpp + + +libcsgvis_la_SOURCES = vscsg.cpp csgpkg.cpp + + +libcsgvis_la_LIBADD = libcsg.la +libcsg_la_LIBADD = $(top_builddir)/libsrc/meshing/libmesh.la + +# $(top_builddir)/libsrc/geom2d/libgeom2d.la + diff --git a/libsrc/csg/Makefile.in b/libsrc/csg/Makefile.in new file mode 100644 index 00000000..641c6a50 --- /dev/null +++ b/libsrc/csg/Makefile.in @@ -0,0 +1,639 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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@ +@NGGUI_TRUE@am__append_1 = libcsgvis.la +subdir = libsrc/csg +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libcsg_la_DEPENDENCIES = $(top_builddir)/libsrc/meshing/libmesh.la +am_libcsg_la_OBJECTS = algprim.lo brick.lo bspline2d.lo csgeom.lo \ + csgparser.lo curve2d.lo edgeflw.lo explicitcurve2d.lo \ + extrusion.lo gencyl.lo genmesh.lo identify.lo manifold.lo \ + meshsurf.lo polyhedra.lo revolution.lo singularref.lo solid.lo \ + specpoin.lo spline3d.lo surface.lo triapprox.lo +libcsg_la_OBJECTS = $(am_libcsg_la_OBJECTS) +libcsgvis_la_DEPENDENCIES = libcsg.la +am_libcsgvis_la_OBJECTS = vscsg.lo csgpkg.lo +libcsgvis_la_OBJECTS = $(am_libcsgvis_la_OBJECTS) +@NGGUI_TRUE@am_libcsgvis_la_rpath = -rpath $(libdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libcsg_la_SOURCES) $(libcsgvis_la_SOURCES) +DIST_SOURCES = $(libcsg_la_SOURCES) $(libcsgvis_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = algprim.hpp csgparser.hpp extrusion.hpp manifold.hpp \ +singularref.hpp surface.hpp brick.hpp curve2d.hpp gencyl.hpp \ +meshsurf.hpp solid.hpp triapprox.hpp csgeom.hpp edgeflw.hpp geoml.hpp \ +polyhedra.hpp specpoin.hpp csg.hpp explicitcurve2d.hpp identify.hpp \ +revolution.hpp spline3d.hpp vscsg.hpp + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(TCL_INCLUDES) +METASOURCES = AUTO +lib_LTLIBRARIES = libcsg.la $(am__append_1) +libcsg_la_SOURCES = algprim.cpp brick.cpp \ +bspline2d.cpp csgeom.cpp csgparser.cpp curve2d.cpp edgeflw.cpp \ +explicitcurve2d.cpp extrusion.cpp gencyl.cpp genmesh.cpp identify.cpp \ +manifold.cpp meshsurf.cpp polyhedra.cpp revolution.cpp singularref.cpp \ +solid.cpp specpoin.cpp spline3d.cpp surface.cpp triapprox.cpp + +libcsgvis_la_SOURCES = vscsg.cpp csgpkg.cpp +libcsgvis_la_LIBADD = libcsg.la +libcsg_la_LIBADD = $(top_builddir)/libsrc/meshing/libmesh.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/csg/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/csg/Makefile +.PRECIOUS: 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): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libcsg.la: $(libcsg_la_OBJECTS) $(libcsg_la_DEPENDENCIES) $(EXTRA_libcsg_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libcsg_la_OBJECTS) $(libcsg_la_LIBADD) $(LIBS) +libcsgvis.la: $(libcsgvis_la_OBJECTS) $(libcsgvis_la_DEPENDENCIES) $(EXTRA_libcsgvis_la_DEPENDENCIES) + $(CXXLINK) $(am_libcsgvis_la_rpath) $(libcsgvis_la_OBJECTS) $(libcsgvis_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/algprim.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/brick.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bspline2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csgeom.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csgparser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/csgpkg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curve2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/edgeflw.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/explicitcurve2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extrusion.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gencyl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genmesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/identify.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manifold.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshsurf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polyhedra.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/revolution.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/singularref.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/solid.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specpoin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spline3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triapprox.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vscsg.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + 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-libLTLIBRARIES + +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: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES 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 uninstall uninstall-am uninstall-libLTLIBRARIES + + +# $(top_builddir)/libsrc/geom2d/libgeom2d.la + +# 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/libsrc/csg/algprim.cpp b/libsrc/csg/algprim.cpp new file mode 100644 index 00000000..09bad013 --- /dev/null +++ b/libsrc/csg/algprim.cpp @@ -0,0 +1,1727 @@ +#include + + +#include +#include + + +namespace netgen +{ + + double + QuadraticSurface :: CalcFunctionValue (const Point<3> & p) const + { + return p(0) * (cxx * p(0) + cxy * p(1) + cxz * p(2) + cx) + + p(1) * (cyy * p(1) + cyz * p(2) + cy) + + p(2) * (czz * p(2) + cz) + c1; + } + + void + QuadraticSurface :: CalcGradient (const Point<3> & p, Vec<3> & grad) const + { + grad(0) = 2 * cxx * p(0) + cxy * p(1) + cxz * p(2) + cx; + grad(1) = 2 * cyy * p(1) + cxy * p(0) + cyz * p(2) + cy; + grad(2) = 2 * czz * p(2) + cxz * p(0) + cyz * p(1) + cz; + } + + void + QuadraticSurface :: CalcHesse (const Point<3> & /* p */, Mat<3> & hesse) const + { + hesse(0,0) = 2 * cxx; + hesse(1,1) = 2 * cyy; + hesse(2,2) = 2 * czz; + hesse(0,1) = hesse(1,0) = cxy; + hesse(0,2) = hesse(2,0) = cxz; + hesse(1,2) = hesse(2,1) = cyz; + } + + + void QuadraticSurface :: Read (istream & ist) + { + ist >> cxx >> cyy >> czz >> cxy >> cxz >> cyz >> cx >> cy >> cz >> c1; + } + + void QuadraticSurface :: Print (ostream & ost) const + { + ost << cxx << " " << cyy << " " << czz << " " + << cxy << " " << cxz << " " << cyz << " " + << cx << " " << cy << " " << cz << " " + << c1; + } + + + void QuadraticSurface :: PrintCoeff (ostream & ost) const + { + ost << " cxx = " << cxx + << " cyy = " << cyy + << " czz = " << czz + << " cxy = " << cxy + << " cxz = " << cxz + << " cyz = " << cyz + << " cx = " << cx + << " cy = " << cy + << " cz = " << cz + << " c1 = " << c1 << endl; + } + + + + Point<3> QuadraticSurface :: GetSurfacePoint () const + { + MyError ("GetSurfacePoint called for QuadraticSurface"); + return Point<3> (0, 0, 0); + } + + + Plane :: Plane (const Point<3> & ap, Vec<3> an) + { + eps_base = 1e-8; + + p = ap; + n = an; + CalcData(); + } + + void Plane :: CalcData() + { + n.Normalize(); + cxx = cyy = czz = cxy = cxz = cyz = 0; + cx = n(0); cy = n(1); cz = n(2); + c1 = - (cx * p(0) + cy * p(1) + cz * p(2)); + } + + Primitive * Plane :: Copy () const + { + return new Plane (p, n); + } + + void Plane :: Transform (Transformation<3> & trans) + { + Point<3> hp; + Vec<3> hn; + trans.Transform (p, hp); + trans.Transform (n, hn); + p = hp; + n = hn; + + CalcData(); + } + + + + void Plane :: GetPrimitiveData (const char *& classname, + Array & coeffs) const + { + classname = "plane"; + coeffs.SetSize (6); + coeffs.Elem(1) = p(0); + coeffs.Elem(2) = p(1); + coeffs.Elem(3) = p(2); + coeffs.Elem(4) = n(0); + coeffs.Elem(5) = n(1); + coeffs.Elem(6) = n(2); + } + + void Plane :: SetPrimitiveData (Array & coeffs) + { + p(0) = coeffs.Elem(1); + p(1) = coeffs.Elem(2); + p(2) = coeffs.Elem(3); + n(0) = coeffs.Elem(4); + n(1) = coeffs.Elem(5); + n(2) = coeffs.Elem(6); + + CalcData(); + } + + Primitive * Plane :: CreateDefault () + { + return new Plane (Point<3> (0,0,0), Vec<3> (0,0,1)); + } + + + int Plane :: IsIdentic (const Surface & s2, int & inv, double eps) const + { + const Plane * ps2 = dynamic_cast(&s2); + + if(ps2) + { + Point<3> pp2 = ps2->GetSurfacePoint(); + Vec<3> n2 = s2.GetNormalVector(pp2); + + if(fabs(n*n2) < 1.-eps_base) + return 0; + + if (fabs (s2.CalcFunctionValue(p)) > eps) return 0; + } + else + { + if (fabs (s2.CalcFunctionValue(p)) > eps) return 0; + Vec<3> hv1, hv2; + hv1 = n.GetNormal (); + hv2 = Cross (n, hv1); + + Point<3> hp = p + hv1; + if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0; + hp = p + hv2; + if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0; + } + + Vec<3> n1, n2; + n1 = GetNormalVector (p); + n2 = s2.GetNormalVector (p); + inv = (n1 * n2 < 0); + return 1; + } + + + + void Plane :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) + { + Surface::DefineTangentialPlane (ap1, ap2); + } + + + void Plane :: ToPlane (const Point<3> & p3d, + Point<2> & pplane, + double h, int & zone) const + { + Vec<3> p1p; + + p1p = p3d - p1; + p1p /= h; + pplane(0) = p1p * ex; + pplane(1) = p1p * ey; + zone = 0; + } + + void Plane :: FromPlane (const Point<2> & pplane, Point<3> & p3d, double h) const + { + p3d = p1 + (h * pplane(0)) * ex + (h * pplane(1)) * ey; + } + + + void Plane :: Project (Point<3> & p3d) const + { + double val = Plane::CalcFunctionValue (p3d); + p3d -= val * n; + } + + INSOLID_TYPE Plane :: BoxInSolid (const BoxSphere<3> & box) const + { + int i; + double val; + Point<3> pp; + + val = Plane::CalcFunctionValue (box.Center()); + if (val > box.Diam() / 2) return IS_OUTSIDE; + if (val < -box.Diam() / 2) return IS_INSIDE; + + if (val > 0) + { + /* + double modify = + ((box.MaxX()-box.MinX()) * fabs (cx) + + (box.MaxY()-box.MinY()) * fabs (cy) + + (box.MaxZ()-box.MinZ()) * fabs (cz)) / 2; + */ + Vec<3> vdiag = box.PMax() - box.PMin(); + double modify = (vdiag(0) * fabs (cx) + + vdiag(1) * fabs (cy) + + vdiag(2) * fabs (cz) ) / 2; + + if (val - modify < 0) + return DOES_INTERSECT; + return IS_OUTSIDE; + + // only outside or intersect possible + for (i = 0; i < 8; i++) + { + pp = box.GetPointNr (i); + val = Plane::CalcFunctionValue (pp); + if (val < 0) + return DOES_INTERSECT; + } + return IS_OUTSIDE; + } + else + { + /* + double modify = + ((box.MaxX()-box.MinX()) * fabs (cx) + + (box.MaxY()-box.MinY()) * fabs (cy) + + (box.MaxZ()-box.MinZ()) * fabs (cz)) / 2; + */ + Vec<3> vdiag = box.PMax() - box.PMin(); + double modify = (vdiag(0) * fabs (cx) + + vdiag(1) * fabs (cy) + + vdiag(2) * fabs (cz) ) / 2; + if (val + modify > 0) + return DOES_INTERSECT; + return IS_INSIDE; + + + // only inside or intersect possible + for (i = 0; i < 8; i++) + { + pp = box.GetPointNr (i); + val = Plane::CalcFunctionValue (pp); + if (val > 0) + return DOES_INTERSECT; + } + return IS_INSIDE; + } + + + + /* + for (i = 1; i <= 8; i++) + { + box.GetPointNr (i, p); + val = CalcFunctionValue (p); + if (val > 0) inside = 0; + if (val < 0) outside = 0; + } + + if (inside) return IS_INSIDE; + if (outside) return IS_OUTSIDE; + return DOES_INTERSECT; + */ + } + + + + // double Plane :: CalcFunctionValue (const Point<3> & p3d) const + // { + // return cx * p3d(0) + cy * p3d(1) + cz * p3d(2) + c1; + // } + + void Plane :: CalcGradient (const Point<3> & /* p */, Vec<3> & grad) const + { + grad(0) = cx; + grad(1) = cy; + grad(2) = cz; + } + + void Plane :: CalcHesse (const Point<3> & /* p */, Mat<3> & hesse) const + { + hesse = 0; + } + + double Plane :: HesseNorm () const + { + return 0; + } + + + Point<3> Plane :: GetSurfacePoint () const + { + return p; + } + + + void Plane :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & boundingbox, double /* facets */) const + { + // find triangle, such that + // boundingbox \cap plane is contained in it + + Point<3> c = boundingbox.Center(); + double r = boundingbox.Diam(); + + Project (c); + Vec<3> t1 = n.GetNormal(); + Vec<3> t2 = Cross (n, t1); + + t1.Normalize(); + t2.Normalize(); + + tas.AddPoint (c + (-0.5 * r) * t2 + (sqrt(0.75) * r) * t1); + tas.AddPoint (c + (-0.5 * r) * t2 + (-sqrt(0.75) * r) * t1); + tas.AddPoint (c + r * t2); + + tas.AddTriangle (TATriangle (0, 0, 1, 2)); + } + + + + + Sphere :: Sphere (const Point<3> & ac, double ar) + { + c = ac; + r = ar; + invr = 1.0/r; + + cxx = cyy = czz = 0.5 / r; + cxy = cxz = cyz = 0; + cx = - c(0) / r; + cy = - c(1) / r; + cz = - c(2) / r; + c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2; + } + + void Sphere :: GetPrimitiveData (const char *& classname, Array & coeffs) const + { + classname = "sphere"; + coeffs.SetSize (4); + coeffs.Elem(1) = c(0); + coeffs.Elem(2) = c(1); + coeffs.Elem(3) = c(2); + coeffs.Elem(4) = r; + } + + void Sphere :: SetPrimitiveData (Array & coeffs) + { + c(0) = coeffs.Elem(1); + c(1) = coeffs.Elem(2); + c(2) = coeffs.Elem(3); + r = coeffs.Elem(4); + + invr = 1.0/r; + cxx = cyy = czz = 0.5 / r; + cxy = cxz = cyz = 0; + cx = - c(0) / r; + cy = - c(1) / r; + cz = - c(2) / r; + c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2; + } + + Primitive * Sphere :: CreateDefault () + { + return new Sphere (Point<3> (0,0,0), 1); + } + + + + Primitive * Sphere :: Copy () const + { + return new Sphere (c, r); + } + + void Sphere :: Transform (Transformation<3> & trans) + { + Point<3> hp; + trans.Transform (c, hp); + c = hp; + + cxx = cyy = czz = 0.5 / r; + cxy = cxz = cyz = 0; + cx = - c(0) / r; + cy = - c(1) / r; + cz = - c(2) / r; + c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2; + } + + + double Sphere :: CalcFunctionValue (const Point<3> & point) const + { + return 0.5* (invr * Abs2 (point-c) - r); + } + + + int Sphere :: IsIdentic (const Surface & s2, int & inv, double eps) const + { + const Sphere * sp2 = dynamic_cast (&s2); + + if (!sp2) return 0; + + if (Dist (sp2->c, c) > eps) return 0; + if (fabs (sp2->r - r) > eps) return 0; + + inv = 0; + + return 1; + } + + + void Sphere :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) + { + Surface::DefineTangentialPlane (ap1, ap2); + + ez = p1 - c; + ez /= ez.Length(); + + ex = p2 - p1; + ex -= (ex * ez) * ez; + ex /= ex.Length(); + + ey = Cross (ez, ex); + } + + + void Sphere :: ToPlane (const Point<3> & p, Point<2> & pplane, double h, int & zone) const + { + Vec<3> p1p; + + p1p = p - p1; + + /* + if (p1p * ez < -r) + { + zone = -1; + pplane = Point<2> (1E8, 1E8); + } + else + { + zone = 0; + p1p /= h; + pplane(0) = p1p * ex; + pplane(1) = p1p * ey; + } + */ + + Point<3> p1top = c + (c - p1); + + Vec<3> p1topp = p - p1top; + Vec<3> p1topp1 = p1 - p1top; + Vec<3> lam; + // SolveLinearSystem (ex, ey, p1topp, p1topp1, lam); + + Mat<3> m; + for (int i = 0; i < 3; i++) + { + m(i, 0) = ex(i); + m(i, 1) = ey(i); + m(i, 2) = p1topp(i); + } + m.Solve (p1topp1, lam); + + pplane(0) = -lam(0) / h; + pplane(1) = -lam(1) / h; + + if (lam(2) > 2) + zone = -1; + else + zone = 0; + } + + void Sphere :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const + { + /* + // Vec<3> p1p; + double z; + Point<2> pplane2 (pplane); + + pplane2(0) *= h; + pplane2(1) *= h; + z = -r + sqrt (sqr (r) - sqr (pplane2(0)) - sqr (pplane2(1))); + // p = p1; + p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0) + z * ez(0); + p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1) + z * ez(1); + p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2) + z * ez(2); + */ + + Point<2> pplane2 (pplane); + + pplane2(0) *= h; + pplane2(1) *= h; + + p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0); + p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1); + p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2); + Project (p); + } + + + void Sphere :: Project (Point<3> & p) const + { + Vec<3> v; + v = p - c; + v *= (r / v.Length()); + p = c + v; + } + + + INSOLID_TYPE Sphere :: BoxInSolid (const BoxSphere<3> & box) const + { + double dist; + dist = Dist (box.Center(), c); + + if (dist - box.Diam()/2 > r) return IS_OUTSIDE; + if (dist + box.Diam()/2 < r) return IS_INSIDE; + return DOES_INTERSECT; + } + + double Sphere :: HesseNorm () const + { + return 2 / r; + } + + + Point<3> Sphere :: GetSurfacePoint () const + { + return c + Vec<3> (r, 0, 0); + } + + + void Sphere :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int n = int(facets) + 1; + + for (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double bg = M_PI * (double(j) / n - 0.5); + + Point<3> p(c(0) + r * cos(bg) * sin (lg), + c(1) + r * cos(bg) * cos (lg), + c(2) + r * sin(bg)); + tas.AddPoint (p); + } + + for (int j = 0; j < n; j++) + for (int i = 0; i < n; i++) + { + int pi = i + (n+1) * j; + tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); + tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); + } + } + + + + + + Ellipsoid :: + Ellipsoid (const Point<3> & aa, + const Vec<3> & av1, const Vec<3> & av2, const Vec<3> & av3) + { + a = aa; + v1 = av1; + v2 = av2; + v3 = av3; + + CalcData(); + } + + + void Ellipsoid :: CalcData () + { + // f = (x-a, vl)^2 / |vl|^2 + (x-a, vs)^2 / |vs|^2 -1 + // f = sum_{i=1}^3 (x-a,v_i)^2 / |vi|^4 - 1 = sum (x-a,hv_i)^2 + + Vec<3> hv1, hv2, hv3; + double lv1 = v1.Length2 (); + if (lv1 < 1e-32) lv1 = 1; + double lv2 = v2.Length2 (); + if (lv2 < 1e-32) lv2 = 1; + double lv3 = v3.Length2 (); + if (lv3 < 1e-32) lv3 = 1; + + rmin = sqrt (min3 (lv1, lv2, lv3)); + + hv1 = (1.0 / lv1) * v1; + hv2 = (1.0 / lv2) * v2; + hv3 = (1.0 / lv3) * v3; + + cxx = hv1(0) * hv1(0) + hv2(0) * hv2(0) + hv3(0) * hv3(0); + cyy = hv1(1) * hv1(1) + hv2(1) * hv2(1) + hv3(1) * hv3(1); + czz = hv1(2) * hv1(2) + hv2(2) * hv2(2) + hv3(2) * hv3(2); + + cxy = 2 * (hv1(0) * hv1(1) + hv2(0) * hv2(1) + hv3(0) * hv3(1)); + cxz = 2 * (hv1(0) * hv1(2) + hv2(0) * hv2(2) + hv3(0) * hv3(2)); + cyz = 2 * (hv1(1) * hv1(2) + hv2(1) * hv2(2) + hv3(1) * hv3(2)); + + Vec<3> va (a); + c1 = sqr(va * hv1) + sqr(va * hv2) + sqr(va * hv3) - 1; + + Vec<3> v = -2 * (va * hv1) * hv1 - 2 * (va * hv2) * hv2 - 2 * (va * hv3) * hv3; + cx = v(0); + cy = v(1); + cz = v(2); + } + + + INSOLID_TYPE Ellipsoid :: BoxInSolid (const BoxSphere<3> & box) const + { + // double grad = 2.0 / rmin; + // double grad = 3*(box.Center()-a).Length() / (rmin*rmin*rmin); + + double ggrad = 1.0 / (rmin*rmin); + Vec<3> g; + double val = CalcFunctionValue (box.Center()); + CalcGradient (box.Center(), g); + double grad = g.Length(); + + double r = box.Diam() / 2; + double maxval = grad * r + ggrad * r * r; + + // (*testout) << "box = " << box << ", val = " << val << ", maxval = " << maxval << endl; + + if (val > maxval) return IS_OUTSIDE; + if (val < -maxval) return IS_INSIDE; + return DOES_INTERSECT; + } + + + double Ellipsoid :: HesseNorm () const + { + return 1.0/ (rmin * rmin); + } + + double Ellipsoid :: MaxCurvature () const + { + const double a2 = v1.Length2(); + const double b2 = v2.Length2(); + const double c2 = v3.Length2(); + + return max3 ( sqrt(a2)/min2(b2,c2), sqrt(b2)/min2(a2,c2), sqrt(c2)/min2(a2,b2) ); + } + + Point<3> Ellipsoid :: GetSurfacePoint () const + { + return a + v1; + } + + + + void Ellipsoid :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int n = int(facets) + 1; + + for (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double bg = M_PI * (double(j) / n - 0.5); + + Point<3> p(a + + sin (bg) * v1 + + cos (bg) * sin (lg) * v2 + + cos (bg) * cos (lg) * v3); + + tas.AddPoint (p); + } + + for (int j = 0; j < n; j++) + for (int i = 0; i < n; i++) + { + int pi = i + (n+1) * j; + tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); + tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); + } + } + + + + + + + + + + + + + + + + + + Cylinder :: Cylinder (Array & coeffs) + { + SetPrimitiveData(coeffs); + } + + Cylinder :: Cylinder (const Point<3> & aa, const Point<3> & ab, double ar) + { + a = aa; + b = ab; + vab = (b - a); + vab /= vab.Length(); + r = ar; + + // ( - 2 + + // - ^2 + 2 - ^2 + // - r^2) / (2r) = 0 + + double hv; + cxx = cyy = czz = 0.5 / r; + cxy = cxz = cyz = 0; + cx = - a(0) / r; + cy = - a(1) / r; + cz = - a(2) / r; + c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r); + hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2); + cxx -= vab(0) * vab(0) / (2 * r); + cyy -= vab(1) * vab(1) / (2 * r); + czz -= vab(2) * vab(2) / (2 * r); + cxy -= vab(0) * vab(1) / r; + cxz -= vab(0) * vab(2) / r; + cyz -= vab(1) * vab(2) / r; + cx += vab(0) * hv / r; + cy += vab(1) * hv / r; + cz += vab(2) * hv / r; + c1 -= hv * hv / (2 * r); + c1 -= r / 2; + // PrintCoeff (); + } + + + + + void Cylinder :: GetPrimitiveData (const char *& classname, Array & coeffs) const + { + classname = "cylinder"; + coeffs.SetSize (7); + coeffs.Elem(1) = a(0); + coeffs.Elem(2) = a(1); + coeffs.Elem(3) = a(2); + coeffs.Elem(4) = b(0); + coeffs.Elem(5) = b(1); + coeffs.Elem(6) = b(2); + coeffs.Elem(7) = r; + } + + void Cylinder :: SetPrimitiveData (Array & coeffs) + { + a(0) = coeffs.Elem(1); + a(1) = coeffs.Elem(2); + a(2) = coeffs.Elem(3); + b(0) = coeffs.Elem(4); + b(1) = coeffs.Elem(5); + b(2) = coeffs.Elem(6); + r = coeffs.Elem(7); + + + vab = (b - a); + vab /= vab.Length(); + + + double hv; + cxx = cyy = czz = 0.5 / r; + cxy = cxz = cyz = 0; + cx = - a(0) / r; + cy = - a(1) / r; + cz = - a(2) / r; + c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r); + hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2); + cxx -= vab(0) * vab(0) / (2 * r); + cyy -= vab(1) * vab(1) / (2 * r); + czz -= vab(2) * vab(2) / (2 * r); + cxy -= vab(0) * vab(1) / r; + cxz -= vab(0) * vab(2) / r; + cyz -= vab(1) * vab(2) / r; + cx += vab(0) * hv / r; + cy += vab(1) * hv / r; + cz += vab(2) * hv / r; + c1 -= hv * hv / (2 * r); + c1 -= r / 2; + } + + Primitive * Cylinder :: CreateDefault () + { + return new Cylinder (Point<3> (0,0,0), Point<3> (1,0,0), 1); + } + + + + + Primitive * Cylinder :: Copy () const + { + return new Cylinder (a, b, r); + } + + + int Cylinder :: IsIdentic (const Surface & s2, int & inv, double eps) const + { + const Cylinder * cyl2 = dynamic_cast (&s2); + + if (!cyl2) return 0; + + if (fabs (cyl2->r - r) > eps) return 0; + + Vec<3> v1 = b - a; + Vec<3> v2 = cyl2->a - a; + + if ( fabs (v1 * v2) < (1-eps) * v1.Length() * v2.Length()) return 0; + v2 = cyl2->b - a; + if ( fabs (v1 * v2) < (1-eps) * v1.Length() * v2.Length()) return 0; + + inv = 0; + return 1; + } + + + + void Cylinder :: Transform (Transformation<3> & trans) + { + Point<3> hp; + trans.Transform (a, hp); + a = hp; + trans.Transform (b, hp); + b = hp; + + vab = (b - a); + vab /= vab.Length(); + + // ( - 2 + + // - ^2 + 2 - ^2 + // - r^2) / (2r) = 0 + + double hv; + cxx = cyy = czz = 0.5 / r; + cxy = cxz = cyz = 0; + cx = - a(0) / r; + cy = - a(1) / r; + cz = - a(2) / r; + c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r); + hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2); + cxx -= vab(0) * vab(0) / (2 * r); + cyy -= vab(1) * vab(1) / (2 * r); + czz -= vab(2) * vab(2) / (2 * r); + cxy -= vab(0) * vab(1) / r; + cxz -= vab(0) * vab(2) / r; + cyz -= vab(1) * vab(2) / r; + cx += vab(0) * hv / r; + cy += vab(1) * hv / r; + cz += vab(2) * hv / r; + c1 -= hv * hv / (2 * r); + c1 -= r / 2; + // PrintCoeff (); + } + + + + + + + + + + void Cylinder :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) + { + Surface::DefineTangentialPlane (ap1, ap2); + + ez = Center (p1, p2) - a; + ez -= (ez * vab) * vab; + ez /= ez.Length(); + + ex = p2 - p1; + ex -= (ex * ez) * ez; + ex /= ex.Length(); + + ey = Cross (ez, ex); + } + + + void Cylinder :: ToPlane (const Point<3> & p, + Point<2> & pplane, + double h, int & zone) const + { + Point<3> cp1p2 = Center (p1, p2); + Project (cp1p2); + + Point<3> ccp1p2 = a + ( (cp1p2 - a) * vab ) * vab; + + Vec<3> er = cp1p2 - ccp1p2; + er.Normalize(); + Vec<3> ephi = Cross (vab, er); + + double co, si; + Point<2> p1p, p2p, pp; + + co = er * (p1 - ccp1p2); + si = ephi * (p1 - ccp1p2); + p1p(0) = r * atan2 (si, co); + p1p(1) = vab * (p1 - ccp1p2); + + co = er * (p2 - ccp1p2); + si = ephi * (p2 - ccp1p2); + p2p(0) = r * atan2 (si, co); + p2p(1) = vab * (p2 - ccp1p2); + + co = er * (p - ccp1p2); + si = ephi * (p - ccp1p2); + + double phi = atan2 (si, co); + pp(0) = r * phi; + pp(1) = vab * (p - ccp1p2); + + zone = 0; + if (phi > 1.57) zone = 1; + if (phi < -1.57) zone = 2; + + + + Vec<2> e2x = p2p - p1p; + e2x /= e2x.Length(); + + Vec<2> e2y (-e2x(1), e2x(0)); + + Vec<2> p1pp = pp - p1p; + + + pplane(0) = (p1pp * e2x) / h; + pplane(1) = (p1pp * e2y) / h; + + /* + (*testout) << "p1 = " << p1 << ", p2 = " << p2 << endl; + (*testout) << "p = " << p << ", pp = " << pp << ", pplane = " << pplane << endl; + */ + + /* + Vec<3> p1p; + + p1p = p - p1; + + if (p1p * ez < -1 * r) + { + zone = -1; + pplane(0) = 1e8; + pplane(1) = 1e8; + } + else + { + zone = 0; + p1p /= h; + pplane(0) = p1p * ex; + pplane(1) = p1p * ey; + } + */ + } + + void Cylinder :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const + { + Point<2> pplane2 (pplane); + + pplane2(0) *= h; + pplane2(1) *= h; + + p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0); + p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1); + p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2); + Project (p); + } + + + void Cylinder :: Project (Point<3> & p) const + { + Vec<3> v; + Point<3> c; + + c = a + ((p - a) * vab) * vab; + v = p - c; + v *= (r / v.Length()); + p = c + v; + } + /* + int Cylinder :: RootInBox (const BoxSphere<3> & box) const + { + double dist; + dist = sqrt (2 * CalcFunctionValue(box.Center()) * r + r * r); + if (fabs (dist - r) > box.Diam()/2) return 0; + return 2; + } + */ + + INSOLID_TYPE Cylinder :: BoxInSolid (const BoxSphere<3> & box) const + { + double dist; + // dist = sqrt (2 * CalcFunctionValue(box.Center()) * r + r * r); + + dist = (2 * CalcFunctionValue(box.Center()) * r + r * r); + if (dist <= 0) dist = 0; + else dist = sqrt (dist + 1e-16); + + if (dist - box.Diam()/2 > r) return IS_OUTSIDE; + if (dist + box.Diam()/2 < r) return IS_INSIDE; + return DOES_INTERSECT; + } + + + double Cylinder :: HesseNorm () const + { + return 2 / r; + } + + Point<3> Cylinder :: GetSurfacePoint () const + { + Vec<3> vr; + if (fabs (vab(0)) > fabs(vab(2))) + vr = Vec<3> (vab(1), -vab(0), 0); + else + vr = Vec<3> (0, -vab(2), vab(1)); + + vr *= (r / vr.Length()); + return a + vr; + } + + void Cylinder :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int n = int(facets) + 1; + + Vec<3> lvab = b - a; + Vec<3> n1 = lvab.GetNormal(); + Vec<3> n2 = Cross (lvab, n1); + + n1.Normalize(); + n2.Normalize(); + + + for (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double bg = double(j) / n; + + Point<3> p = a + (bg * lvab) + + ((r * cos(lg)) * n1) + + ((r * sin(lg)) * n2); + + tas.AddPoint (p); + } + + for (int j = 0; j < n; j++) + for (int i = 0; i < n; i++) + { + int pi = i + (n+1) * j; + tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); + tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); + } + } + + + + + + + + + + EllipticCylinder :: + EllipticCylinder (const Point<3> & aa, + const Vec<3> & avl, const Vec<3> & avs) + { + a = aa; + if(avl.Length2() > avs.Length2()) + { + vl = avl; + vs = avs; + } + else + { + vl = avs; + vs = avl; + } + + CalcData(); + } + + EllipticCylinder :: EllipticCylinder (Array & coeffs) + { + SetPrimitiveData(coeffs); + } + + + + void EllipticCylinder :: GetPrimitiveData (const char *& classname, Array & coeffs) const + { + classname = "ellipticcylinder"; + coeffs.SetSize (9); + coeffs[0] = a(0); + coeffs[1] = a(1); + coeffs[2] = a(2); + coeffs[3] = vl(0); + coeffs[4] = vl(1); + coeffs[5] = vl(2); + coeffs[6] = vs(0); + coeffs[7] = vs(1); + coeffs[8] = vs(2); + } + + void EllipticCylinder :: SetPrimitiveData (Array & coeffs) + { + a(0) = coeffs[0]; + a(1) = coeffs[1]; + a(2) = coeffs[2]; + vl(0) = coeffs[3]; + vl(1) = coeffs[4]; + vl(2) = coeffs[5]; + vs(0) = coeffs[6]; + vs(1) = coeffs[7]; + vs(2) = coeffs[8]; + + CalcData(); + } + + + + void EllipticCylinder :: CalcData () + { + // f = (x-a, vl)^2 / |vl|^2 + (x-a, vs)^2 / |vs|^2 -1 + + Vec<3> hvl, hvs; + double lvl = vl.Length2 (); + if (lvl < 1e-32) lvl = 1; + double lvs = vs.Length2 (); + if (lvs < 1e-32) lvs = 1; + + hvl = (1.0 / lvl) * vl; + hvs = (1.0 / lvs) * vs; + + cxx = hvl(0) * hvl(0) + hvs(0) * hvs(0); + cyy = hvl(1) * hvl(1) + hvs(1) * hvs(1); + czz = hvl(2) * hvl(2) + hvs(2) * hvs(2); + + cxy = 2 * (hvl(0) * hvl(1) + hvs(0) * hvs(1)); + cxz = 2 * (hvl(0) * hvl(2) + hvs(0) * hvs(2)); + cyz = 2 * (hvl(1) * hvl(2) + hvs(1) * hvs(2)); + + Vec<3> va (a); + c1 = pow(va * hvl,2) + pow(va * hvs,2) - 1; + + Vec<3> v = -2 * (va * hvl) * hvl - 2 * (va * hvs) * hvs; + cx = v(0); + cy = v(1); + cz = v(2); + } + + + INSOLID_TYPE EllipticCylinder :: BoxInSolid (const BoxSphere<3> & box) const + { + double grad = 2.0 / vs.Length (); + double ggrad = 1.0 / vs.Length2 (); + + double val = CalcFunctionValue (box.Center()); + double r = box.Diam() / 2; + double maxval = grad * r + ggrad * r * r; + + // (*testout) << "box = " << box << ", val = " << val << ", maxval = " << maxval << endl; + + if (val > maxval) return IS_OUTSIDE; + if (val < -maxval) return IS_INSIDE; + return DOES_INTERSECT; + } + + + double EllipticCylinder :: HesseNorm () const + { + return 1.0/min(vs.Length2 (),vl.Length2()); + } + + double EllipticCylinder :: MaxCurvature () const + { + double aa = vs.Length(); + double bb = vl.Length(); + + return max2(bb/(aa*aa),aa/(bb*bb)); + } + + double EllipticCylinder :: MaxCurvatureLoc (const Point<3> & /* c */, + double /* rad */) const + { + // saubere Loesung wird noch notwendig !!! + double aa = vs.Length(); + double bb = vl.Length(); + return max2(bb/(aa*aa),aa/(bb*bb)); + } + + + + Point<3> EllipticCylinder :: GetSurfacePoint () const + { + return a + vl; + } + + + + void EllipticCylinder :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int n = int(facets) + 1; + + Vec<3> axis = Cross (vl, vs); + + for (int j = 0; j <= n; j++) + for (int i = 0; i <= n; i++) + { + double lg = 2 * M_PI * double (i) / n; + double bg = double(j) / n; + + Point<3> p = a + (bg * axis) + + cos(lg) * vl + sin(lg) * vs; + + tas.AddPoint (p); + } + + for (int j = 0; j < n; j++) + for (int i = 0; i < n; i++) + { + int pi = i + (n+1) * j; + tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); + tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); + } + } + + + + + + + + + + + Cone :: Cone (const Point<3> & aa, const Point<3> & ab, + double ara, double arb) + { + a = aa; + b = ab; + ra = ara; + rb = arb; + + CalcData(); + // Print (cout); + } + + + Primitive * Cone :: CreateDefault () + { + return new Cone (Point<3> (0,0,0), Point<3> (1,0,0), 0.5, 0.2); + } + + + + + void Cone :: GetPrimitiveData (const char *& classname, Array & coeffs) const + { + classname = "cone"; + coeffs.SetSize (8); + coeffs.Elem(1) = a(0); + coeffs.Elem(2) = a(1); + coeffs.Elem(3) = a(2); + coeffs.Elem(4) = b(0); + coeffs.Elem(5) = b(1); + coeffs.Elem(6) = b(2); + coeffs.Elem(7) = ra; + coeffs.Elem(8) = rb; + } + + void Cone :: SetPrimitiveData (Array & coeffs) + { + a(0) = coeffs.Elem(1); + a(1) = coeffs.Elem(2); + a(2) = coeffs.Elem(3); + b(0) = coeffs.Elem(4); + b(1) = coeffs.Elem(5); + b(2) = coeffs.Elem(6); + ra = coeffs.Elem(7); + rb = coeffs.Elem(8); + + CalcData(); + } + + void Cone :: CalcData () + { + + minr = (ra < rb) ? ra : rb; + + vab = b - a; + vabl = vab.Length(); + + Vec<3> va (a); + + // + // f = r(P)^2 - R(z(P))^2 + // + // z(P) = t0vec * P + t0 = (P-a, b-a)/(b-a,b-a) + // R(z(P)) = t1vec * P + t1 = rb * z + ra * (1-z) + // r(P)^2 =||P-a||^2 - ||a-b||^2 z^2k + + cosphi = vabl / sqrt (vabl*vabl+sqr(ra-rb)); + + t0vec = vab; + t0vec /= (vabl * vabl); + t0 = -(va * vab) / (vabl * vabl); + + t1vec = t0vec; + t1vec *= (rb - ra); + t1 = ra + (rb - ra) * t0; + + cxx = cyy = czz = 1; + cxy = cxz = cyz = 0; + + cxx = 1 - (vab*vab) * t0vec(0) * t0vec(0) - t1vec(0) * t1vec(0); + cyy = 1 - (vab*vab) * t0vec(1) * t0vec(1) - t1vec(1) * t1vec(1); + czz = 1 - (vab*vab) * t0vec(2) * t0vec(2) - t1vec(2) * t1vec(2); + + cxy = -2 * (vab * vab) * t0vec(0) * t0vec(1) - 2 * t1vec(0) * t1vec(1); + cxz = -2 * (vab * vab) * t0vec(0) * t0vec(2) - 2 * t1vec(0) * t1vec(2); + cyz = -2 * (vab * vab) * t0vec(1) * t0vec(2) - 2 * t1vec(1) * t1vec(2); + + cx = -2 * a(0) - 2 * (vab * vab) * t0 * t0vec(0) - 2 * t1 * t1vec(0); + cy = -2 * a(1) - 2 * (vab * vab) * t0 * t0vec(1) - 2 * t1 * t1vec(1); + cz = -2 * a(2) - 2 * (vab * vab) * t0 * t0vec(2) - 2 * t1 * t1vec(2); + + c1 = va.Length2() - (vab * vab) * t0 * t0 - t1 * t1; + + + double maxr = max2(ra,rb); + cxx /= maxr; cyy /= maxr; czz /= maxr; + cxy /= maxr; cxz /= maxr; cyz /= maxr; + cx /= maxr; cy /= maxr; cz /= maxr; + c1 /= maxr; + + + // (*testout) << "t0vec = " << t0vec << " t0 = " << t0 << endl; + // (*testout) << "t1vec = " << t1vec << " t1 = " << t1 << endl; + // PrintCoeff (*testout); + } + + + INSOLID_TYPE Cone :: BoxInSolid (const BoxSphere<3> & box) const + { + Vec<3> cv(box.Center()); + + double rzp = cv * t1vec + t1; + double dist = sqrt (CalcFunctionValue(box.Center()) *max2(ra,rb) + rzp * rzp) - rzp; + + dist *= cosphi; + INSOLID_TYPE res = DOES_INTERSECT; + + if (dist - box.Diam() > 0) res = IS_OUTSIDE; + if (dist + box.Diam() < 0) res = IS_INSIDE; + + return res; + } + + + double Cone :: HesseNorm () const + { + // cout << "2/minr = " << 2/minr << ", cxx .. = " << cxx << ", " << cyy << ", " << czz << endl; + return 2 / minr; + } + + + double Cone :: LocH (const Point<3> & p, double /* x */, + double /* c */, double hmax) const + { + //double bloch = Surface::LocH (p, x, c, hmax); + Vec<3> g; + CalcGradient (p, g); + + double lam = Abs(g); + double meancurv = + -( 2 * g(0)*g(1)*cxy - 2 * czz * (g(0)*g(0)+g(1)*g(1)) + +2 * g(1)*g(2)*cyz - 2 * cxx * (g(1)*g(1)+g(2)*g(2)) + +2 * g(0)*g(2)*cxz - 2 * cyy * (g(0)*g(0)+g(2)*g(2))) / (3*lam*lam*lam); + + // cout << "type = " << typeid(*this).name() << ", baseh = " << bloch << ", meancurv = " << meancurv << endl; + // return bloch; + + meancurv = fabs (meancurv); + if (meancurv < 1e-20) meancurv = 1e-20; + + // cout << "c = " << c << ", safety = " << mparam.curvaturesafety << endl; + double hcurv = 1.0/(4*meancurv*mparam.curvaturesafety); + + return min2 (hmax, hcurv); + } + + + Point<3> Cone :: GetSurfacePoint () const + { + Vec<3> vr = vab.GetNormal (); + + vr *= (ra / vr.Length()); + return a + vr; + } + + + + + + void Cone :: GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int i, j; + double lg, bg; + int n = int(facets) + 1; + + Vec<3> lvab = b - a; + Vec<3> n1 = lvab.GetNormal(); + Vec<3> n2 = Cross (lvab, n1); + + n1.Normalize(); + n2.Normalize(); + + + for (j = 0; j <= n; j++) + for (i = 0; i <= n; i++) + { + lg = 2 * M_PI * double (i) / n; + bg = double(j) / n; + + Point<3> p = a + (bg * lvab) + + (( (ra+(rb-ra)*bg) * cos(lg)) * n1) + + (( (ra+(rb-ra)*bg) * sin(lg)) * n2); + + tas.AddPoint (p); + } + + for (j = 0; j < n; j++) + for (i = 0; i < n; i++) + { + int pi = i + (n+1) * j; + tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2)); + tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1)); + } + } + + + + + + + + + + /// Torus + /// Lorenzo Codecasa (codecasa@elet.polimi.it) + /// April 27th, 2005 + /// + Torus :: Torus (const Point<3> & ac, const Vec<3> & an, double aR, double ar) + { + c = ac; + n = an; + n.Normalize(); + R = aR; + r = ar; + } + + void Torus :: GetPrimitiveData (const char *& classname, Array & coeffs) const + { + classname = "torus"; + coeffs.SetSize (8); + coeffs.Elem(1) = c(0); + coeffs.Elem(2) = c(1); + coeffs.Elem(3) = c(2); + coeffs.Elem(4) = n(0); + coeffs.Elem(5) = n(1); + coeffs.Elem(6) = n(2); + coeffs.Elem(7) = R; + coeffs.Elem(8) = r; + } + + void Torus :: SetPrimitiveData (Array & coeffs) + { + c(0) = coeffs.Elem(1); + c(1) = coeffs.Elem(2); + c(2) = coeffs.Elem(3); + n(0) = coeffs.Elem(4); + n(1) = coeffs.Elem(5); + n(2) = coeffs.Elem(6); + R = coeffs.Elem(7); + r = coeffs.Elem(8); + } + + Primitive * Torus :: CreateDefault () + { + return new Torus (Point<3> (0,0,0), Vec<3> (0,0,1), 2, 1); + } + + Primitive * Torus :: Copy () const + { + return new Torus (c, n, R, r); + } + + void Torus :: Transform (Transformation<3> & trans) + { + Point<3> hc; + trans.Transform (c, hc); + c = hc; + + Vec<3> hn; + trans.Transform (n, hn); + n = hn; + } + + int Torus :: IsIdentic (const Surface & s2, int & inv, double eps) const + { + const Torus * torus2 = dynamic_cast (&s2); + + if (!torus2) return 0; + + if (fabs (torus2->R - R) > eps) return 0; + + if (fabs (torus2->r - r) > eps) return 0; + + Vec<3> v2 = torus2->n - n; + if ( v2 * v2 > eps ) return 0; + + v2 = torus2->c - c; + if ( v2 * v2 > eps ) return 0; + + inv = 0; + return 1; + } + + double Torus :: CalcFunctionValue (const Point<3> & point) const + { + /* + // original version + Vec<3> v1 = point - c; + double a1 = Abs2 (v1); // v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a2 = n * v1; // n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2); + double a3 = a1 + R * R - r * r; + double a4 = Abs2 (n); // n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + + return ( a3 * a3 -4 * R * R * ( a1 - a2 * a2 / a4 ) ) / ( R * R * R ); + */ + + + // JS, April 2011 + Vec<3> v1 = point-c; + double abs2 = Abs2(v1); + double tau = v1 * n; + double rho = sqrt (abs2 - tau*tau); + return sqr (R - rho) + tau*tau - r*r; + + // double val2 = sqr (tau*tau + sqr (R - rho) -r*r) / (R*R*R); + } + + void Torus :: CalcGradient (const Point<3> & point, Vec<3> & grad) const + { + /* + Vec<3> v1 = point - c; + double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a2 = n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2); + double a3 = a1 - R * R - r * r; + double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + grad(0) = ( 4 * a3 * v1(0) + 8 * R * R * a2 / a4 * n(0) ) / ( R * R * R ); + grad(1) = ( 4 * a3 * v1(1) + 8 * R * R * a2 / a4 * n(1) ) / ( R * R * R ); + grad(2) = ( 4 * a3 * v1(2) + 8 * R * R * a2 / a4 * n(2) ) / ( R * R * R ); + */ + + Vec<3> v1 = point-c; + double abs2 = Abs2(v1); + double tau = v1 * n; + double rho = sqrt (abs2 - tau*tau); + double func = sqr (R - rho) + tau*tau - r*r; + + Vec<3> gradabs2 = 2 * v1; + Vec<3> gradtau = n; + Vec<3> gradrho = 0.5 / rho * (gradabs2 - 2 * tau * gradtau); + grad = -2 * (R - rho) * gradrho + 2 * tau * gradtau; + } + + void Torus :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const + { + Surface::CalcHesse (point, hesse); + return; + + Vec<3> v1 = point - c; + double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a3 = a1 - R * R - r * r; + double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + hesse(0,0) = ( 4 * a3 + 8 * (v1(0) * v1(0) + (R * n(0)) * (R * n(0)) / a4 ) ) / ( R * R * R ); + hesse(1,1) = ( 4 * a3 + 8 * (v1(1) * v1(1) + (R * n(1)) * (R * n(1)) / a4 ) ) / ( R * R * R ); + hesse(2,2) = ( 4 * a3 + 8 * (v1(2) * v1(2) + (R * n(2)) * (R * n(2)) / a4 ) ) / ( R * R * R ); + hesse(0,1) = hesse(1,0) = 8 * (v1(0) * v1(1) + (R * n(0)) * (R * n(1)) / a4 ) / ( R * R * R ); + hesse(1,2) = hesse(2,1) = 8 * (v1(1) * v1(2) + (R * n(1)) * (R * n(2)) / a4) / ( R * R * R ); + hesse(0,2) = hesse(2,0) = 8 * (v1(0) * v1(2) + (R * n(0)) * (R * n(2)) / a4) / ( R * R * R ); + } + + double Torus :: HesseNorm () const + { + return 4/(r*r); + // return ( 2 / r + 2 / ( R - r ) ); + } + + Point<3> Torus :: GetSurfacePoint () const + { + Vec<3> vn = n.GetNormal(); + return c + ( R + r ) * vn.Normalize(); + } + + /// void Torus :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2) + /// { + /// } + + /// void Torus :: ToPlane (const Point<3> & p, + /// Point<2> & pplane, + /// double h, int & zone) const + /// { + /// } + + /// void Torus :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const + /// { + /// } + + /// void Torus :: Project (Point<3> & p) const + /// { + /// } + + INSOLID_TYPE Torus :: BoxInSolid (const BoxSphere<3> & box) const + { + Vec<3> v1 = box.Center() - c; + double a1 = Abs2(v1); // v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2); + double a2 = n * v1; // n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2); + double a4 = Abs2(n); // n(0) * n(0) + n(1) * n(1) + n(2) * n(2); + + double dist = sqrt( a1 + R * R - 2 * R * sqrt( a1 - a2 * a2 / a4) ); + + if (dist - box.Diam()/2 > r) return IS_OUTSIDE; + if (dist + box.Diam()/2 < r) return IS_INSIDE; + return DOES_INTERSECT; + } + + void Torus :: GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & /* boundingbox */, double facets) const + { + int N = int(facets) + 1; + + Vec<3> lvab = n ; + lvab.Normalize(); + + Vec<3> n1 = lvab.GetNormal(); + n1.Normalize(); + + Vec<3> n2 = Cross(lvab, n1); + n2.Normalize(); + + for (int j = 0; j <= N; j++) + for (int i = 0; i <= N; i++) + { + double lg = 2 * M_PI * double (i) / N; + double bg = 2 * M_PI * double(j) / N; + + Point<3> p = c + ( R + r * cos(lg) ) * ( cos(bg) * n1 + sin(bg) * n2 ) + r * sin(lg) * n; + tas.AddPoint (p); + } + + for (int j = 0; j < N; j++) + for (int i = 0; i < N; i++) + { + int pi = i + (N+1) * j; + tas.AddTriangle (TATriangle (0, pi, pi+1, pi+N+2)); + tas.AddTriangle (TATriangle (0, pi, pi+N+2, pi+N+1)); + } + } + + void Torus :: Read (istream & ist) + { + ist >> c(0) >> c(1) >> c(2) >> n(0) >> n(1) >> n(2) >> R >> r; + } + + void Torus :: Print (ostream & ost) const + { + ost << c(0) << " " << c(1) << " " << c(2) << " " + << n(0) << " " << n(1) << " " << n(2) << " " + << R << " " << r << endl; + } + + + +} diff --git a/libsrc/csg/algprim.hpp b/libsrc/csg/algprim.hpp new file mode 100644 index 00000000..82cd58e7 --- /dev/null +++ b/libsrc/csg/algprim.hpp @@ -0,0 +1,446 @@ +#ifndef FILE_ALGPRIM +#define FILE_ALGPRIM + + +/**************************************************************************/ +/* File: algprim.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 1. Dez. 95 */ +/**************************************************************************/ + +namespace netgen +{ + + /* + + Quadric Surfaces (Plane, Sphere, Cylinder) + + */ + + + /** + A quadric surface. + surface defined by + cxx x^2 + cyy y^2 + czz z^2 + cxy x y + cxz x z + cyz y z + + cx x + cy y + cz z + c1 = 0. + **/ + class QuadraticSurface : public OneSurfacePrimitive + { + protected: + double cxx, cyy, czz, cxy, cxz, cyz, cx, cy, cz, c1; + + public: + virtual double CalcFunctionValue (const Point<3> & point) const; + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + /* + virtual int RootInBox (const Box<3> & box) + const { return 0; } + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) + const { return DOES_INTERSECT; } + */ + virtual double HesseNorm () const { return cxx + cyy + czz; } + + virtual Point<3> GetSurfacePoint () const; + + + virtual void Print (ostream & ist) const; + virtual void Read (istream & ist); + void PrintCoeff (ostream & ost) const; + }; + + + /// A Plane (i.e., the plane and everything behind it). + class Plane : public QuadraticSurface + { + /// a point in the plane + Point<3> p; + /// outward normal vector + Vec<3> n; + + double eps_base; + + public: + /// + Plane (const Point<3> & ap, Vec<3> an); + + virtual void GetPrimitiveData (const char *& classname, + Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + static Primitive * CreateDefault (); + + virtual Primitive * Copy () const; + virtual void Transform (Transformation<3> & trans); + + + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + + /// + virtual void DefineTangentialPlane (const Point<3> & ap1, + const Point<3> & ap2); + /// + virtual void ToPlane (const Point<3> & p3d, + Point<2> & pplane, double h, + int & zone) const; + /// + virtual void FromPlane (const Point<2> & pplane, + Point<3> & p3d, + double h) const; + /// + virtual void Project (Point<3> & p) const; + + /// + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + + /// + inline virtual double CalcFunctionValue (const Point<3> & p3d) const + {return cx * p3d(0) + cy * p3d(1) + cz * p3d(2) + c1;} + /// + virtual void CalcGradient (const Point<3> & point, + Vec<3> & grad) const; + /// + virtual void CalcHesse (const Point<3> & point, + Mat<3> & hesse) const; + /// + virtual double HesseNorm () const; + /// + virtual Point<3> GetSurfacePoint () const; + /// + virtual void GetTriangleApproximation + (TriangleApproximation & tas, + const Box<3> & boundingbox, double facets) const; + protected: + void CalcData(); + }; + + // typedef Plane Plane; + + + /// + class Sphere : public QuadraticSurface + { + /// + Point<3> c; + /// + double r, invr; + public: + /// + Sphere (const Point<3> & ac, double ar); + + virtual void GetPrimitiveData (const char *& classname, + Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + static Primitive * CreateDefault (); + + virtual Primitive * Copy () const; + virtual void Transform (Transformation<3> & trans); + + virtual double CalcFunctionValue (const Point<3> & point) const; + + + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + + /// + virtual void DefineTangentialPlane (const Point<3> & ap1, + const Point<3> & ap2); + /// + virtual void ToPlane (const Point<3> & p3d, + Point<2> & pplane, double h, + int & zone) const; + /// + virtual void FromPlane (const Point<2> & pplane, + Point<3> & p, double h) const; + /// + virtual void Project (Point<3> & p) const; + + /// + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + /// + virtual double HesseNorm () const; + /// + virtual Point<3> GetSurfacePoint () const; + /// + const Point<3> & Center () const { return c; } + /// + double Radius () const { return r; } + + /// + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & bbox, + double facets) const; + }; + + + /// + class Cylinder : public QuadraticSurface + { + /// + Point<3> a, b; + /// + double r; + /// + Vec<3> vab; + + public: + Cylinder (const Point<3> & aa, const Point<3> & ab, double ar); + Cylinder (Array & coeffs); + + virtual void GetPrimitiveData (const char *& classname, Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + static Primitive * CreateDefault (); + + virtual Primitive * Copy () const; + virtual void Transform (Transformation<3> & trans); + + /// + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + /// + virtual void DefineTangentialPlane (const Point<3> & ap1, + const Point<3> & ap2); + /// + virtual void ToPlane (const Point<3> & p, + Point<2> & pplane, + double h, + int & zone) const; + /// + virtual void FromPlane (const Point<2> & pplane, + Point<3> & p, + double h) const; + /// + virtual void Project (Point<3> & p) const; + + /// + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + /// + virtual double HesseNorm () const; + /// + virtual Point<3> GetSurfacePoint () const; + /// + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & bbox, + double facets) const; + }; + + + + + + /// + class EllipticCylinder : public QuadraticSurface + { + private: + /// + Point<3> a; + /// + Vec<3> vl, vs; + /// + Vec<3> vab, t0vec, t1vec; + /// + double vabl, t0, t1; + public: + /// + EllipticCylinder (const Point<3> & aa, + const Vec<3> & avl, const Vec<3> & avs); + EllipticCylinder (Array & coeffs); + + + // static Primitive * CreateDefault (); + virtual void GetPrimitiveData (const char *& classname, Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + + /// + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + /// + virtual double HesseNorm () const; + /// + virtual Point<3> GetSurfacePoint () const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & bbox, + double facets) const; + + + virtual double MaxCurvature () const; + + virtual double MaxCurvatureLoc (const Point<3> & /* c */ , + double /* rad */) const; + + + private: + void CalcData(); + }; + + + + + + + /// + class Ellipsoid : public QuadraticSurface + { + private: + /// + Point<3> a; + /// + Vec<3> v1, v2, v3; + /// + double rmin; + public: + /// + Ellipsoid (const Point<3> & aa, + const Vec<3> & av1, + const Vec<3> & av2, + const Vec<3> & av3); + /// + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + /// + virtual double HesseNorm () const; + /// + virtual double MaxCurvature () const; + /// + virtual Point<3> GetSurfacePoint () const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & bbox, + double facets) const; + + private: + void CalcData(); + }; + + + + + + + + + /// + class Cone : public QuadraticSurface + { + /// + Point<3> a, b; + /// + double ra, rb, minr; + /// + Vec<3> vab, t0vec, t1vec; + /// + double vabl, t0, t1; + double cosphi; + public: + /// + Cone (const Point<3> & aa, const Point<3> & ab, double ara, double arb); + /// + static Primitive * CreateDefault (); + virtual void GetPrimitiveData (const char *& classname, Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + + /// + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + /// + virtual double HesseNorm () const; + + virtual double LocH (const Point<3> & p, double x, + double c, double hmax) const; + + /// + virtual Point<3> GetSurfacePoint () const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & bbox, + double facets) const; + + private: + void CalcData(); + }; + + + + + + + + + /** Torus + /// Lorenzo Codecasa (codecasa@elet.polimi.it) + /// April 27th, 2005 + */ + class Torus : public OneSurfacePrimitive + { + /// center of the torus + Point<3> c; + /// vector normal to the symmetry plane of the torus + Vec<3> n; + /// Large radius of the torus + double R; + /// Small radius of the torus + double r; + + public: + /// OK + Torus (const Point<3> & ac, const Vec<3> & an, double aR, double ar); + /// OK + const Point<3> & Center () const { return c; } + /// OK + const Vec<3> & NormalToPlane () const { return n; } + /// OK + double LargeRadius () const { return R; } + /// OK + double SmallRadius () const { return r; } + /// OK + virtual double CalcFunctionValue (const Point<3> & point) const; + /// OK + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + /// OK + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + /// OK + virtual double HesseNorm () const; + /// OK + virtual Point<3> GetSurfacePoint () const; + /// OK + virtual void GetPrimitiveData (const char *& classname, + Array & coeffs) const; + /// OK + virtual void SetPrimitiveData (Array & coeffs); + /// OK + static Primitive * CreateDefault (); + /// OK + virtual Primitive * Copy () const; + /// OK + virtual void Transform (Transformation<3> & trans); + /// OK + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + /// OK + /// virtual void DefineTangentialPlane (const Point<3> & ap1, + // const Point<3> & ap2); + /// OK + /// virtual void ToPlane (const Point<3> & p3d, + /// Point<2> & pplane, + /// double h, int & zone) const; + /// OK + /// virtual void FromPlane (const Point<2> & pplane, + // Point<3> & p, double h) const; + /// OK + /// virtual void Project (Point<3> & p) const; + /// OK + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + /// OK + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & bbox, + double facets) const; + /// OK + virtual void Print (ostream & ist) const; + /// OK + virtual void Read (istream & ist); + }; + + /// ...end + + +} + + + + + +#endif diff --git a/libsrc/csg/brick.cpp b/libsrc/csg/brick.cpp new file mode 100644 index 00000000..54c23b17 --- /dev/null +++ b/libsrc/csg/brick.cpp @@ -0,0 +1,526 @@ +#include + +#include +#include + +namespace netgen +{ + +Parallelogram3d :: Parallelogram3d (Point<3> ap1, Point<3> ap2, Point<3> ap3) +{ + p1 = ap1; + p2 = ap2; + p3 = ap3; + + CalcData(); +} + +Parallelogram3d ::~Parallelogram3d () +{ + ; +} + +void Parallelogram3d :: SetPoints (Point<3> ap1, + Point<3> ap2, + Point<3> ap3) +{ + p1 = ap1; + p2 = ap2; + p3 = ap3; + + CalcData(); +} + +void Parallelogram3d :: CalcData() +{ + v12 = p2 - p1; + v13 = p3 - p1; + p4 = p2 + v13; + + n = Cross (v12, v13); + n.Normalize(); +} + +int Parallelogram3d :: +IsIdentic (const Surface & s2, int & inv, double eps) const +{ + int id = + (fabs (s2.CalcFunctionValue (p1)) <= eps) && + (fabs (s2.CalcFunctionValue (p2)) <= eps) && + (fabs (s2.CalcFunctionValue (p3)) <= eps); + + if (id) + { + Vec<3> n2; + n2 = s2.GetNormalVector(p1); + inv = (n * n2) < 0; + } + return id; +} + + +double Parallelogram3d :: CalcFunctionValue (const Point<3> & point) const +{ + return n * (point - p1); +} + +void Parallelogram3d :: CalcGradient (const Point<3> & /* point */, + Vec<3> & grad) const +{ + grad = n; +} + +void Parallelogram3d :: CalcHesse (const Point<3> & /* point */, Mat<3> & hesse) const +{ + hesse = 0; +} + +double Parallelogram3d :: HesseNorm () const +{ + return 0; +} + +Point<3> Parallelogram3d :: GetSurfacePoint () const +{ + return p1; +} + +void Parallelogram3d :: Print (ostream & str) const +{ + str << "Parallelogram3d " << p1 << " - " << p2 << " - " << p3 << endl; +} + + +void Parallelogram3d :: +GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & /* bbox */, + double /* facets */) const +{ + tas.AddPoint (p1); + tas.AddPoint (p2); + tas.AddPoint (p3); + tas.AddPoint (p4); + tas.AddTriangle (TATriangle (0, 0, 1, 2)); + tas.AddTriangle (TATriangle (0, 2, 1, 3)); +} + + + + + + + + + + +Brick :: Brick (Point<3> ap1, Point<3> ap2, + Point<3> ap3, Point<3> ap4) +{ + faces.SetSize (6); + surfaceids.SetSize (6); + surfaceactive.SetSize(6); + + p1 = ap1; p2 = ap2; + p3 = ap3; p4 = ap4; + + for (int i = 0; i < 6; i++) + { + faces[i] = new Plane (Point<3>(0,0,0), Vec<3> (0,0,1)); + surfaceactive[i] = 1; + } + + CalcData(); +} + +Brick :: ~Brick () +{ + for (int i = 0; i < 6; i++) + delete faces[i]; +} + +Primitive * Brick :: CreateDefault () +{ + return new Brick (Point<3> (0,0,0), + Point<3> (1,0,0), + Point<3> (0,1,0), + Point<3> (0,0,1)); +} + + + +Primitive * Brick :: Copy () const +{ + return new Brick (p1, p2, p3, p4); +} + +void Brick :: Transform (Transformation<3> & trans) +{ + trans.Transform (p1); + trans.Transform (p2); + trans.Transform (p3); + trans.Transform (p4); + + CalcData(); +} + + + + + + + + + +INSOLID_TYPE Brick :: BoxInSolid (const BoxSphere<3> & box) const +{ + /* + int i; + double maxval; + for (i = 1; i <= 6; i++) + { + double val = faces.Get(i)->CalcFunctionValue (box.Center()); + if (i == 1 || val > maxval) + maxval = val; + } + + if (maxval > box.Diam()) return IS_OUTSIDE; + if (maxval < -box.Diam()) return IS_INSIDE; + return DOES_INTERSECT; + */ + + bool inside = 1; + bool outside = 0; + + Point<3> p[8]; + for (int j = 0; j < 8; j++) + p[j] = box.GetPointNr(j); + + for (int i = 0; i < 6; i++) + { + bool outsidei = 1; + for (int j = 0; j < 8; j++) + { + // Point<3> p = box.GetPointNr (j); + double val = faces[i]->Plane::CalcFunctionValue (p[j]); + + if (val > 0) inside = 0; + if (val < 0) outsidei = 0; + } + if (outsidei) outside = 1; + } + + if (outside) return IS_OUTSIDE; + if (inside) return IS_INSIDE; + return DOES_INTERSECT; +} + +INSOLID_TYPE Brick :: PointInSolid (const Point<3> & p, + double eps) const +{ + double maxval = faces[0] -> Plane::CalcFunctionValue (p); + for (int i = 1; i < 6; i++) + { + double val = faces[i] -> Plane::CalcFunctionValue (p); + if (val > maxval) maxval = val; + } + + if (maxval > eps) return IS_OUTSIDE; + if (maxval < -eps) return IS_INSIDE; + return DOES_INTERSECT; +} + + +INSOLID_TYPE Brick :: VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const +{ + INSOLID_TYPE result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid(p, v, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; + + /* + INSOLID_TYPE is = IS_INSIDE; + Vec<3> grad; + double scal; + + for (int i = 0; i < faces.Size(); i++) + { + if (faces[i] -> PointOnSurface (p, eps)) + { + GetSurface(i).CalcGradient (p, grad); + scal = v * grad; + + if (scal >= eps) + is = IS_OUTSIDE; + if (scal >= -eps && is == IS_INSIDE) + is = DOES_INTERSECT; + } + } + return is; + */ + + /* + Point<3> p2 = p + 1e-2 * v; + return PointInSolid (p2, eps); + */ +} + + + + + +INSOLID_TYPE Brick :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + INSOLID_TYPE result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid2(p, v1, v2, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; +} + +INSOLID_TYPE Brick :: VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + INSOLID_TYPE result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid3(p, v1, v2, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; +} + +INSOLID_TYPE Brick :: VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const +{ + INSOLID_TYPE result = IS_INSIDE; + for (int i = 0; i < faces.Size(); i++) + { + INSOLID_TYPE hres = faces[i]->VecInSolid4(p, v, v2, m, eps); + if (hres == IS_OUTSIDE || result == IS_OUTSIDE) result = IS_OUTSIDE; + else if (hres == DOES_INTERSECT || result == DOES_INTERSECT) result = DOES_INTERSECT; + else result = IS_INSIDE; + } + return result; +} + + + + + + + + + + + + + + + + + + + +void Brick :: +GetPrimitiveData (const char *& classname, Array & coeffs) const +{ + classname = "brick"; + coeffs.SetSize(12); + coeffs.Elem(1) = p1(0); + coeffs.Elem(2) = p1(1); + coeffs.Elem(3) = p1(2); + + coeffs.Elem(4) = p2(0); + coeffs.Elem(5) = p2(1); + coeffs.Elem(6) = p2(2); + + coeffs.Elem(7) = p3(0); + coeffs.Elem(8) = p3(1); + coeffs.Elem(9) = p3(2); + + coeffs.Elem(10) = p4(0); + coeffs.Elem(11) = p4(1); + coeffs.Elem(12) = p4(2); +} + +void Brick :: SetPrimitiveData (Array & coeffs) +{ + p1(0) = coeffs.Elem(1); + p1(1) = coeffs.Elem(2); + p1(2) = coeffs.Elem(3); + + p2(0) = coeffs.Elem(4); + p2(1) = coeffs.Elem(5); + p2(2) = coeffs.Elem(6); + + p3(0) = coeffs.Elem(7); + p3(1) = coeffs.Elem(8); + p3(2) = coeffs.Elem(9); + + p4(0) = coeffs.Elem(10); + p4(1) = coeffs.Elem(11); + p4(2) = coeffs.Elem(12); + + CalcData(); +} + + + +void Brick :: CalcData() +{ + v12 = p2 - p1; + v13 = p3 - p1; + v14 = p4 - p1; + + Point<3> pi[8]; + int i1, i2, i3; + int i, j; + + i = 0; + for (i3 = 0; i3 <= 1; i3++) + for (i2 = 0; i2 <= 1; i2++) + for (i1 = 0; i1 <= 1; i1++) + { + pi[i] = p1 + i1 * v12 + i2 * v13 + i3 * v14; + i++; + } + + static int lface[6][4] = + { { 1, 3, 2, 4 }, + { 5, 6, 7, 8 }, + { 1, 2, 5, 6 }, + { 3, 7, 4, 8 }, + { 1, 5, 3, 7 }, + { 2, 4, 6, 8 } }; + + Array data(6); + for (i = 0; i < 6; i++) + { + const Point<3> lp1 = pi[lface[i][0]-1]; + const Point<3> lp2 = pi[lface[i][1]-1]; + const Point<3> lp3 = pi[lface[i][2]-1]; + + Vec<3> n = Cross ((lp2-lp1), (lp3-lp1)); + n.Normalize(); + + for (j = 0; j < 3; j++) + { + data[j] = lp1(j); + data[j+3] = n(j); + } + faces[i] -> SetPrimitiveData (data); + /* + { + faces.Elem(i+1) -> SetPoints + (pi[lface[i][0]-1], + pi[lface[i][1]-1], + pi[lface[i][2]-1]); + } + */ + } +} + + +void Brick :: Reduce (const BoxSphere<3> & box) +{ + double val; + // Point<3> p; + Point<3> p[8]; + for(int j=0;j<8;j++) + p[j]=box.GetPointNr(j); + + for (int i = 0; i < 6; i++) + { + bool hasout = 0; + bool hasin = 0; + for (int j = 0; j < 8; j++) + { + // p = box.GetPointNr (j); + val = faces[i]->Plane::CalcFunctionValue (p[j]); + if (val > 0) hasout = 1; + else if (val < 0) hasin = 1; + if (hasout && hasin) break; + } + surfaceactive[i] = hasout && hasin; + } +} + +void Brick :: UnReduce () +{ + for (int i = 0; i < 6; i++) + surfaceactive[i] = 1; +} + + + +OrthoBrick :: OrthoBrick (const Point<3> & ap1, const Point<3> & ap2) + : Brick (ap1, + Point<3> (ap2(0), ap1(1), ap1(2)), + Point<3> (ap1(0), ap2(1), ap1(2)), + Point<3> (ap1(0), ap1(1), ap2(2))) +{ + pmin = ap1; + pmax = ap2; +} + +INSOLID_TYPE OrthoBrick :: BoxInSolid (const BoxSphere<3> & box) const +{ + if (pmin(0) > box.PMax()(0) || + pmin(1) > box.PMax()(1) || + pmin(2) > box.PMax()(2) || + pmax(0) < box.PMin()(0) || + pmax(1) < box.PMin()(1) || + pmax(2) < box.PMin()(2)) + return IS_OUTSIDE; + + if (pmin(0) < box.PMin()(0) && + pmin(1) < box.PMin()(1) && + pmin(2) < box.PMin()(2) && + pmax(0) > box.PMax()(0) && + pmax(1) > box.PMax()(1) && + pmax(2) > box.PMax()(2)) + return IS_INSIDE; + + return DOES_INTERSECT; +} + + +void OrthoBrick :: Reduce (const BoxSphere<3> & box) +{ + surfaceactive.Elem(1) = + (box.PMin()(2) < pmin(2)) && (pmin(2) < box.PMax()(2)); + surfaceactive.Elem(2) = + (box.PMin()(2) < pmax(2)) && (pmax(2) < box.PMax()(2)); + + surfaceactive.Elem(3) = + (box.PMin()(1) < pmin(1)) && (pmin(1) < box.PMax()(1)); + surfaceactive.Elem(4) = + (box.PMin()(1) < pmax(1)) && (pmax(1) < box.PMax()(1)); + + surfaceactive.Elem(5) = + (box.PMin()(0) < pmin(0)) && (pmin(0) < box.PMax()(0)); + surfaceactive.Elem(6) = + (box.PMin()(0) < pmax(0)) && (pmax(0) < box.PMax()(0)); +} +} diff --git a/libsrc/csg/brick.hpp b/libsrc/csg/brick.hpp new file mode 100644 index 00000000..25b003e0 --- /dev/null +++ b/libsrc/csg/brick.hpp @@ -0,0 +1,126 @@ +#ifndef FILE_BRICK +#define FILE_BRICK + + +/**************************************************************************/ +/* File: brick.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 11. Mar. 98 */ +/**************************************************************************/ + +namespace netgen +{ + + + /* + + brick geometry, has several surfaces + + */ + + + + class Parallelogram3d : public Surface + { + Point<3> p1, p2, p3, p4; + Vec<3> v12, v13; + Vec<3> n; + + public: + Parallelogram3d (Point<3> ap1, Point<3> ap2, Point<3> ap3); + virtual ~Parallelogram3d (); + + void SetPoints (Point<3> ap1, Point<3> ap2, Point<3> ap3); + + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + + virtual double CalcFunctionValue (const Point<3> & point) const; + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + virtual double HesseNorm () const; + + virtual Point<3> GetSurfacePoint () const; + virtual void Print (ostream & str) const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const; + + protected: + void CalcData(); + }; + + + class Brick : public Primitive + { + Point<3> p1, p2, p3, p4; + Vec<3> v12, v13, v14; + // Array faces; + Array faces; + + public: + Brick (Point<3> ap1, Point<3> ap2, Point<3> ap3, Point<3> ap4); + virtual ~Brick (); + static Primitive * CreateDefault (); + + virtual Primitive * Copy () const; + virtual void Transform (Transformation<3> & trans); + + + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + + virtual INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const; + virtual INSOLID_TYPE VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const; + virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const; + + + virtual int GetNSurfaces() const + { return 6; } + virtual Surface & GetSurface (int i) + { return *faces[i]; } + virtual const Surface & GetSurface (int i) const + { return *faces[i]; } + + + virtual void GetPrimitiveData (const char *& classname, Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + + virtual void Reduce (const BoxSphere<3> & box); + virtual void UnReduce (); + + protected: + void CalcData(); + }; + + + class OrthoBrick : public Brick + { + protected: + Point<3> pmin, pmax; + public: + OrthoBrick (const Point<3> & ap1, const Point<3> & ap2); + + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + virtual void Reduce (const BoxSphere<3> & box); + }; + +} + +#endif diff --git a/libsrc/csg/bspline2d.cpp b/libsrc/csg/bspline2d.cpp new file mode 100644 index 00000000..93b5e896 --- /dev/null +++ b/libsrc/csg/bspline2d.cpp @@ -0,0 +1,242 @@ +#include + +#include + +namespace netgen +{ + +BSplineCurve2d :: BSplineCurve2d () +{ + redlevel = 0; +} + + +void BSplineCurve2d :: AddPoint (const Point<2> & apoint) +{ + points.Append (apoint); + intervallused.Append (0); +} + +bool BSplineCurve2d :: Inside (const Point<2> & p, double & dist) const +{ + Point<2> hp = p; + double t = ProjectParam (p); + hp = Eval(t); + Vec<2> v = EvalPrime (t); + + Vec<2> n (v(0), -v(1)); + + cout << "p = " << p << ", hp = " << hp << endl; + dist = Dist (p, hp); + double scal = (hp-p) * n; + cout << "scal = " << scal << endl; + + return scal >= 0; +} + +double BSplineCurve2d :: ProjectParam (const Point<2> & p) const +{ + double t, dt, mindist, mint = 0.0; + int n1; + + mindist = 1e10; + dt = 0.2; + for (n1 = 1; n1 <= points.Size(); n1++) + if (intervallused.Get(n1) == 0) + for (t = n1; t <= n1+1; t += dt) + if (Dist (Eval(t), p) < mindist) + { + mint = t; + mindist = Dist (Eval(t), p); + } + + if (mindist > 1e9) + { + for (t = 0; t <= points.Size(); t += dt) + if (Dist (Eval(t), p) < mindist) + { + mint = t; + mindist = Dist (Eval(t), p); + } + } + + while (Dist (Eval (mint-dt), p) < mindist) + { + mindist = Dist (Eval (mint-dt), p); + mint -= dt; + } + while (Dist (Eval (mint+dt), p) < mindist) + { + mindist = Dist (Eval (mint+dt), p); + mint += dt; + } + + + return NumericalProjectParam (p, mint-dt, mint+dt); +} + + +// t \in (n1, n2) + +Point<2> BSplineCurve2d :: Eval (double t) const +{ + int n, n1, n2, n3, n4; + double loct, b1, b2, b3, b4; + Point<2> hp; + + static int cnt = 0; + cnt++; + if (cnt % 100000 == 0) (*mycout) << "cnt = " << cnt << endl; + + n = int(t); + loct = t - n; + + b1 = 0.25 * (1 - loct) * (1 - loct); + b4 = 0.25 * loct * loct; + b2 = 0.5 - b4; + b3 = 0.5 - b1; + + n1 = (n + 10 * points.Size() -1) % points.Size() + 1; + n2 = n1+1; + if (n2 > points.Size()) n2 = 1; + n3 = n2+1; + if (n3 > points.Size()) n3 = 1; + n4 = n3+1; + if (n4 > points.Size()) n4 = 1; + + // (*mycout) << "t = " << t << " n = " << n << " loct = " << loct + // << " n1 = " << n1 << endl; + + + hp(0) = b1 * points.Get(n1)(0) + b2 * points.Get(n2)(0) + + b3 * points.Get(n3)(0) + b4 * points.Get(n4)(0); + hp(1) = b1 * points.Get(n1)(1) + b2 * points.Get(n2)(1) + + b3 * points.Get(n3)(1) + b4 * points.Get(n4)(1); + return hp; +} + +Vec<2> BSplineCurve2d :: EvalPrime (double t) const +{ + int n, n1, n2, n3, n4; + double loct, db1, db2, db3, db4; + Vec<2> hv; + + n = int(t); + loct = t - n; + + db1 = 0.5 * (loct - 1); + db4 = 0.5 * loct; + db2 = -db4; + db3 = -db1; + + n1 = (n + 10 * points.Size() -1) % points.Size() + 1; + n2 = n1+1; + if (n2 > points.Size()) n2 = 1; + n3 = n2+1; + if (n3 > points.Size()) n3 = 1; + n4 = n3+1; + if (n4 > points.Size()) n4 = 1; + + hv(0) = db1 * points.Get(n1)(0) + db2 * points.Get(n2)(0) + + db3 * points.Get(n3)(0) + db4 * points.Get(n4)(0); + hv(1) = db1 * points.Get(n1)(1) + db2 * points.Get(n2)(1) + + db3 * points.Get(n3)(1) + db4 * points.Get(n4)(1); + return hv; +} + +Vec<2> BSplineCurve2d :: EvalPrimePrime (double t) const +{ + int n, n1, n2, n3, n4; + double ddb1, ddb2, ddb3, ddb4; + Vec<2> hv; + + n = int(t); + // double loct = t - n; + + ddb1 = 0.5; + ddb4 = 0.5; + ddb2 = -0.5; + ddb3 = -0.5; + + n1 = (n + 10 * points.Size() -1) % points.Size() + 1; + n2 = n1+1; + if (n2 > points.Size()) n2 = 1; + n3 = n2+1; + if (n3 > points.Size()) n3 = 1; + n4 = n3+1; + if (n4 > points.Size()) n4 = 1; + + hv(0) = ddb1 * points.Get(n1)(0) + ddb2 * points.Get(n2)(0) + + ddb3 * points.Get(n3)(0) + ddb4 * points.Get(n4)(0); + hv(1) = ddb1 * points.Get(n1)(1) + ddb2 * points.Get(n2)(1) + + ddb3 * points.Get(n3)(1) + ddb4 * points.Get(n4)(1); + return hv; +} + + +int BSplineCurve2d :: SectionUsed (double t) const +{ + int n1 = int(t); + n1 = (n1 + 10 * points.Size() - 1) % points.Size() + 1; + return (intervallused.Get(n1) == 0); +} + +void BSplineCurve2d :: Reduce (const Point<2> & p, double rad) +{ + int n1, n; + int j; + double minx, miny, maxx, maxy; + + // (*testout) << "Reduce: " << p << "," << rad << endl; + + redlevel++; + + for (n1 = 1; n1 <= points.Size(); n1++) + { + if (intervallused.Get(n1) != 0) continue; + + minx = maxx = points.Get(n1)(0); + miny = maxy = points.Get(n1)(1); + + n = n1; + for (j = 1; j <= 3; j++) + { + n++; + if (n > points.Size()) n = 1; + if (points.Get(n)(0) < minx) minx = points.Get(n)(0); + if (points.Get(n)(1) < miny) miny = points.Get(n)(1); + if (points.Get(n)(0) > maxx) maxx = points.Get(n)(0); + if (points.Get(n)(1) > maxy) maxy = points.Get(n)(1); + } + + if (minx > p(0) + rad || maxx < p(0) - rad || + miny > p(1) + rad || maxy < p(1) - rad) + { + intervallused.Elem(n1) = redlevel; + // (*testout) << 0; + } + else + { + // (*testout) << 1; + intervallused.Elem(n1) = 0; + } + } + // (*testout) << endl; +} + +void BSplineCurve2d :: UnReduce () +{ + int i; + for (i = 1; i <= intervallused.Size(); i++) + if (intervallused.Get(i) == redlevel) + intervallused.Set (i, 0); + redlevel--; +} + +void BSplineCurve2d :: Print (ostream & ost) const +{ + ost << "SplineCurve: " << points.Size() << " points." << endl; + for (int i = 1; i <= points.Size(); i++) + ost << "P" << i << " = " << points.Get(i) << endl; +} +} diff --git a/libsrc/csg/csg.hpp b/libsrc/csg/csg.hpp new file mode 100644 index 00000000..8ddf8d50 --- /dev/null +++ b/libsrc/csg/csg.hpp @@ -0,0 +1,44 @@ +#ifndef FILE_CSG +#define FILE_CSG + +/* *************************************************************************/ +/* File: geoml.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 21. Jun. 98 */ +/* *************************************************************************/ + +#include +#include +#include + +// #include +#include "../gprim/spline.hpp" +#include "../gprim/splinegeometry.hpp" + + + +#include "surface.hpp" +#include "solid.hpp" +#include "identify.hpp" +#include "singularref.hpp" +#include "csgeom.hpp" +#include "csgparser.hpp" + + +#include "triapprox.hpp" +#include "algprim.hpp" +#include "brick.hpp" +#include "spline3d.hpp" +#include "manifold.hpp" +#include "curve2d.hpp" +#include "explicitcurve2d.hpp" +#include "gencyl.hpp" +#include "polyhedra.hpp" +#include "extrusion.hpp" +#include "revolution.hpp" +#include "specpoin.hpp" +#include "edgeflw.hpp" +#include "meshsurf.hpp" + + +#endif diff --git a/libsrc/csg/csgeom.cpp b/libsrc/csg/csgeom.cpp new file mode 100644 index 00000000..754dbe49 --- /dev/null +++ b/libsrc/csg/csgeom.cpp @@ -0,0 +1,1562 @@ +#include +#include + +#include +#include + + +namespace netgen +{ + + + + int CSGeometry :: changeval = 0; + + + + TopLevelObject :: + TopLevelObject (Solid * asolid, + Surface * asurface) + { + solid = asolid; + surface = asurface; + + SetRGB (0, 0, 1); + SetTransparent (0); + SetVisible (1); + SetLayer (1); + + if (!surface) + maxh = solid->GetMaxH(); + else + maxh = surface->GetMaxH(); + + SetBCProp (-1); + + bcname = "default"; + } + + void TopLevelObject :: GetData (ostream & ost) + { + ost << red << " " << green << " " << blue << " " + << transp << " " << visible << " "; + } + + void TopLevelObject :: SetData (istream & ist) + { + ist >> red >> green >> blue >> transp >> visible; + } + + + + Box<3> CSGeometry::default_boundingbox (Point<3> (-1000, -1000, -1000), + Point<3> ( 1000, 1000, 1000)); + + + CSGeometry :: CSGeometry () + : boundingbox (default_boundingbox), + identicsurfaces (100), ideps(1e-9), filename("") + { + ; + } + + CSGeometry :: CSGeometry (const string & afilename) + : boundingbox (default_boundingbox), + identicsurfaces (100), ideps(1e-9), filename(afilename) + { + changeval++; + } + + CSGeometry :: ~CSGeometry () + { + Clean(); + } + + + void CSGeometry :: Clean () + { + Array< Solid* > to_delete; + + for (int i = 0; i < solids.Size(); i++) + if(!to_delete.Contains(solids[i]->S1())) + to_delete.Append(solids[i]->S1()); + for (int i = 0; i < solids.Size(); i++) + if(!to_delete.Contains(solids[i])) + to_delete.Append(solids[i]); + + for(int i = 0; i < to_delete.Size(); i++) + delete to_delete[i]; + + solids.DeleteAll (); + + for (int i = 0; i < splinecurves2d.Size(); i++) + delete splinecurves2d[i]; + splinecurves2d.DeleteAll(); + + /* + for (int i = 0; i < surfaces.Size(); i++) + delete surfaces[i]; + surfaces.DeleteAll (); + */ + for(int i = 0; i Set2dOptimizer(new MeshOptimize2dSurfaces(*this)); + return *ref; + } + + class WritePrimitivesIt : public SolidIterator + { + ostream & ost; + public: + WritePrimitivesIt (ostream & aost) : ost(aost) { ; } + virtual ~WritePrimitivesIt () { ; } + + virtual void Do (Solid * sol); + }; + + void WritePrimitivesIt :: Do (Solid * sol) + { + Primitive * prim = sol->GetPrimitive(); + if (prim) + { + const char * classname; + Array coeffs; + + prim -> GetPrimitiveData (classname, coeffs); + + if (sol->Name()) + ost << "primitive " + << sol->Name() << " " + << classname << " " << coeffs.Size(); + for (int i = 0; i < coeffs.Size(); i++) + ost << " " << coeffs[i]; + ost << endl; + } + } + + + void CSGeometry :: Save (string filename) const + { + fstream ost (filename.c_str()); + Save (ost); + } + + void CSGeometry :: Save (ostream & ost) const + { + ost << "boundingbox " + << boundingbox.PMin()(0) << " " + << boundingbox.PMin()(1) << " " + << boundingbox.PMin()(2) << " " + << boundingbox.PMax()(0) << " " + << boundingbox.PMax()(1) << " " + << boundingbox.PMax()(2) << endl; + + + WritePrimitivesIt wpi(ost); + IterateAllSolids (wpi, 1); + + for (int i = 0; i < solids.Size(); i++) + { + if (!solids[i]->GetPrimitive()) + { + ost << "solid " << solids.GetName(i) << " "; + solids[i] -> GetSolidData (ost); + ost << endl; + } + } + + for (int i = 0; i < GetNTopLevelObjects(); i++) + { + TopLevelObject * tlo = GetTopLevelObject (i); + ost << "toplevel "; + if (tlo -> GetSurface()) + ost << "surface " << tlo->GetSolid()->Name() << " " + << tlo->GetSurface()->Name() << " "; + else + ost << "solid " << tlo->GetSolid()->Name() << " "; + tlo->GetData(ost); + ost << endl; + } + + for (int i = 0; i < identifications.Size(); i++) + { + ost << "identify "; + identifications[i] -> GetData (ost); + ost << endl; + } + + ost << "end" << endl; + } + + + void CSGeometry :: Load (istream & ist) + { + // CSGeometry * geo = new CSGeometry; + + char key[100], name[100], classname[100], sname[100]; + int ncoeff, i, j; + Array coeff; + + while (ist.good()) + { + ist >> key; + if (strcmp (key, "boundingbox") == 0) + { + Point<3> pmin, pmax; + ist >> pmin(0) >> pmin(1) >> pmin(2); + ist >> pmax(0) >> pmax(1) >> pmax(2); + SetBoundingBox (Box<3> (pmin, pmax)); + } + if (strcmp (key, "primitive") == 0) + { + ist >> name >> classname >> ncoeff; + coeff.SetSize (ncoeff); + for (i = 0; i < ncoeff; i++) + ist >> coeff[i]; + + Primitive * nprim = Primitive::CreatePrimitive (classname); + nprim -> SetPrimitiveData (coeff); + Solid * nsol = new Solid (nprim); + + for (j = 0; j < nprim->GetNSurfaces(); j++) + { + sprintf (sname, "%s,%d", name, j); + AddSurface (sname, &nprim->GetSurface(j)); + nprim -> SetSurfaceId (j, GetNSurf()); + } + SetSolid (name, nsol); + } + else if (strcmp (key, "solid") == 0) + { + ist >> name; + Solid * nsol = Solid::CreateSolid (ist, solids); + + cout << " I have found solid " << name << " = "; + nsol -> GetSolidData (cout); + cout << endl; + + SetSolid (name, nsol); + } + else if (strcmp (key, "toplevel") == 0) + { + char type[20], solname[50], surfname[50]; + const Solid * sol = NULL; + const Surface * surf = NULL; + int nr; + + ist >> type; + if (strcmp (type, "solid") == 0) + { + ist >> solname; + sol = GetSolid (solname); + } + if (strcmp (type, "surface") == 0) + { + ist >> solname >> surfname; + sol = GetSolid (solname); + surf = GetSurface (surfname); + } + nr = SetTopLevelObject ((Solid*)sol, (Surface*)surf); + GetTopLevelObject (nr) -> SetData (ist); + } + else if (strcmp (key, "identify") == 0) + { + char type[10], surfname1[50], surfname2[50]; + const Surface * surf1; + const Surface * surf2; + + + ist >> type >> surfname1 >> surfname2; + surf1 = GetSurface(surfname1); + surf2 = GetSurface(surfname2); + + AddIdentification (new PeriodicIdentification + (GetNIdentifications(), + *this, surf1, surf2)); + } + else if (strcmp (key, "end") == 0) + break; + } + + changeval++; + } + + + + void CSGeometry :: SaveSurfaces (ostream & out) const + { + if(singfaces.Size() > 0 || singedges.Size() > 0 || singpoints.Size() > 0) + { + PrintMessage(3,"Singular faces/edges/points => no csg-information in .vol file"); + return; + } + + + + Array coeffs; + const char * classname; + + out << "csgsurfaces " << GetNSurf() << "\n"; + for(int i=0; i (GetSurface(i)); + const ExtrusionFace * ef = dynamic_cast< const ExtrusionFace * > (GetSurface(i)); + const RevolutionFace * rf = dynamic_cast< const RevolutionFace * > (GetSurface(i)); + const DummySurface * dummyf = dynamic_cast< const DummySurface * > (GetSurface(i)); + + + if(sp) + { + sp->GetPrimitiveData(classname,coeffs); + + out << classname << " "; + } + else if(ef) + { + out << "extrusionface "; + ef->GetRawData(coeffs); + } + else if(rf) + { + out << "revolutionface "; + rf->GetRawData(coeffs); + } + else if(dummyf) + { + out << "dummy "; + coeffs.SetSize(0); + } + else + throw NgException ("Cannot write csg surface. Please, contact developers!"); + + + out << coeffs.Size() << "\n"; + for(int j=0; j coeffs; + string classname; + int nsurfaces,size; + + in >> classname; + + if(classname == "csgsurfaces") + in >> nsurfaces; + else + nsurfaces = atoi(classname.c_str()); + + Point<3> dummypoint(0,0,0); + Vec<3> dummyvec(0,0,0); + double dummydouble(0.1); + + for(int i=0; i> classname; + in >> size; + + coeffs.SetSize(size); + + for(int j=0; j> coeffs[j]; + + if(classname == "plane") + { + Plane * plane = new Plane(dummypoint,dummyvec); + plane->SetPrimitiveData(coeffs); + + AddSurface(plane); + delete_them.Append(plane); + } + + else if(classname == "sphere") + { + Sphere * sphere = new Sphere(dummypoint,dummydouble); + sphere->SetPrimitiveData(coeffs); + + AddSurface(sphere); + delete_them.Append(sphere); + } + + else if(classname == "cylinder") + { + Cylinder * cylinder = new Cylinder(coeffs); + + AddSurface(cylinder); + delete_them.Append(cylinder); + } + + else if(classname == "ellipticcylinder") + { + EllipticCylinder * cylinder = new EllipticCylinder(coeffs); + AddSurface(cylinder); + delete_them.Append(cylinder); + } + + + else if(classname == "torus") + { + Torus * torus = new Torus(dummypoint,dummyvec,dummydouble, dummydouble); + torus->SetPrimitiveData(coeffs); + AddSurface(torus); + delete_them.Append(torus); + } + + + else if(classname == "cone") + { + Cone * cone = new Cone(dummypoint,dummypoint,dummydouble,dummydouble); + cone->SetPrimitiveData(coeffs); + + AddSurface(cone); + delete_them.Append(cone); + } + + else if(classname == "extrusionface") + { + ExtrusionFace * ef = + new ExtrusionFace(coeffs); + + AddSurface(ef); + delete_them.Append(ef); + } + + else if(classname == "revolutionface") + { + RevolutionFace * rf = + new RevolutionFace(coeffs); + + AddSurface(rf); + delete_them.Append(rf); + } + + else if(classname == "dummy") + { + Surface * surf = new DummySurface(); + + AddSurface(surf); + delete_them.Append(surf); + } + + } + } + + + void CSGeometry :: SaveToMeshFile (ostream & ost) const + { + SaveSurfaces (ost); + } + + + + + void CSGeometry :: AddSurface (Surface * surf) + { + static int cntsurfs = 0; + cntsurfs++; + char name[15]; + sprintf (name, "nnsurf%d", cntsurfs); + AddSurface (name, surf); + } + + void CSGeometry :: AddSurface (char * name, Surface * surf) + { + (*testout) << "Adding surface " << name << endl; + surfaces.Set (name, surf); + surf->SetName (name); + changeval++; + } + + void CSGeometry :: AddSurfaces (Primitive * prim) + { + for (int i = 0; i < prim->GetNSurfaces(); i++) + { + AddSurface (&prim->GetSurface(i)); + prim->SetSurfaceId (i, GetNSurf()-1); + surf2prim.Append (prim); + } + } + + const Surface * CSGeometry :: GetSurface (const char * name) const + { + if (surfaces.Used(name)) + return surfaces.Get(name); + else + return NULL; + } + + /* + const Surface * CSGeometry :: GetSurface (int i) const + { + if (i >= 0 && i < surfaces.Size()) + return surfaces[i]; + else + throw NgException ("CSGeometry::GetSurface out of range"); + } + */ + + + + + void CSGeometry :: SetSolid (const char * name, Solid * sol) + { + Solid * oldsol = NULL; + + if (solids.Used (name)) + oldsol = solids.Get(name); + + solids.Set (name, sol); + sol->SetName (name); + + if (oldsol) + { + if (oldsol->op != Solid::ROOT || + sol->op != Solid::ROOT) + { + cerr << "Setsolid: old or new no root" << endl; + } + oldsol -> s1 = sol -> s1; + } + changeval++; + } + + const Solid * CSGeometry :: GetSolid (const char * name) const + { + if (solids.Used(name)) + return solids.Get(name); + else + return NULL; + } + + + + + + const Solid * CSGeometry :: GetSolid (const string & name) const + { + if (solids.Used(name.c_str())) + return solids.Get(name.c_str()); + else + return NULL; + } + + + + + void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<2> * spl) + { + splinecurves2d.Set(name,spl); + } + void CSGeometry :: SetSplineCurve (const char * name, SplineGeometry<3> * spl) + { + splinecurves3d.Set(name,spl); + } + + + const SplineGeometry<2> * CSGeometry :: GetSplineCurve2d (const string & name) const + { + if (splinecurves2d.Used(name.c_str())) + return splinecurves2d.Get(name.c_str()); + else + return NULL; + } + const SplineGeometry<3> * CSGeometry :: GetSplineCurve3d (const string & name) const + { + if (splinecurves3d.Used(name.c_str())) + return splinecurves3d.Get(name.c_str()); + else + return NULL; + } + + + + /* + class RemoveDummyIterator : public SolidIterator + { + public: + + RemoveDummyIterator() { ; } + virtual ~RemoveDummyIterator() { ; } + virtual void Do(Solid * sol); + }; + + void RemoveDummyIterator :: Do(Solid * sol) + { + cerr << "remove dummy iterator is obsolete" << endl; + + if ( (sol->op == Solid::SUB || sol->op == Solid::SECTION || + sol->op == Solid::UNION) + && sol->s1->op == Solid::DUMMY) + sol->s1 = sol->s1->s1; + if ( (sol->op == Solid::SECTION || sol->op == Solid::UNION) + && sol->s2->op == Solid::DUMMY) + sol->s2 = sol->s2->s1; + } + */ + + + + + + + int CSGeometry :: SetTopLevelObject (Solid * sol, Surface * surf) + { + return toplevelobjects.Append (new TopLevelObject (sol, surf)) - 1; + } + + TopLevelObject * CSGeometry :: + GetTopLevelObject (const Solid * sol, const Surface * surf) + { + for (int i = 0; i < toplevelobjects.Size(); i++) + { + if (toplevelobjects[i]->GetSolid() == sol && + toplevelobjects[i]->GetSurface() == surf) + return (toplevelobjects[i]); + } + return NULL; + } + + void CSGeometry :: RemoveTopLevelObject (Solid * sol, Surface * surf) + { + for (int i = 0; i < toplevelobjects.Size(); i++) + { + if (toplevelobjects[i]->GetSolid() == sol && + toplevelobjects[i]->GetSurface() == surf) + { + delete toplevelobjects[i]; + toplevelobjects.DeleteElement (i+1); + changeval++; + break; + } + } + } + + void CSGeometry :: AddIdentification (Identification * ident) + { + identifications.Append (ident); + } + + void CSGeometry :: SetFlags (const char * solidname, const Flags & flags) + { + Solid * solid = solids.Elem(solidname); + Array surfind; + + int i; + double maxh = flags.GetNumFlag ("maxh", -1); + if (maxh > 0 && solid) + { + solid->GetSurfaceIndices (surfind); + + for (i = 0; i < surfind.Size(); i++) + { + if (surfaces[surfind[i]]->GetMaxH() > maxh) + surfaces[surfind[i]] -> SetMaxH (maxh); + } + + solid->SetMaxH (maxh); + } + + if ( flags.StringFlagDefined ("bcname") ) + { + solid->GetSurfaceIndices (surfind); + string bcn = flags.GetStringFlag("bcname", "default"); + for (i = 0; i < surfind.Size(); i++) + { + if(surfaces[surfind[i]]->GetBCName() == "default") + surfaces[surfind[i]]->SetBCName(bcn); + } + } + + if (flags.StringListFlagDefined ("bcname")) + { + const Array & bcname = flags.GetStringListFlag("bcname"); + + Polyhedra * polyh; + if(solid->S1()) + polyh = dynamic_cast(solid->S1()->GetPrimitive()); + else + polyh = dynamic_cast(solid->GetPrimitive()); + + if(polyh) + { + Array < Array * > polysurfs; + polyh->GetPolySurfs(polysurfs); + if(bcname.Size() != polysurfs.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size() + << " surfaces and should get " << bcname.Size() << " bc-names!" << endl; + + for ( i = 0; i < min2(polysurfs.Size(),bcname.Size()); i++) + { + for (int j = 0; j < polysurfs[i]->Size(); j++) + { + if(surfaces[(*polysurfs[i])[j]]->GetBCName() == "default") + surfaces[(*polysurfs[i])[j]]->SetBCName(bcname[i]); + } + delete polysurfs[i]; + } + } + else + { + solid->GetSurfaceIndices (surfind); + if(bcname.Size() != surfind.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size() + << " surfaces and should get " << bcname.Size() << " bc-names!" << endl; + + for (i = 0; i < min2(surfind.Size(),bcname.Size()); i++) + { + if(surfaces[surfind[i]]->GetBCName() == "default") + surfaces[surfind[i]]->SetBCName(bcname[i]); + } + } + } + + if (flags.NumFlagDefined ("bc")) + { + solid->GetSurfaceIndices (surfind); + int bc = int (flags.GetNumFlag("bc", -1)); + for (i = 0; i < surfind.Size(); i++) + { + if (surfaces[surfind[i]]->GetBCProperty() == -1) + surfaces[surfind[i]]->SetBCProperty(bc); + } + } + + if (flags.NumListFlagDefined ("bc")) + { + const Array & bcnum = flags.GetNumListFlag("bc"); + + Polyhedra * polyh; + if(solid->S1()) + polyh = dynamic_cast(solid->S1()->GetPrimitive()); + else + polyh = dynamic_cast(solid->GetPrimitive()); + + if(polyh) + { + Array < Array * > polysurfs; + polyh->GetPolySurfs(polysurfs); + if(bcnum.Size() != polysurfs.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << polysurfs.Size() + << " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl; + + for ( i = 0; i < min2(polysurfs.Size(),bcnum.Size()); i++) + { + for (int j = 0; j < polysurfs[i]->Size(); j++) + { + if ( surfaces[(*polysurfs[i])[j]]->GetBCProperty() == -1 ) + surfaces[(*polysurfs[i])[j]]->SetBCProperty(int(bcnum[i])); + } + delete polysurfs[i]; + } + } + else + { + solid->GetSurfaceIndices (surfind); + if(bcnum.Size() != surfind.Size()) + cerr << "WARNING: solid \"" << solidname << "\" has " << surfind.Size() + << " surfaces and should get " << bcnum.Size() << " bc-numbers!" << endl; + + for (i = 0; i < min2(surfind.Size(),bcnum.Size()); i++) + { + if (surfaces[surfind[i]]->GetBCProperty() == -1) + surfaces[surfind[i]]->SetBCProperty(int(bcnum[i])); + } + } + } + + } + + void CSGeometry :: FindIdenticSurfaces (double eps) + { + int inv; + int nsurf = GetNSurf(); + + isidenticto.SetSize(nsurf); + for (int i = 0; i < nsurf; i++) + isidenticto[i] = i; + + for (int i = 0; i < nsurf; i++) + for (int j = i+1; j < nsurf; j++) + { + if (GetSurface(j) -> IsIdentic (*GetSurface(i), inv, eps)) + { + INDEX_2 i2(i, j); + identicsurfaces.Set (i2, inv); + isidenticto[j] = isidenticto[i]; + } + } + + (*testout) << "identicmap:" << endl; + for (int i = 0; i < isidenticto.Size(); i++) + (*testout) << i << " -> " << isidenticto[i] << endl; + } + + + + void CSGeometry :: + GetSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + Array & locsurf) const + { + ReducePrimitiveIterator rpi(box); + UnReducePrimitiveIterator urpi; + + const_cast (sol) -> IterateSolid (rpi); + sol -> GetSurfaceIndices (locsurf); + const_cast (sol) -> IterateSolid (urpi); + + for (int i = locsurf.Size()-1; i >= 0; i--) + { + bool indep = 1; + for (int j = 0; j < i; j++) + if (locsurf[i] == locsurf[j]) + { + indep = 0; + break; + } + + if (!indep) locsurf.Delete(i); + } + } + + + + + void CSGeometry :: + GetIndependentSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + Array & locsurf) const + { + ReducePrimitiveIterator rpi(box); + UnReducePrimitiveIterator urpi; + + ((Solid*)sol) -> IterateSolid (rpi); + sol -> GetSurfaceIndices (locsurf); + ((Solid*)sol) -> IterateSolid (urpi); + + for (int i = 0; i < locsurf.Size(); i++) + locsurf[i] = isidenticto[locsurf[i]]; + + for (int i = locsurf.Size()-1; i >= 0; i--) + { + bool indep = 1; + for (int j = 0; j < i; j++) + if (locsurf[i] == locsurf[j]) + { + indep = 0; + break; + } + + if (!indep) locsurf.Delete(i); + } + + + /* + // delete identified + for (int i = locsurf.Size()-1; i >= 0; i--) + { + bool indep = 1; + for (int j = 0; j < i; j++) + { + if (identicsurfaces.Used (INDEX_2::Sort (locsurf[i], locsurf[j])) != + (isidenticto[locsurf[i]] == isidenticto[locsurf[j]])) + { + cerr << "different result" << endl; + exit(1); + } + + if (isidenticto[locsurf[i]] == isidenticto[locsurf[j]]) + { + indep = 0; + break; + } + } + if (!indep) + locsurf.Delete(i); + } + + for (int i = 0; i < locsurf.Size(); i++) + locsurf[i] = isidenticto[locsurf[i]]; + */ + } + + /* + void CSGeometry :: + GetIndependentSurfaceIndices (const Solid * sol, + const Point<3> & p, Vec<3> & v, + Array & locsurf) const + { + cout << "very dangerous" << endl; + Point<3> p2 = p + 1e-2 * v; + BoxSphere<3> box (p2, p2); + box.Increase (1e-3); + box.CalcDiamCenter(); + GetIndependentSurfaceIndices (sol, box, locsurf); + } + */ + + void CSGeometry :: + GetIndependentSurfaceIndices (Array & locsurf) const + { + for (int i = 0; i < locsurf.Size(); i++) + locsurf[i] = isidenticto[locsurf[i]]; + + for (int i = locsurf.Size()-1; i >= 0; i--) + { + bool indep = 1; + for (int j = 0; j < i; j++) + if (locsurf[i] == locsurf[j]) + { + indep = 0; + break; + } + + if (!indep) locsurf.Delete(i); + } + } + + + + + + + + + + void CSGeometry :: + CalcTriangleApproximation(double detail, double facets) + { + PrintMessage (1, "Calc Triangle Approximation"); + + try + { + // FindIdenticSurfaces (1e-6); + + int ntlo = GetNTopLevelObjects(); + + for (int i = 0; i < triapprox.Size(); i++) + delete triapprox[i]; + triapprox.SetSize (ntlo); + + Array surfind; + IndexSet iset(GetNSurf()); + + for (int i = 0; i < ntlo; i++) + { + Solid * sol; + Surface * surf; + GetTopLevelObject (i, sol, surf); + + sol -> CalcSurfaceInverse (); + + TriangleApproximation * tams = new TriangleApproximation(); + triapprox[i] = tams; + + // sol -> GetSurfaceIndices (surfind); + for (int j = 0; j < GetNSurf(); j++) + // for (int jj = 0; jj < surfind.Size(); jj++) + { + // int j = surfind[jj]; + + PrintMessageCR (3, "Surface ", j, "/", GetNSurf()); + // PrintMessageCR (3, "Surface ", j, "/", surfind.Size()); + + if (surf && surf != GetSurface(j)) + continue; + + TriangleApproximation tas; + GetSurface (j) -> GetTriangleApproximation (tas, boundingbox, facets); + + int oldnp = tams -> GetNP(); + + if (!tas.GetNP()) + continue; + + for (int k = 0; k < tas.GetNP(); k++) + { + tams -> AddPoint (tas.GetPoint(k)); + Vec<3> n = GetSurface(j) -> GetNormalVector (tas.GetPoint(k)); + n.Normalize(); + if (GetSurface(j)->Inverse()) n *= -1; + tams -> AddNormal (n); + } + + BoxSphere<3> surfbox; + + if (tas.GetNP()) + surfbox.Set (tas.GetPoint(0)); + for (int k = 1; k < tas.GetNP(); k++) + surfbox.Add (tas.GetPoint(k)); + surfbox.Increase (1e-6); + surfbox.CalcDiamCenter(); + + Solid * surflocsol = sol -> GetReducedSolid (surfbox); + if (!surflocsol) + continue; + + for (int k = 0; k < tas.GetNT(); k++) + { + const TATriangle & tri = tas.GetTriangle (k); + + // check triangle + BoxSphere<3> box; + box.Set (tas.GetPoint (tri[0])); + box.Add (tas.GetPoint (tri[1])); + box.Add (tas.GetPoint (tri[2])); + box.Increase (1e-6); + box.CalcDiamCenter(); + + + Solid * locsol = surflocsol -> GetReducedSolid (box); + + if (locsol) + { + TATriangle tria(j, + tri[0] + oldnp, + tri[1] + oldnp, + tri[2] + oldnp); + + // tams -> AddTriangle (tria); + + RefineTriangleApprox (locsol, j, box, detail, + tria, *tams, iset, 1); + + delete locsol; + } + } + } + + tams->RemoveUnusedPoints (); + PrintMessage (2, "Object ", i, " has ", tams->GetNT(), " triangles"); + } + } + catch (exception) + { + cerr << "*************************************************************" << endl + << "**** out of memory problem in CSG visualization ****" << endl + << "**** Restart netgen, and disable ****" << endl + << "**** 'Draw Geometry' in Geometry -> CSG Options ****" << endl + << "**** before loading the geometry ****" << endl + << "**** meshing will still work ! ****" << endl + << "*************************************************************" << endl; + exit(1); + } + Change(); + } + + + + void CSGeometry :: + RefineTriangleApprox (Solid * locsol, + int surfind, + const BoxSphere<3> & box, + double detail, + const TATriangle & tria, + TriangleApproximation & tams, + IndexSet & iset, + int level) + { + // if (level > 10) return; + + //tams.AddTriangle (tria); + //(*testout) << "tria " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2]) + // << " ( " << tria[0] << " " << tria[1] << " " << tria[2] << ")" < surfused(GetNSurf()); + + ReducePrimitiveIterator rpi(box); + UnReducePrimitiveIterator urpi; + + locsol -> IterateSolid (rpi); + // locsol -> GetSurfaceIndices (lsurfi); + + + // IndexSet iset(GetNSurf()); + locsol -> GetSurfaceIndices (iset); + const Array & lsurfi = iset.GetArray(); + + locsol -> IterateSolid (urpi); + + int surfii = -1; + for (int i = 0; i < lsurfi.Size(); i++) + if (lsurfi[i] == surfind) + { + surfii = i; + break; + } + + if (surfii == -1) + return; + + int cntindep = 0; + + for (int i = 0; i < lsurfi.Size(); i++) + { + int linkto = isidenticto[lsurfi[i]]; + surfused[linkto] = 0; + } + + for (int i = 0; i < lsurfi.Size(); i++) + { + int linkto = isidenticto[lsurfi[i]]; + if (!surfused[linkto]) + { + surfused[linkto] = 1; + cntindep++; + } + } + + int inverse = surfaces[surfind]->Inverse(); + + if (cntindep == 1) + { + tams.AddTriangle (tria); + //(*testout) << "pos1 " << tams.GetPoint(tria[0]) << " - " << tams.GetPoint(tria[1]) << " - " << tams.GetPoint(tria[2]) << endl; + return; + } + + if (cntindep == 2) + { + // just 2 surfaces: + // if smooth, project inner points to edge and finish + + int otherind = -1; + + for (int i = 0; i < lsurfi.Size(); i++) + { + INDEX_2 i2 (lsurfi[i], surfind); + i2.Sort(); + + if (i != surfii && !identicsurfaces.Used(i2)) + otherind = lsurfi[i]; + } + + double kappa = GetSurface(otherind)-> MaxCurvature (); + + if (kappa * box.Diam() < 0.1) + { + int pnums[6]; + static int between[3][3] = + { { 1, 2, 3 }, + { 0, 2, 4 }, + { 0, 1, 5 } }; + int onsurface[3]; + + for (int j = 0; j < 3; j++) + { + int pi = tria[j]; + pnums[j] = pi; + + + onsurface[j] = + !locsol->IsStrictIn (tams.GetPoint (pi), 1e-6) && + locsol->IsIn (tams.GetPoint (pi), 1e-6); + + // + /* + static int nos=0; + if(!onsurface[j]) + { + nos++; + cout << "NOT ON SURFACE!! "<< nos << endl; + } + */ + } + + for (int j = 0; j < 3; j++) + { + int lpi1 = between[j][0]; + int lpi2 = between[j][1]; + int lpin = between[j][2]; + if (onsurface[lpi1] == onsurface[lpi2]) + pnums[lpin] = -1; + else + { + const Point<3> & p1 = tams.GetPoint (pnums[lpi1]); + const Point<3> & p2 = tams.GetPoint (pnums[lpi2]); + double f1 = GetSurface(otherind)->CalcFunctionValue (p1); + double f2 = GetSurface(otherind)->CalcFunctionValue (p2); + + Point<3> pn; + + double l2(100),l1(100); + if ( fabs (f1-f2) > 1e-20 ) + { + l2 = -f1/(f2-f1); + l1 = f2/(f2-f1); + pn = Point<3>(l1 * p1(0) + l2 * p2(0), + l1 * p1(1) + l2 * p2(1), + l1 * p1(2) + l2 * p2(2)); + } + else + pn = p1; + +// if(fabs(pn(0)) > 4 || fabs(pn(1)) > 4 || fabs(pn(2)) > 4) +// { +// cout << "p1 " << p1 << " p2 " << p2 +// << " f1 " << f1 << " f2 " << f2 +// << " l1 " << l1 << " l2 " << l2 +// << " pn " << pn << endl; + +// } + + + //GetSurface (surfind)->Project (pn); + + pnums[lpin] = tams.AddPoint (pn); + + GetSurface (surfind)->Project (pn); + + Vec<3> n; + n = GetSurface (surfind)->GetNormalVector (pn); + if (inverse) n *= -1; + tams.AddNormal(n); + } + } + + int vcase = 0; + if (onsurface[0]) vcase++; + if (onsurface[1]) vcase+=2; + if (onsurface[2]) vcase+=4; + + static int trias[8][6] = + { { 0, 0, 0, 0, 0, 0 }, + { 1, 6, 5, 0, 0, 0 }, + { 2, 4, 6, 0, 0, 0 }, + { 1, 2, 4, 1, 4, 5 }, + { 3, 5, 4, 0, 0, 0 }, + { 1, 6, 4, 1, 4, 3 }, + { 2, 3, 6, 3, 5, 6 }, + { 1, 2, 3, 0, 0, 0 } }; + static int ntrias[4] = + { 0, 1, 2, 1 }; + + int nvis = 0; + for (int j = 0; j < 3; j++) + if (onsurface[j]) + nvis++; + + for (int j = 0; j < ntrias[nvis]; j++) + { + TATriangle ntria(tria.SurfaceIndex(), + pnums[trias[vcase][3*j]-1], + pnums[trias[vcase][3*j+1]-1], + pnums[trias[vcase][3*j+2]-1]); + //(*testout) << "pos2 " << tams.GetPoint(ntria[0]) << " - " << tams.GetPoint(ntria[1]) << " - " << tams.GetPoint(ntria[2]) << endl + // << "( " << ntria[0] << " - " << ntria[1] << " - " << ntria[2] << ")" << endl; + tams.AddTriangle (ntria); + } + + /* saturn changes: + + int pvis[3]; + for (j = 0; j < 3; j++) + pvis[j] = !locsol->IsStrictIn (tams.GetPoint (j+1), 1e-6) && + locsol->IsIn (tams.GetPoint (j+1), 1e-6); + + int newpi[3]; + for (j = 0; j < 3; j++) + { + int pi1 = j; + int pi2 = (j+1) % 3; + int pic = j; + + if (pvis[pi1] != pvis[pi2]) + { + Point<3> hp = Center (tams.GetPoint (tria.PNum (pi1+1)), + tams.GetPoint (tria.PNum (pi2+1))); + + newpi[j] = tams.AddPoint (hp); + Vec<3> n = tams.GetNormal (pi1); + tams.AddNormal (n); + } + else + newpi[j] = 0; + } + + int nvis = 0; + for (j = 0; j <= nvis; j++) + if (pvis[j]) nvis++; + + int si = tria.SurfaceIndex(); + switch (nvis) + { + case 0: + break; + case 1: + { + int visj; + for (j = 0; j < 3; j++) + if (pvis[j]) visj = j; + int pivis = tria.PNum (visj+1); + int pic1 = newpi[(visj+1)%3]; + int pic2 = newpi[(visj+2)%3]; + + cout << pivis << "," << pic1 << "," << pic2 << endl; + + tams.AddTriangle (TATriangle (si, pivis, pic1,pic2)); + break; + } + case 2: + { + int nvisj; + for (j = 0; j < 3; j++) + if (!pvis[j]) nvisj = j; + + int pivis1 = tria.PNum ((nvisj+1)%3+1); + int pivis2 = tria.PNum ((nvisj+2)%3+1); + int pic1 = newpi[nvisj]; + int pic2 = newpi[(nvisj+2)%3]; + + tams.AddTriangle (TATriangle (si, pivis1, pic1,pic2)); + tams.AddTriangle (TATriangle (si, pivis1, pic1,pivis2)); + break; + } + case 3: + { + tams.AddTriangle (tria); + break; + } + } + + */ + return; + } + } + + // bisection + if (box.Diam() < detail) + { + //cout << "returning" << endl; + return; + } + + for (int i = 0; i < 3; i++) + pinds[i] = tria[i]; + + static int between[3][3] = + { { 0, 1, 5 }, + { 0, 2, 4 }, + { 1, 2, 3 } }; + + for (int i = 0; i < 3; i++) + { + // int pi1 = tria[between[i][0]]; + + Point<3> newp = Center (tams.GetPoint (tria[between[i][0]]), + tams.GetPoint (tria[between[i][1]])); + Vec<3> n; + + GetSurface(surfind)->Project (newp); + + n = GetSurface(surfind)->GetNormalVector (newp); + + pinds[between[i][2]] = tams.AddPoint (newp); + if (inverse) n *= -1; + tams.AddNormal (n); + } + + static int trias[4][4] = + { { 0, 5, 4 }, + { 5, 1, 3 }, + { 4, 3, 2 }, + { 3, 4, 5 } }; + + for (int i = 0; i < 4; i++) + { + TATriangle ntri(surfind, + pinds[trias[i][0]], + pinds[trias[i][1]], + pinds[trias[i][2]]); + + // check triangle + BoxSphere<3> nbox; + nbox.Set (tams.GetPoint (ntri[0])); + nbox.Add (tams.GetPoint (ntri[1])); + nbox.Add (tams.GetPoint (ntri[2])); + nbox.Increase (1e-8); + nbox.CalcDiamCenter(); + + Solid * nsol = locsol -> GetReducedSolid (nbox); + + if (nsol) + { + RefineTriangleApprox (nsol, surfind, nbox, + detail, ntri, tams, iset, level+1); + + delete nsol; + } + } + } + + + + + class ClearVisitedIt : public SolidIterator + { + public: + ClearVisitedIt () { ; } + virtual ~ClearVisitedIt () { ; } + + virtual void Do (Solid * sol) + { + sol -> visited = 0; + } + }; + + + void CSGeometry :: + IterateAllSolids (SolidIterator & it, bool only_once) const + { + if (only_once) + { + ClearVisitedIt clit; + for (int i = 0; i < solids.Size(); i++) + solids[i] -> IterateSolid (clit, 0); + } + + for (int i = 0; i < solids.Size(); i++) + solids[i] -> IterateSolid (it, only_once); + } + + + double CSGeometry :: MaxSize () const + { + double maxs, mins; + maxs = max3 (boundingbox.PMax()(0), + boundingbox.PMax()(1), + boundingbox.PMax()(2)); + mins = min3 (boundingbox.PMin()(0), + boundingbox.PMin()(1), + boundingbox.PMin()(2)); + return max2 (maxs, -mins) * 1.1; + } + + + + class CSGeometryRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const; + virtual NetgenGeometry * LoadFromMeshFile (istream & ist) const; + // virtual VisualScene * GetVisualScene (const NetgenGeometry * geom) const; + }; + + extern CSGeometry * ParseCSG (istream & istr); + + NetgenGeometry * CSGeometryRegister :: Load (string filename) const + { + const char * cfilename = filename.c_str(); + if (strcmp (&cfilename[strlen(cfilename)-3], "geo") == 0) + { + PrintMessage (1, "Load CSG geometry file ", cfilename); + + ifstream infile(cfilename); + + CSGeometry * hgeom = ParseCSG (infile); + if (!hgeom) + throw NgException ("geo-file should start with 'algebraic3d'"); + + hgeom -> FindIdenticSurfaces(1e-8 * hgeom->MaxSize()); + return hgeom; + } + + if (strcmp (&cfilename[strlen(cfilename)-3], "ngg") == 0) + { + PrintMessage (1, "Load new CSG geometry file ", cfilename); + + ifstream infile(cfilename); + CSGeometry * hgeom = new CSGeometry(""); + hgeom -> Load (infile); + + return hgeom; + } + + + + return NULL; + } + + NetgenGeometry * CSGeometryRegister :: LoadFromMeshFile (istream & ist) const + { + string auxstring; + if (ist.good()) + { + ist >> auxstring; + if (auxstring == "csgsurfaces") + { + CSGeometry * geometry = new CSGeometry (""); + geometry -> LoadSurfaces(ist); + return geometry; + } + // else + // ist.putback (auxstring); + } + return NULL; + } + + + class CSGInit + { + public: + CSGInit() + { + geometryregister.Append (new CSGeometryRegister); + } + }; + + CSGInit csginit; + +} diff --git a/libsrc/csg/csgeom.hpp b/libsrc/csg/csgeom.hpp new file mode 100644 index 00000000..4f0ef5ab --- /dev/null +++ b/libsrc/csg/csgeom.hpp @@ -0,0 +1,329 @@ +#ifndef FILE_CSGEOM +#define FILE_CSGEOM + +/**************************************************************************/ +/* File: csgeom.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 27. Nov. 97 */ +/**************************************************************************/ + +namespace netgen +{ + + /** + Constructive Solid Geometry + */ + + + class TriangleApproximation; + class TATriangle; + + + /** + A top level object is an entity to be meshed. + I can be either a solid, or one surface patch of a solid. + */ + class TopLevelObject + { + Solid * solid; + Surface * surface; + + double red, blue, green; + bool visible, transp; + double maxh; + string material; + int layer; + int bc; // for surface patches, only + string bcname; + + public: + TopLevelObject (Solid * asolid, + Surface * asurface = NULL); + + const Solid * GetSolid() const { return solid; } + Solid * GetSolid() { return solid; } + + const Surface * GetSurface () const { return surface; } + Surface * GetSurface () { return surface; } + + void GetData (ostream & ost); + void SetData (istream & ist); + + void SetMaxH (double amaxh) { maxh = amaxh; } + double GetMaxH () const { return maxh; } + + void SetRGB (double ared, double agreen, double ablue) + { + red = ared; + green = agreen; + blue = ablue; + } + + double GetRed () const { return red; } + double GetGreen () const { return green; } + double GetBlue () const { return blue; } + + void SetTransparent (bool atransp) + { transp = atransp; } + bool GetTransparent () const { return transp; } + + void SetVisible (bool avisible) + { visible = avisible; } + bool GetVisible () const { return visible; } + + const string GetMaterial () const { return material; } + void SetMaterial (const string & mat) { material = mat; } + + int GetLayer () const { return layer; } + void SetLayer (int alayer) { layer = alayer; } + + void SetBCProp (int abc) { bc = abc; } + int GetBCProp () const { return bc; } + + void SetBCName (string abc) { bcname = abc; } + const string GetBCName () const { return bcname; } + }; + + + + + + /** + CSGeometry has the whole geometric information + */ + class CSGeometry : public NetgenGeometry + { + private: + /// all surfaces + SYMBOLTABLE surfaces; + + public: + /// primitive of surface + Array surf2prim; + + private: + Array delete_them; + + /// all named solids + SYMBOLTABLE solids; + + /// all 2d splinecurves + SYMBOLTABLE< SplineGeometry<2>* > splinecurves2d; + /// all 3d splinecurves + SYMBOLTABLE< SplineGeometry<3>* > splinecurves3d; + + /// all top level objects: solids and surfaces + Array toplevelobjects; + + /// additional points specified by user + Array > userpoints; + Array userpoints_ref_factor; + + mutable Array > identpoints; + + /// triangular approximation of top level objects + Array triapprox; + + /// increment, if geometry is changed + static int changeval; + + /// bounding box of geometry + Box<3> boundingbox; + + /// bounding box, if not set by input file + static Box<3> default_boundingbox; + + /// identic surfaces are stored by pair of indizes, val = inverse + INDEX_2_HASHTABLE identicsurfaces; + Array isidenticto; + /// identification of boundaries (periodic, thin domains, ...) + + double ideps; + + /// filename of inputfile + string filename; + + public: + CSGeometry (); + CSGeometry (const string & afilename); + virtual ~CSGeometry (); + + void Clean (); + + virtual void Save (string filename) const; + void Save (ostream & ost) const; + void Load (istream & ist); + + void SaveSurfaces (ostream & out) const; + void LoadSurfaces (istream & in); + + virtual void SaveToMeshFile (ostream & ost) const; + + int GetChangeVal() { return changeval; } + void Change() { changeval++; } + + void AddSurface (Surface * surf); + void AddSurface (char * name, Surface * surf); + void AddSurfaces (Primitive * prim); + + int GetNSurf () const { return surfaces.Size(); } + const Surface * GetSurface (const char * name) const; + const Surface * GetSurface (int i) const + { return surfaces[i]; } + + void SetSolid (const char * name, Solid * sol); + const Solid * GetSolid (const char * name) const; + const Solid * GetSolid (const string & name) const; + int GetNSolids () const { return solids.Size(); } + const Solid * GetSolid (int i) const { return solids[i]; } + const SYMBOLTABLE & GetSolids () const { return solids; } + + + void SetSplineCurve (const char * name, SplineGeometry<2> * spl); + void SetSplineCurve (const char * name, SplineGeometry<3> * spl); + const SplineGeometry<2> * GetSplineCurve2d (const string & name) const; + const SplineGeometry<3> * GetSplineCurve3d (const string & name) const; + + + void SetFlags (const char * solidname, const Flags & flags); + + + int GetNTopLevelObjects () const + { return toplevelobjects.Size(); } + int SetTopLevelObject (Solid * sol, Surface * surf = NULL); + void GetTopLevelObject (int nr, Solid *& sol, Surface *& surf) + { + sol = toplevelobjects[nr]->GetSolid(); + surf = toplevelobjects[nr]->GetSurface(); + } + void GetTopLevelObject (int nr, const Solid *& sol, const Surface *& surf) const + { + sol = toplevelobjects[nr]->GetSolid(); + surf = toplevelobjects[nr]->GetSurface(); + } + + TopLevelObject * GetTopLevelObject (const Solid * sol, const Surface * surf = NULL); + TopLevelObject * GetTopLevelObject (int nr) const + { return toplevelobjects[nr]; } + // const TopLevelObject * GetTopLevelObject (int nr) const + // { return toplevelobjects[nr]; } + void RemoveTopLevelObject (Solid * sol, Surface * surf = NULL); + + + void AddUserPoint (const Point<3> & p, double ref_factor = 0) + { userpoints.Append (p); userpoints_ref_factor.Append (ref_factor); } + int GetNUserPoints () const + { return userpoints.Size(); } + const Point<3> & GetUserPoint (int nr) const + { return userpoints[nr]; } + double GetUserPointRefFactor (int nr) const + { return userpoints_ref_factor[nr]; } + + void AddIdentPoint (const Point<3> & p) const + { identpoints.Append(p);} + int GetNIdentPoints (void) const + { return identpoints.Size();} + const Point<3> & GetIdentPoint(int nr) const + { return identpoints[nr]; } + void DeleteIdentPoints(void) const + { identpoints.DeleteAll();} + + + // quick implementations: + Array singfaces; + Array singedges; + Array singpoints; + Array identifications; + + int GetNIdentifications (void) const { return identifications.Size(); } + void AddIdentification (Identification * ident); + + + /// + void CalcTriangleApproximation(double detail, double facets); + + /// + void FindIdenticSurfaces (double eps); + /// + void GetSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + Array & locsurf) const; + /// + void GetIndependentSurfaceIndices (const Solid * sol, + const BoxSphere<3> & box, + Array & locsurf) const; + /// + /* + void GetIndependentSurfaceIndices (const Solid * sol, + const Point<3> & p, Vec<3> & v, + Array & locsurf) const; + */ + /// + void GetIndependentSurfaceIndices (Array & locsurf) const; + + /// + int GetSurfaceClassRepresentant (int si) const + { return isidenticto[si]; } + + /// + const TriangleApproximation * GetTriApprox (int msnr) + { + if (msnr < triapprox.Size()) + return triapprox[msnr]; + return 0; + } + + + void IterateAllSolids (SolidIterator & it, bool only_once = false) const; + + void RefineTriangleApprox (Solid * locsol, + int surfind, + const BoxSphere<3> & box, + double detail, + const TATriangle & tria, + TriangleApproximation & tams, + IndexSet & iset, + int level); + + const Box<3> & BoundingBox () const { return boundingbox; } + + void SetBoundingBox (const Box<3> & abox) + { + boundingbox = abox; + } + + + static void SetDefaultBoundingBox (const Box<3> & abox) + { + default_boundingbox = abox; + } + + double MaxSize () const; + + void SetIdEps(double eps){ideps = eps;} + double GetIdEps(void) const {return ideps;} + + class BCModification { + public: + int si; + int tlonr; + int bcnr; + string * bcname; + }; + + Array bcmodifications; + + virtual int GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend); + + virtual const Refinement & GetRefinement () const; + }; + + + + + +} + +#endif + diff --git a/libsrc/csg/csgparser.cpp b/libsrc/csg/csgparser.cpp new file mode 100644 index 00000000..c2728bcd --- /dev/null +++ b/libsrc/csg/csgparser.cpp @@ -0,0 +1,1390 @@ +#include +#include + +#include +#include + + +namespace netgen +{ + static kwstruct defkw[] = + { + { TOK_RECO, "algebraic3d" }, + { TOK_SOLID, "solid" }, + { TOK_TLO, "tlo" }, + { TOK_CURVE2D, "curve2d" }, + { TOK_CURVE3D, "curve3d" }, + { TOK_BOUNDINGBOX, "boundingbox" }, + { TOK_OR, "or" }, + { TOK_AND, "and" }, + { TOK_NOT, "not" }, + { TOK_SINGULAR, "singular" }, + { TOK_EDGE, "edge" }, + { TOK_FACE, "face" }, + { TOK_POINT, "point" }, + { TOK_IDENTIFY, "identify" }, + { TOK_CLOSESURFACES, "closesurfaces" }, + { TOK_CLOSEEDGES, "closeedges" }, + { TOK_PERIODIC, "periodic" }, + { TOK_BOUNDARYCONDITION, "boundarycondition" }, + { TOK_BOUNDARYCONDITIONNAME, "boundaryconditionname" }, + { TOK_DEFINE, "define" }, + { TOK_CONSTANT, "constant" }, + { TOKEN_TYPE(0), 0 } + }; + + static primstruct defprim[] = + { + { TOK_PLANE, "plane" }, + { TOK_SPHERE, "sphere" }, + { TOK_CYLINDER, "cylinder" }, + { TOK_CONE, "cone" }, + { TOK_ELLIPTICCYLINDER, "ellipticcylinder" }, + { TOK_ELLIPSOID, "ellipsoid" }, + { TOK_ORTHOBRICK, "orthobrick" }, + { TOK_POLYHEDRON, "polyhedron" }, + { TOK_TORUS, "torus" }, + + { TOK_TUBE, "tube" }, + { TOK_GENCYL, "gencyl" }, + { TOK_EXTRUSION, "extrusion" }, + { TOK_REVOLUTION, "revolution" }, + + { TOK_TRANSLATE, "translate" }, + { TOK_MULTITRANSLATE, "multitranslate" }, + { TOK_ROTATE, "rotate" }, + { TOK_MULTIROTATE, "multirotate" }, + { PRIMITIVE_TYPE(0), 0 } + }; + + static CSGeometry * geom; + + + CSGScanner :: CSGScanner (istream & ascanin) + { + scanin = &ascanin; + token = TOK_END; + num_value = 0; + linenum = 1; + } + + + void CSGScanner :: ReadNext () + { + char ch; + + + // scan whitespaces + do + { + scanin->get(ch); + + //if (ch == '\n') + // linenum++; + + // end of file reached + if (scanin->eof()) + { + token = TOK_END; + return; + } + if (ch == '\n') + linenum++; + + + // skip comment line + if (ch == '#') + { + while (ch != '\n') + { + scanin->get(ch); + if (scanin->eof()) + { + token = TOK_END; + return; + } + } + linenum++; + } + } + while (isspace(ch)); + + switch (ch) + { + case '(': case ')': + case '[': case ']': + case '-': + case '=': case ',': case ';': + { + token = TOKEN_TYPE (ch); + break; + } + + default: + { + if (isdigit (ch) || ch == '.') + { + scanin->putback (ch); + (*scanin) >> num_value; + token = TOK_NUM; + return; + } + + if (isalpha (ch)) + { + string_value = string (1, ch); + scanin->get(ch); + while (isalnum(ch) || ch == '_') + { + string_value += ch; + scanin->get(ch); + } + scanin->putback (ch); + } + + int nr = 0; + while (defkw[nr].kw) + { + if (string_value == defkw[nr].name) + { + token = defkw[nr].kw; + return; + } + nr++; + } + + nr = 0; + while (defprim[nr].kw) + { + if (string_value == defprim[nr].name) + { + token = TOK_PRIMITIVE; + prim_token = defprim[nr].kw; + return; + } + nr++; + } + + token = TOK_STRING; + } + } + } + + void CSGScanner :: Error (const string & err) + { + stringstream errstr; + errstr << "Parsing error in line " << linenum << ": " << endl << err << endl; + throw string(errstr.str()); + } + + + /* + Solid = Term { OR Term } + Term = Primary { AND Primary } + Primary = PRIM | IDENT | ( Solid ) | NOT Primary + */ + + void ParseChar (CSGScanner & scan, char ch) + { + if (scan.GetToken() != TOKEN_TYPE(ch)) + scan.Error (string ("token '") + string(1, ch) + string("' expected")); + scan.ReadNext(); + } + + double ParseNumber(CSGScanner & scan) + { + if (scan.GetToken() == '-') + { + scan.ReadNext(); + return -ParseNumber (scan); + } + if (scan.GetToken() != TOK_NUM) scan.Error ("number expected"); + double val = scan.GetNumValue(); + scan.ReadNext(); + return val; + } + + Vec<3> ParseVector (CSGScanner & scan) + { + Vec<3> v; + v(0) = ParseNumber (scan); + ParseChar (scan, ','); + v(1) = ParseNumber (scan); + ParseChar (scan, ','); + v(2) = ParseNumber (scan); + return v; + } + + + CSGScanner & operator>> (CSGScanner & scan, char ch) + { + if (scan.GetToken() != TOKEN_TYPE(ch)) + scan.Error (string ("token '") + string(1, ch) + string("' expected")); + scan.ReadNext(); + return scan; + } + + CSGScanner & operator>> (CSGScanner & scan, double & d) + { + d = ParseNumber (scan); + return scan; + } + + CSGScanner & operator>> (CSGScanner & scan, int & i) + { + i = int (ParseNumber (scan)); + return scan; + } + + CSGScanner & operator>> (CSGScanner & scan, Point<3> & p) + { + scan >> p(0) >> ',' >> p(1) >> ',' >> p(2); + return scan; + } + + CSGScanner & operator>> (CSGScanner & scan, Vec<3> & v) + { + scan >> v(0) >> ',' >> v(1) >> ',' >> v(2); + return scan; + } + + + Solid * ParseSolid (CSGScanner & scan); + Solid * ParseTerm (CSGScanner & scan); + Solid * ParsePrimary (CSGScanner & scan); + + + Solid * ParsePrimary (CSGScanner & scan) + { + if (scan.GetToken() == TOK_PRIMITIVE) + { + switch (scan.GetPrimitiveToken()) + { + case TOK_PLANE: + { + Point<3> p; + Vec<3> v; + + scan.ReadNext(); + scan >> '(' >> p >> ';' >> v >> ')'; + + OneSurfacePrimitive * surf = new Plane ( p, v ); + geom->AddSurfaces (surf); + return new Solid (surf); + } + + case TOK_CYLINDER: + { + Point<3> pa, pb; + double r; + + scan.ReadNext(); + scan >> '(' >> pa >> ';' >> pb >> ';' >> r >> ')'; + + OneSurfacePrimitive * surf = new Cylinder ( pa, pb, r ); + geom->AddSurfaces (surf); + return new Solid (surf); + } + + case TOK_ELLIPTICCYLINDER: + { + Point<3> pa; + Vec<3> vl, vs; + + scan.ReadNext(); + scan >> '(' >> pa >> ';' >> vl >> ';' >> vs >> ')'; + + OneSurfacePrimitive * surf = new EllipticCylinder ( pa, vl, vs); + geom->AddSurfaces (surf); + return new Solid (surf); + } + + + case TOK_ELLIPSOID: + { + Point<3> pa; + Vec<3> v1, v2, v3; + + scan.ReadNext(); + scan >> '(' >> pa >> ';' >> v1 >> ';' >> v2 >> ';' >> v3 >> ')'; + + OneSurfacePrimitive * surf = new Ellipsoid ( pa, v1, v2, v3); + geom->AddSurfaces (surf); + return new Solid (surf); + } + + + case TOK_CONE: + { + Point<3> pa, pb; + double ra, rb; + + scan.ReadNext(); + scan >> '(' >> pa >> ';' >> ra >> ';' >> pb >> ';' >> rb >> ')'; + + OneSurfacePrimitive * surf = new Cone ( pa, pb, ra, rb ); + geom->AddSurfaces (surf); + return new Solid (surf); + } + + + + case TOK_SPHERE: + { + Point<3> p; + double r; + + scan.ReadNext(); + scan >> '(' >> p >> ';' >> r >> ')'; + + OneSurfacePrimitive * surf = new Sphere ( p, r ); + geom->AddSurfaces (surf); + return new Solid (surf); + } + + case TOK_ORTHOBRICK: + { + Point<3> pa, pb; + + scan.ReadNext(); + scan >> '(' >> pa >> ';' >> pb >> ')'; + + + Primitive * nprim = new OrthoBrick (pa, pb); + geom->AddSurfaces (nprim); + return new Solid (nprim); + } + + case TOK_POLYHEDRON: + { + // Added by Dalibor Lukas, October 15, 2003 + + Point<3> p; + //int pi1, pi2, pi3, pi4; + + scan.ReadNext(); + ParseChar (scan, '('); + + Polyhedra * polyhedron = new Polyhedra; + + // scanning the points + while (1) + { + p = Point<3> (ParseVector (scan)); + ParseChar (scan, ';'); + + polyhedron->AddPoint(p); + + if (scan.GetToken() == ';') + { + scan.ReadNext(); + break; + } + } + + // scanning the faces + int inputface = 0; + while (1) + { + Array pnums,cleaned_pnums; + for(int i=0; i<3; i++) + { + pnums.Append((int) (ParseNumber (scan))); + if(i<2) + ParseChar (scan, ','); + } + + if (scan.GetToken() == TOK_COMMA) + { + ParseChar (scan, ','); + pnums.Append((int) (ParseNumber (scan))); + } + + for(int i=0; iAddFace(cleaned_pnums[0]-1, + cleaned_pnums[1]-1, + cleaned_pnums[2]-1, + inputface); + } + else if(cleaned_pnums.Size() == 4) + { + polyhedron->AddFace(cleaned_pnums[0]-1, + cleaned_pnums[1]-1, + cleaned_pnums[2]-1, + inputface); + polyhedron->AddFace(cleaned_pnums[0]-1, + cleaned_pnums[2]-1, + cleaned_pnums[3]-1, + inputface); + } + else + { + ostringstream msg; + msg << "Something wrong with polyhedron face:"; + for(int i=0; iAddSurfaces (polyhedron); + return new Solid (polyhedron); + } + + + case TOK_REVOLUTION: + { + Point<3> p0,p1; + + scan.ReadNext(); + scan >> '(' >> p0 >> ';' >> p1 >> ';'; + + string spline = scan.GetStringValue(); + + scan.ReadNext(); + scan >> ')'; + + if(!geom->GetSplineCurve2d(spline)) + { + scan.Error ( string("2D Spline curve not found: ") + spline ); + break; + } + + Primitive * nprim = new Revolution(p0,p1, + *(geom->GetSplineCurve2d(spline))); + + geom->AddSurfaces (nprim); + return new Solid(nprim); + } + + + case TOK_EXTRUSION: + { + scan.ReadNext(); + scan >> '('; + string epath = scan.GetStringValue(); + scan.ReadNext(); + scan >> ';'; + string profile = scan.GetStringValue(); + + + scan.ReadNext(); + Vec<3> z_dir; + scan >> ';' >> z_dir(0) >> ',' >> z_dir(1) >> ',' >> z_dir(2) >> ')'; + + if(!geom->GetSplineCurve2d(profile)) + { + scan.Error ( string("2D Spline curve not found: ") + profile ); + break; + } + if(!geom->GetSplineCurve3d(epath)) + { + scan.Error ( string("2D Spline curve not found: ") + epath ); + break; + } + + Primitive * nprim = new Extrusion(*(geom->GetSplineCurve3d(epath)), + *(geom->GetSplineCurve2d(profile)), + z_dir); + geom->AddSurfaces (nprim); + return new Solid(nprim); + } + + + /// Torus + /// Lorenzo Codecasa (codecasa@elet.polimi.it) + /// April 27th, 2005 + /// + /// begin... + case TOK_TORUS: + { + Point<3> pc; + Vec<3> vn; + double R, r; + + scan.ReadNext(); + scan >> '(' >> pc >> ';' >> vn >> ';' >> R >> ';' >> r >> ')'; + + OneSurfacePrimitive * surf = new Torus ( pc, vn, R, r ); + geom->AddSurfaces (surf); + return new Solid (surf); + } + /// ..end + + + + + case TOK_TRANSLATE: + { + Vec<3> v; + scan.ReadNext(); + + ParseChar (scan, '('); + v = ParseVector (scan); + ParseChar (scan, ';'); + + Solid * sol1 = ParseSolid (scan); + + ParseChar (scan, ')'); + + Solid * nsol = sol1 -> Copy(*geom); + Transformation<3> trans(v); + nsol -> Transform (trans); + return nsol; + } + + + case TOK_ROTATE: + { + Point<3> c; + Vec<3> v; + scan.ReadNext(); + + scan >> '(' >> c >> ';' >> v >> ';'; + + Solid * sol1 = ParseSolid (scan); + + ParseChar (scan, ')'); + + Solid * nsol = sol1 -> Copy(*geom); + Transformation<3> trans(c,v(0),v(1),v(2)); + nsol -> Transform (trans); + return nsol; + } + + + case TOK_MULTITRANSLATE: + { + Vec<3> v; + int n; + + scan.ReadNext(); + + scan >> '(' >> v >> ';' >> n >> ';'; + + Solid * sol1 = ParseSolid (scan); + + scan >> ')'; + + Solid * hsol = sol1; + for (int i = 1; i <= n; i++) + { + Solid * nsol = sol1 -> Copy(*geom); + Transformation<3> trans(double(i) * v); + + nsol -> Transform (trans); + hsol = new Solid (Solid::UNION, hsol, nsol); + } + return hsol; + } + + + case TOK_MULTIROTATE: + { + Point<3> c; + Vec<3> v; + int n; + + scan.ReadNext(); + + scan >> '(' >> c >> ';' >> v >> ';' >> n >> ';'; + Solid * sol1 = ParseSolid (scan); + scan >> ')'; + + Transformation<3> trans(c, v(0), v(1), v(2)); + Transformation<3> multi(Vec<3>(0,0,0)); + Transformation<3> ht; + + Solid * hsol = sol1; + for (int i = 1; i <= n; i++) + { + Solid * nsol = sol1 -> Copy(*geom); + + nsol -> Transform (multi); + hsol = new Solid (Solid::UNION, hsol, nsol); + + ht=multi; + multi.Combine (trans, ht); + } + return hsol; + } + + + default: + { + scan.Error (string ("unknown primary ") + scan.GetStringValue()); + } + + } + } + + else if (scan.GetToken() == TOK_STRING && + geom->GetSolid(scan.GetStringValue())) + + { + Solid * sol = const_cast (geom->GetSolid(scan.GetStringValue())); + scan.ReadNext(); + return sol; + } + + else if (scan.GetToken() == TOK_NOT) + + { + scan.ReadNext(); + Solid * sol1 = ParsePrimary (scan); + return new Solid (Solid::SUB, sol1); + } + + else if (scan.GetToken() == '(') + + { + scan.ReadNext(); + Solid * sol1 = ParseSolid (scan); + scan.ReadNext(); + return sol1; + } + + scan.Error (string ("not a primary, name = ")+ + scan.GetStringValue()); + return 0; + } + + + + Solid * ParseTerm (CSGScanner & scan) + { + Solid * sol = ParsePrimary(scan); + while (scan.GetToken() == TOK_AND) + { + scan.ReadNext(); + Solid * sol2 = ParsePrimary(scan); + sol = new Solid (Solid::SECTION, sol, sol2); + } + return sol; + } + + + Solid * ParseSolid (CSGScanner & scan) + { + Solid * sol = ParseTerm(scan); + while (scan.GetToken() == TOK_OR) + { + scan.ReadNext(); + Solid * sol2 = ParseTerm(scan); + sol = new Solid (Solid::UNION, sol, sol2); + } + return sol; + } + + + template + void LoadSpline (SplineGeometry & spline, CSGScanner & scan) + { + double hd; + Point x; + int nump, numseg; + + //scan.ReadNext(); + scan >> nump >> ';'; + + hd = 1; + spline.geompoints.SetSize(nump); + for(int i = 0; i> x(0) >> ',' >> x(1) >> ';'; + else if(D==3) + scan >> x(0) >> ',' >> x(1) >> ',' >> x(2) >> ';'; + + spline.geompoints[i] = GeomPoint(x,hd); + } + + scan >> numseg;// >> ';'; + + spline.splines.SetSize(numseg); + + int pnums,pnum1,pnum2,pnum3; + + + for(int i = 0; i> ';' >> pnums >> ','; + if (pnums == 2) + { + scan >> pnum1 >> ',' >> pnum2;// >> ';'; + spline.splines[i] = new LineSeg(spline.geompoints[pnum1-1], + spline.geompoints[pnum2-1]); + } + else if (pnums == 3) + { + scan >> pnum1 >> ',' >> pnum2 >> ',' + >> pnum3;// >> ';'; + spline.splines[i] = new SplineSeg3(spline.geompoints[pnum1-1], + spline.geompoints[pnum2-1], + spline.geompoints[pnum3-1]); + } + else if (pnums == 4) + { + scan >> pnum1 >> ',' >> pnum2 >> ',' + >> pnum3;// >> ';'; + spline.splines[i] = new CircleSeg(spline.geompoints[pnum1-1], + spline.geompoints[pnum2-1], + spline.geompoints[pnum3-1]); + } + } + } + + + + + void ParseFlags (CSGScanner & scan, Flags & flags) + { + while (scan.GetToken() == '-') + { + scan.ReadNext(); + string name = scan.GetStringValue(); + scan.ReadNext(); + if (scan.GetToken() == '=') + { + scan.ReadNext(); + if (scan.GetToken() == TOK_STRING) + { + flags.SetFlag (name.c_str(), scan.GetStringValue().c_str()); + scan.ReadNext(); + } + else if (scan.GetToken() == '[') + { + scan.ReadNext(); + + if(scan.GetToken() == '-' || scan.GetToken() == TOK_NUM) + { + Array vals; + vals.Append (ParseNumber(scan)); + while (scan.GetToken() == ',') + { + scan.ReadNext(); + vals.Append (ParseNumber(scan)); + } + ParseChar (scan, ']'); + flags.SetFlag (name.c_str(), vals); + } + else + { // string list + Array vals; + string val = scan.GetStringValue(); + vals.Append(new char[val.size()+1]); + strcpy(vals.Last(),val.c_str()); + scan.ReadNext(); + + while (scan.GetToken() == ',') + { + scan.ReadNext(); + val = scan.GetStringValue(); + vals.Append(new char[val.size()+1]); + strcpy(vals.Last(),val.c_str()); + scan.ReadNext(); + } + ParseChar (scan, ']'); + flags.SetFlag (name.c_str(), vals); + for(int i=0; iGetSolid (name)) + scan.Error ("Top-Level-Object "+name+" not defined"); + + int tlonr = + geom->SetTopLevelObject ((Solid*)geom->GetSolid(name)); + TopLevelObject * tlo = geom->GetTopLevelObject (tlonr); + + if (flags.NumListFlagDefined ("col")) + { + const Array & col = + flags.GetNumListFlag ("col"); + tlo->SetRGB (col[0], col[1], col[2]); + } + + if (flags.GetDefineFlag ("transparent")) + tlo->SetTransparent (1); + + tlo->SetMaterial (flags.GetStringFlag ("material", "")); + tlo->SetLayer (int(flags.GetNumFlag ("layer", 1))); + if (flags.NumFlagDefined ("maxh")) + tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10)); + } + + else + + { // a surface TLO + + string surfname = scan.GetStringValue(); + scan.ReadNext(); + + Flags flags; + ParseFlags (scan, flags); + + ParseChar (scan, ';'); + + Array si; + geom->GetSolid(surfname)->GetSurfaceIndices(si); + int tlonr = + geom->SetTopLevelObject ((Solid*)geom->GetSolid(name), + (Surface*)geom->GetSurface(si.Get(1))); + TopLevelObject * tlo = geom->GetTopLevelObject (tlonr); + if (flags.NumListFlagDefined ("col")) + { + const Array & col = flags.GetNumListFlag ("col"); + tlo->SetRGB (col.Get(1), col.Get(2), col.Get(3)); + } + if (flags.GetDefineFlag ("transparent")) + tlo->SetTransparent (1); + + if (flags.NumFlagDefined ("maxh")) + tlo->SetMaxH (flags.GetNumFlag("maxh", 1e10)); + tlo->SetLayer (int(flags.GetNumFlag ("layer", 1))); + tlo->SetBCProp (int(flags.GetNumFlag ("bc", -1))); + if ( flags.StringFlagDefined("bcname") ) + tlo->SetBCName ( flags.GetStringFlag ("bcname", "default") ); + } + } + + else if (scan.GetToken() == TOK_IDENTIFY) + + { + + scan.ReadNext(); + switch (scan.GetToken()) + { + case TOK_CLOSESURFACES: + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + Flags flags; + ParseFlags (scan, flags); + + ParseChar (scan, ';'); + + + Array si1, si2; + geom->GetSolid(name1)->GetSurfaceIndices(si1); + geom->GetSolid(name2)->GetSurfaceIndices(si2); + + const TopLevelObject * domain = 0; + if (flags.StringFlagDefined ("tlo")) + { + domain = + geom->GetTopLevelObject (geom->GetSolid(flags.GetStringFlag ("tlo",""))); + if (!domain) + scan.Error ("identification needs undefined tlo"); + } + + geom->AddIdentification + (new CloseSurfaceIdentification + (geom->GetNIdentifications()+1, *geom, + geom->GetSurface (si1[0]), geom->GetSurface (si2[0]), + domain, + flags)); + + break; + } + + case TOK_PERIODIC: + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + ParseChar (scan, ';'); + + + Array si1, si2; + geom->GetSolid(name1)->GetSurfaceIndices(si1); + geom->GetSolid(name2)->GetSurfaceIndices(si2); + + geom->AddIdentification + (new PeriodicIdentification + (geom->GetNIdentifications()+1, + *geom, + geom->GetSurface (si1.Get(1)), + geom->GetSurface (si2.Get(1)))); + break; + } + + default: + scan.Error ("keyword 'closesurfaces' or 'periodic' expected"); + } + + } + + else if (scan.GetToken() == TOK_SINGULAR) + + { + + scan.ReadNext(); + switch (scan.GetToken()) + { + case TOK_FACE: + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); // tlo + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + Flags flags; + ParseFlags (scan, flags); + int factor = int(flags.GetNumFlag("factor",1)); + // cout << "Singular Face with factor " << factor << endl; + PrintMessageCR (3, "Singular Face with factor ", factor); + + ParseChar (scan, ';'); + + const Solid * sol = geom->GetSolid(name2); + + if(!sol) + scan.Error ("unknown solid in singular face definition"); + else + for (int i = 0; i < geom->GetNTopLevelObjects(); i++) + if (name1 == geom->GetTopLevelObject (i)->GetSolid()->Name()) + geom->singfaces.Append (new SingularFace (i+1, sol,factor)); + + break; + } + + case TOK_EDGE: + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + Flags flags; + ParseFlags (scan, flags); + int factor = int(flags.GetNumFlag("factor",1)); + double maxhinit = flags.GetNumFlag("maxh",-1); + ParseChar (scan, ';'); + + const Solid * s1 = geom->GetSolid(name1); + const Solid * s2 = geom->GetSolid(name2); + PrintMessageCR (3, "Singular Edge with factor ", factor); + + int domnr = -1; + if (flags.StringFlagDefined ("tlo")) + { + const Solid * sol = + geom->GetSolid(flags.GetStringFlag ("tlo","")); + + for (int i = 0; i < geom->GetNTopLevelObjects(); i++) + if (geom->GetTopLevelObject(i)->GetSolid() == sol) + domnr = i; + + // cout << "domnr = " << domnr; + } + + if(!s1 || !s2) + scan.Error ("unknown solid ins singular edge definition"); + else + geom->singedges.Append (new SingularEdge (1, domnr, + *geom, s1, s2, factor, + maxhinit)); + break; + } + + case TOK_POINT: + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + string name2 = scan.GetStringValue(); + scan.ReadNext(); + string name3 = scan.GetStringValue(); + scan.ReadNext(); + + Flags flags; + ParseFlags (scan, flags); + int factor = int(flags.GetNumFlag("factor",1)); + ParseChar (scan, ';'); + + const Solid * s1 = geom->GetSolid(name1); + const Solid * s2 = geom->GetSolid(name2); + const Solid * s3 = geom->GetSolid(name3); + // cout << "Singular Point with factor " << factor << endl; + PrintMessageCR (3, "Singular Point with factor ", factor); + geom->singpoints.Append (new SingularPoint (1, s1, s2, s3, factor)); + break; + } + default: + scan.Error ("keyword 'face' or 'edge' or 'point' expected"); + } + } + + + else if (scan.GetToken() == TOK_POINT) + { + Point<3> p; + + scan.ReadNext(); + ParseChar (scan, '('); + p = Point<3> (ParseVector (scan)); + ParseChar (scan, ')'); + + + Flags flags; + ParseFlags (scan, flags); + int factor = int(flags.GetNumFlag("factor",0)); + + ParseChar (scan, ';'); + + geom->AddUserPoint (p, factor); + } + + else if (scan.GetToken() == TOK_BOUNDINGBOX) + { + Point<3> p1, p2; + + scan.ReadNext(); + ParseChar (scan, '('); + p1 = Point<3> (ParseVector (scan)); + ParseChar (scan, ';'); + p2 = Point<3> (ParseVector (scan)); + ParseChar (scan, ')'); + ParseChar (scan, ';'); + + geom->SetBoundingBox (Box<3> (p1, p2)); + } + + else if (scan.GetToken() == TOK_CURVE2D) + { + scan.ReadNext(); + + + if (scan.GetToken() != TOK_STRING) + scan.Error ("name identifier expected"); + string curvename = scan.GetStringValue(); + + scan.ReadNext(); + + ParseChar (scan, '='); + ParseChar (scan, '('); + + SplineGeometry<2> * newspline = new SplineGeometry<2>; + // newspline->CSGLoad(scan); + LoadSpline (*newspline, scan); + + ParseChar (scan, ')'); + ParseChar (scan, ';'); + + geom->SetSplineCurve(curvename.c_str(),newspline); + + PrintMessage (4, "define 2d curve ", curvename); + } + + else if (scan.GetToken() == TOK_CURVE3D) + { + scan.ReadNext(); + + + if (scan.GetToken() != TOK_STRING) + scan.Error ("name identifier expected"); + string curvename = scan.GetStringValue(); + + scan.ReadNext(); + + ParseChar (scan, '='); + ParseChar (scan, '('); + + SplineGeometry<3> * newspline = new SplineGeometry<3>; + // newspline->CSGLoad(scan); + LoadSpline (*newspline, scan); + + ParseChar (scan, ')'); + ParseChar (scan, ';'); + + geom->SetSplineCurve(curvename.c_str(),newspline); + + PrintMessage (4, "define 3d curve ", curvename); + } + + else if (scan.GetToken() == TOK_BOUNDARYCONDITION) + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + int num = int (ParseNumber (scan)); + ParseChar (scan, ';'); + + + CSGeometry::BCModification bcm; + bcm.bcname = NULL; + Array si; + + geom->GetSolid(name1)->GetSurfaceIndices(si); + if(si.Size() == 0) + { + string errstring = "solid \""; errstring += name1; errstring += "\" has no surfaces"; + scan.Error (errstring); + } + + bcm.tlonr = -1; + int i; + for (i = 0; i < geom->GetNTopLevelObjects(); i++) + if (string (geom->GetTopLevelObject(i)->GetSolid()->Name()) + == name2) + { + bcm.tlonr = i; + break; + } + if(bcm.tlonr == -1) + { + string errstring = "tlo \""; errstring += name2; errstring += "\" not found"; + scan.Error(errstring); + } + + + bcm.bcnr = num; + for (i = 0; i < si.Size(); i++) + { + bcm.si = si[i]; + geom->bcmodifications.Append (bcm); + } + } + + else if (scan.GetToken() == TOK_BOUNDARYCONDITIONNAME) + { + scan.ReadNext(); + + string name1 = scan.GetStringValue(); + scan.ReadNext(); + + string name2 = scan.GetStringValue(); + scan.ReadNext(); + + string bcname = scan.GetStringValue(); + scan.ReadNext(); + ParseChar(scan, ';'); + + + CSGeometry::BCModification bcm; + bcm.bcname = NULL; + + + Array si; + + geom->GetSolid(name1)->GetSurfaceIndices(si); + if(si.Size() == 0) + { + string errstring = "solid \""; errstring += name1; errstring += "\" has no surfaces"; + scan.Error (errstring); + } + + bcm.tlonr = -1; + int i; + for (i = 0; i < geom->GetNTopLevelObjects(); i++) + if (string (geom->GetTopLevelObject(i)->GetSolid()->Name()) + == name2) + { + bcm.tlonr = i; + break; + } + if(bcm.tlonr == -1) + { + string errstring = "tlo \""; errstring += name2; errstring += "\" not found"; + scan.Error(errstring); + } + + + bcm.bcnr = -1; + for (i = 0; i < si.Size(); i++) + { + bcm.si = si[i]; + geom->bcmodifications.Append (bcm); + geom->bcmodifications.Last().bcname = new string(bcname); + } + } + + else if (scan.GetToken() == TOK_DEFINE) + { + scan.ReadNext(); + string name; + double val; + + switch (scan.GetToken()) + { + case TOK_CONSTANT: + scan.ReadNext(); + + name = scan.GetStringValue(); + scan.ReadNext(); + + ParseChar(scan, '='); + val = ParseNumber(scan); + + if(name == "identprec") + geom->SetIdEps(val); + + + + break; + default: + scan.Error ("keyword 'constant' expected"); + } + } + + + else + { + cout << "read unidentified token " << scan.GetToken() + << " (as char: \"" << char(scan.GetToken()) << "\")" + << " string = " << scan.GetStringValue() << endl; + scan.ReadNext(); + } + } + } + catch (string errstr) + { + cout << "caught error " << errstr << endl; + throw NgException (errstr); + } + + + + (*testout) << geom->GetNTopLevelObjects() << " TLOs:" << endl; + for (int i = 0; i < geom->GetNTopLevelObjects(); i++) + { + const TopLevelObject * tlo = geom->GetTopLevelObject(i); + if (tlo->GetSolid()) + (*testout) << i << ": " << *tlo->GetSolid() << endl; + } + + (*testout) << geom->GetNSurf() << " Surfaces" << endl; + for (int i = 0; i < geom->GetNSurf(); i++) + (*testout) << i << ": " << *geom->GetSurface(i) << endl; + + return geom; + /* + do + { + scan.ReadNext(); + if (scan.GetToken() == TOK_STRING) + cout << "found string " << scan.GetStringValue() << endl; + else + cout << "token = " << int(scan.GetToken()) << endl; + } + while (scan.GetToken() != TOK_END); + */ + } + + +}; + diff --git a/libsrc/csg/csgparser.hpp b/libsrc/csg/csgparser.hpp new file mode 100644 index 00000000..dfbd24ac --- /dev/null +++ b/libsrc/csg/csgparser.hpp @@ -0,0 +1,101 @@ +#ifndef _CSGPARSER_HPP +#define _CSGPARSER_HPP + + +namespace netgen +{ + + enum TOKEN_TYPE + { + TOK_MINUS = '-', TOK_LP = '(', OK_RP = ')', TOK_LSP = '[', TOK_RSP = ']', + TOK_EQU = '=', TOK_COMMA = ',', TOK_SEMICOLON = ';', + TOK_NUM = 100, TOK_STRING, TOK_NAMED_SOLID, TOK_PRIMITIVE, + TOK_OR, TOK_AND, TOK_NOT, + TOK_SINGULAR, TOK_EDGE, TOK_POINT, TOK_FACE, TOK_IDENTIFY, TOK_CLOSESURFACES, + TOK_CLOSEEDGES, TOK_PERIODIC, + TOK_SOLID, TOK_RECO, TOK_TLO, TOK_CURVE2D, TOK_CURVE3D, TOK_BOUNDINGBOX, + TOK_BOUNDARYCONDITION, TOK_BOUNDARYCONDITIONNAME, + TOK_DEFINE, TOK_CONSTANT, + TOK_END }; + + struct kwstruct + { + TOKEN_TYPE kw; + const char * name; + }; + + enum PRIMITIVE_TYPE + { + TOK_SPHERE = 1, TOK_CYLINDER, TOK_PLANE, TOK_ELLIPTICCYLINDER, + TOK_ELLIPSOID, TOK_CONE, + TOK_ORTHOBRICK, TOK_POLYHEDRON, + TOK_TORUS, + TOK_TUBE, TOK_GENCYL, TOK_EXTRUSION, TOK_REVOLUTION, + + TOK_TRANSLATE, TOK_MULTITRANSLATE, TOK_ROTATE, TOK_MULTIROTATE + }; + + struct primstruct + { + PRIMITIVE_TYPE kw; + const char * name; + }; + + + class CSGScanner + { + TOKEN_TYPE token; + PRIMITIVE_TYPE prim_token; + double num_value; + string string_value; + + int linenum; + istream * scanin; + + public: + + CSGScanner (istream & ascanin); + + TOKEN_TYPE GetToken() const + { return token; } + + double GetNumValue() const + { return num_value; } + + const string & GetStringValue() const + { return string_value; } + + char GetCharValue() const + { return string_value[0]; } + + PRIMITIVE_TYPE GetPrimitiveToken() const + { return prim_token; } + + void ReadNext(); + + /* + CSGScanner & Parse (char ch); + CSGScanner & Parse (int & i); + CSGScanner & Parse (double & d); + CSGScanner & Parse (Point<3> & p); + CSGScanner & Parse (Vec<3> & p); + */ + void Error (const string & err); + }; + + + + CSGScanner & operator>> (CSGScanner & scan, char ch); + CSGScanner & operator>> (CSGScanner & scan, double & d); + CSGScanner & operator>> (CSGScanner & scan, int & i); + CSGScanner & operator>> (CSGScanner & scan, Point<3> & p); + CSGScanner & operator>> (CSGScanner & scan, Vec<3> & v); + + + +} + + + +#endif + diff --git a/libsrc/csg/csgpkg.cpp b/libsrc/csg/csgpkg.cpp new file mode 100644 index 00000000..589d12ff --- /dev/null +++ b/libsrc/csg/csgpkg.cpp @@ -0,0 +1,720 @@ +#include +#include +#include +#include + + +#include +#include + + +#include "vscsg.hpp" + + +extern "C" int Ng_CSG_Init (Tcl_Interp * interp); + + + +namespace netgen +{ + // extern DLL_HEADER NetgenGeometry * ng_geometry; + extern DLL_HEADER AutoPtr ng_geometry; + extern DLL_HEADER AutoPtr mesh; + + static VisualSceneGeometry vsgeom; + + char * err_needscsgeometry = (char*) "This operation needs an CSG geometry"; + extern char * err_needsmesh; + extern char * err_jobrunning; + + + + + int Ng_ParseGeometry (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * csgeom = dynamic_cast (ng_geometry.Ptr()); + if (csgeom) + { + double detail = atof (Tcl_GetVar (interp, "::geooptions.detail", 0)); + double facets = atof (Tcl_GetVar (interp, "::geooptions.facets", 0)); + + if (atoi (Tcl_GetVar (interp, "::geooptions.drawcsg", 0))) + csgeom->CalcTriangleApproximation(detail, facets); + } + return TCL_OK; + } + + + + + int Ng_GeometryOptions (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + + + const char * command = argv[1]; + + if (strcmp (command, "get") == 0) + { + if (geometry) + { + char buf[20]; + Point3d pmin = geometry->BoundingBox ().PMin(); + Point3d pmax = geometry->BoundingBox ().PMax(); + + sprintf (buf, "%5.1lf", pmin.X()); + Tcl_SetVar (interp, "::geooptions.minx", buf, 0); + sprintf (buf, "%5.1lf", pmin.Y()); + Tcl_SetVar (interp, "::geooptions.miny", buf, 0); + sprintf (buf, "%5.1lf", pmin.Z()); + Tcl_SetVar (interp, "::geooptions.minz", buf, 0); + + sprintf (buf, "%5.1lf", pmax.X()); + Tcl_SetVar (interp, "::geooptions.maxx", buf, 0); + sprintf (buf, "%5.1lf", pmax.Y()); + Tcl_SetVar (interp, "::geooptions.maxy", buf, 0); + sprintf (buf, "%5.1lf", pmax.Z()); + Tcl_SetVar (interp, "::geooptions.maxz", buf, 0); + } + } + else if (strcmp (command, "set") == 0) + { + Point<3> pmin (atof (Tcl_GetVar (interp, "::geooptions.minx", 0)), + atof (Tcl_GetVar (interp, "::geooptions.miny", 0)), + atof (Tcl_GetVar (interp, "::geooptions.minz", 0))); + Point<3> pmax (atof (Tcl_GetVar (interp, "::geooptions.maxx", 0)), + atof (Tcl_GetVar (interp, "::geooptions.maxy", 0)), + atof (Tcl_GetVar (interp, "::geooptions.maxz", 0))); + Box<3> box (pmin, pmax); + if (geometry) + geometry -> SetBoundingBox (box); + CSGeometry::SetDefaultBoundingBox (box); + } + + return TCL_OK; + } + + + + + + // attempt of a simple modeller + + int Ng_CreatePrimitive (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + tcl_const char * classname = argv[1]; + tcl_const char * name = argv[2]; + + cout << "Create primitive, class = " << classname + << ", name = " << name << endl; + + Primitive * nprim = Primitive::CreatePrimitive (classname); + Solid * nsol = new Solid (nprim); + + char sname[100]; + for (int j = 1; j <= nprim->GetNSurfaces(); j++) + { + sprintf (sname, "%s,%d", name, j); + geometry -> AddSurface (sname, &nprim->GetSurface(j)); + nprim -> SetSurfaceId (j, geometry->GetNSurf()); + } + + geometry->SetSolid (name, nsol); + + return TCL_OK; + } + + + int Ng_SetPrimitiveData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + tcl_const char * name = argv[1]; + tcl_const char * value = argv[2]; + + Array coeffs; + + + cout << "Set primitive data, name = " << name + << ", value = " << value << endl; + + + istringstream vst (value); + double val; + while (!vst.eof()) + { + vst >> val; + coeffs.Append (val); + } + + ((Primitive*) + geometry->GetSolid (name)->GetPrimitive())->SetPrimitiveData (coeffs); + + return TCL_OK; + } + + + + int Ng_SetSolidData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + tcl_const char * name = argv[1]; + tcl_const char * val = argv[2]; + + cout << "Set Solid Data, name = " << name + << ", value = " << val << endl; + + istringstream vst (val); + + Solid * nsol = Solid::CreateSolid (vst, geometry->GetSolids()); + geometry->SetSolid (name, nsol); + + return TCL_OK; + } + + + int Ng_GetPrimitiveData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + tcl_const char * name = argv[1]; + tcl_const char * classnamevar = argv[2]; + tcl_const char * valuevar = argv[3]; + + const char * classname; + + Array coeffs; + + geometry->GetSolid (name)->GetPrimitive()->GetPrimitiveData (classname, coeffs); + + ostringstream vst; + for (int i = 1; i <= coeffs.Size(); i++) + vst << coeffs.Get(i) << " "; + + cout << "GetPrimitiveData, name = " << name + << ", classnamevar = " << classnamevar + << ", classname = " << classname << endl + << " valuevar = " << valuevar + << ", values = " << vst.str() << endl; + + Tcl_SetVar (interp, classnamevar, (char*)classname, 0); + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + int Ng_GetSolidData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + tcl_const char * name = argv[1]; + tcl_const char * valuevar = argv[2]; + + ostringstream vst; + + const Solid * sol = geometry->GetSolid (name); + sol->GetSolidData (vst); + + cout << "GetSolidData, name = " << name << ", data = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + int Ng_GetPrimitiveList (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + tcl_const char * valuevar = argv[1]; + int i; + + stringstream vst; + + for (i = 1; i <= geometry->GetNSolids(); i++) + { + const Solid * sol = geometry->GetSolid(i); + if (sol->GetPrimitive()) + vst << sol->Name() << " "; + } + + cout << "primnames = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + + int Ng_GetSurfaceList (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + tcl_const char * valuevar = argv[1]; + int i; + + stringstream vst; + + for (i = 1; i <= geometry->GetNSurf(); i++) + { + const Surface * surf = geometry->GetSurface(i); + vst << surf->Name() << " "; + } + + cout << "surfnames = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + int Ng_GetSolidList (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + tcl_const char * valuevar = argv[1]; + int i; + + stringstream vst; + + for (i = 1; i <= geometry->GetNSolids(); i++) + { + const Solid * sol = geometry->GetSolid(i); + if (!sol->GetPrimitive()) + vst << sol->Name() << " "; + } + + cout << "solnames = " << vst.str() << endl; + + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + + return TCL_OK; + } + + + int Ng_TopLevel (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + int i; + /* + for (i = 0; i < argc; i++) + cout << argv[i] << ", "; + cout << endl; + */ + + if (strcmp (argv[1], "getlist") == 0) + { + stringstream vst; + + for (i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + const Solid * sol; + const Surface * surf; + geometry->GetTopLevelObject (i, sol, surf); + + if (!surf) + vst << "{ " << sol->Name() << " } "; + else + vst << "{ " << sol->Name() << " " << surf->Name() << " } "; + } + + tcl_const char * valuevar = argv[2]; + Tcl_SetVar (interp, valuevar, (char*)vst.str().c_str(), 0); + } + + if (strcmp (argv[1], "set") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + geometry->SetTopLevelObject (sol, surf); + } + + if (strcmp (argv[1], "remove") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + geometry->RemoveTopLevelObject (sol, surf); + } + + if (strcmp (argv[1], "setprop") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + tcl_const char * propvar = argv[4]; + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + TopLevelObject * tlo = geometry->GetTopLevelObject (sol, surf); + + if (!tlo) return TCL_OK; + + char varname[50]; + sprintf (varname, "%s(red)", propvar); + double red = atof (Tcl_GetVar (interp, varname, 0)); + sprintf (varname, "%s(blue)", propvar); + double blue = atof (Tcl_GetVar (interp, varname, 0)); + sprintf (varname, "%s(green)", propvar); + double green = atof (Tcl_GetVar (interp, varname, 0)); + tlo -> SetRGB (red, green, blue); + + sprintf (varname, "%s(visible)", propvar); + tlo -> SetVisible (bool(atoi (Tcl_GetVar (interp, varname, 0)))); + sprintf (varname, "%s(transp)", propvar); + tlo -> SetTransparent (bool(atoi (Tcl_GetVar (interp, varname, 0)))); + } + + if (strcmp (argv[1], "getprop") == 0) + { + tcl_const char * solname = argv[2]; + tcl_const char * surfname = argv[3]; + tcl_const char * propvar = argv[4]; + + Solid * sol = (Solid*)geometry->GetSolid (solname); + Surface * surf = (Surface*)geometry->GetSurface (surfname); + TopLevelObject * tlo = geometry->GetTopLevelObject (sol, surf); + + if (!tlo) return TCL_OK; + + char varname[50], varval[10]; + + sprintf (varname, "%s(red)", propvar); + sprintf (varval, "%lf", tlo->GetRed()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(green)", propvar); + sprintf (varval, "%lf", tlo->GetGreen()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(blue)", propvar); + sprintf (varval, "%lf", tlo->GetBlue()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(visible)", propvar); + sprintf (varval, "%d", tlo->GetVisible()); + Tcl_SetVar (interp, varname, varval, 0); + + sprintf (varname, "%s(transp)", propvar); + sprintf (varval, "%d", tlo->GetTransparent()); + Tcl_SetVar (interp, varname, varval, 0); + } + + + return TCL_OK; + } + + + + + int Ng_SingularEdgeMS (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + double globh = mparam.maxh; + for (int i = 1; i <= geometry->singedges.Size(); i++) + geometry->singedges.Get(i)->SetMeshSize (*mesh, globh); + return TCL_OK; + } + + + int Ng_SingularPointMS (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (!geometry) + { + Tcl_SetResult (interp, err_needscsgeometry, TCL_STATIC); + return TCL_ERROR; + } + + double globh = mparam.maxh; + for (int i = 1; i <= geometry->singpoints.Size(); i++) + geometry->singpoints.Get(i)->SetMeshSize (*mesh, globh); + return TCL_OK; + } + + + + int Ng_SelectSurface (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int surfnr = atoi (argv[1]); + vsgeom.SelectSurface (surfnr); + return TCL_OK; + } + + + /* + class CSGeometryRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const; + virtual NetgenGeometry * LoadFromMeshFile (istream & ist) const; + virtual VisualScene * GetVisualScene (const NetgenGeometry * geom) const; + }; + + extern CSGeometry * ParseCSG (istream & istr); + + NetgenGeometry * CSGeometryRegister :: Load (string filename) const + { + const char * cfilename = filename.c_str(); + if (strcmp (&cfilename[strlen(cfilename)-3], "geo") == 0) + { + PrintMessage (1, "Load CSG geometry file ", cfilename); + + ifstream infile(cfilename); + + CSGeometry * hgeom = ParseCSG (infile); + if (!hgeom) + throw NgException ("geo-file should start with 'algebraic3d'"); + + hgeom -> FindIdenticSurfaces(1e-8 * hgeom->MaxSize()); + return hgeom; + } + + if (strcmp (&cfilename[strlen(cfilename)-3], "ngg") == 0) + { + PrintMessage (1, "Load new CSG geometry file ", cfilename); + + ifstream infile(cfilename); + CSGeometry * hgeom = new CSGeometry(""); + hgeom -> Load (infile); + + return hgeom; + } + + + + return NULL; + } + + NetgenGeometry * CSGeometryRegister :: LoadFromMeshFile (istream & ist) const + { + string auxstring; + if (ist.good()) + { + ist >> auxstring; + if (auxstring == "csgsurfaces") + { + CSGeometry * geometry = new CSGeometry (""); + geometry -> LoadSurfaces(ist); + return geometry; + } + // else + // ist.putback (auxstring); + } + return NULL; + } + + VisualScene * CSGeometryRegister :: GetVisualScene (const NetgenGeometry * geom) const + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (geometry) + { + vsgeom.SetGeometry (geometry); + return &vsgeom; + } + return NULL; + } + */ + + + + class CSGeometryVisRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const { return NULL; } + virtual VisualScene * GetVisualScene (const NetgenGeometry * geom) const; + }; + + VisualScene * CSGeometryVisRegister :: GetVisualScene (const NetgenGeometry * geom) const + { + const CSGeometry * geometry = dynamic_cast (geom); + if (geometry) + { + vsgeom.SetGeometry (const_cast(geometry)); + return &vsgeom; + } + return NULL; + } +} + + +using namespace netgen; + +int Ng_CSG_Init (Tcl_Interp * interp) +{ + geometryregister.Append (new CSGeometryVisRegister); + if (interp == NULL) return TCL_OK; + + + Tcl_CreateCommand (interp, "Ng_ParseGeometry", Ng_ParseGeometry, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + // geometry + Tcl_CreateCommand (interp, "Ng_CreatePrimitive", Ng_CreatePrimitive, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetPrimitiveData", Ng_SetPrimitiveData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetPrimitiveData", Ng_GetPrimitiveData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetPrimitiveList", Ng_GetPrimitiveList, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_GetSurfaceList", Ng_GetSurfaceList, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + + Tcl_CreateCommand (interp, "Ng_SetSolidData", Ng_SetSolidData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetSolidData", Ng_GetSolidData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetSolidList", Ng_GetSolidList, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_TopLevel", Ng_TopLevel, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GeometryOptions", Ng_GeometryOptions, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SingularEdgeMS", Ng_SingularEdgeMS, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SingularPointMS", Ng_SingularPointMS, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SelectSurface", Ng_SelectSurface, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + return TCL_OK; +} + + + diff --git a/libsrc/csg/curve2d.cpp b/libsrc/csg/curve2d.cpp new file mode 100644 index 00000000..7091e87a --- /dev/null +++ b/libsrc/csg/curve2d.cpp @@ -0,0 +1,78 @@ +#include + +#include +#include + +namespace netgen +{ +CircleCurve2d :: CircleCurve2d (const Point<2> & acenter, double arad) + { + center = acenter; + rad = arad; + } + +void CircleCurve2d :: Project (Point<2> & p) const + { + Vec<2> v = p - center; + v *= rad/v.Length(); + p = center + v; + } + +void CircleCurve2d :: NormalVector (const Point<2> & p, Vec<2> & n) const + { + n = p - center; + n /= n.Length(); + } + + + + + + +QuadraticCurve2d :: QuadraticCurve2d () +{ + cxx = cyy = cxy = cx = cy = c = 0; +} + +void QuadraticCurve2d :: Read (istream & ist) +{ + ist >> cxx >> cyy >> cxy >> cx >> cy >> c; +} + + +void QuadraticCurve2d :: Project (Point<2> & p) const +{ + double f, x, y, gradx, grady, grad2; + int its = 0; + + x = p(0); + y = p(1); + + do + { + f = cxx * x * x + cyy * y * y + cxy * x * y + cx * x + cy * y + c; + gradx = 2 * cxx * x + cxy * y + cx; + grady = 2 * cyy * y + cxy * x + cy; + grad2 = gradx * gradx + grady * grady; + + x -= f * gradx / grad2; + y -= f * grady / grad2; + + // (*mycout) << "x = " << x << " y = " << y << " f = " << f << endl; + its++; + } + while (fabs (f) > 1e-8 && its < 20); + if (its >= 20) + cerr << "QuadraticCurve2d::Project: many iterations, f = " << f << endl; + p(0) = x; + p(1) = y; +} + + +void QuadraticCurve2d :: NormalVector (const Point<2> & p, Vec<2> & n) const +{ + n(0) = 2 * cxx * p(0) + cxy * p(1) + cx; + n(1) = 2 * cyy * p(1) + cxy * p(0) + cy; + n.Normalize(); +} +} diff --git a/libsrc/csg/curve2d.hpp b/libsrc/csg/curve2d.hpp new file mode 100644 index 00000000..066a40ad --- /dev/null +++ b/libsrc/csg/curve2d.hpp @@ -0,0 +1,67 @@ +#ifndef FILE_CURVE2D +#define FILE_CURVE2D + +/**************************************************************************/ +/* File: curve2d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 24. Jul. 96 */ +/**************************************************************************/ + +namespace netgen +{ + + + /* + + 2D Curve repesentation + + */ + + + + /// + class Curve2d : public Manifold + { + public: + /// + virtual void Project (Point<2> & p) const = 0; + /// + virtual void NormalVector (const Point<2> & p, Vec<2> & n) const = 0; + }; + + /// + class CircleCurve2d : public Curve2d + { + /// + Point<2> center; + /// + double rad; + public: + /// + CircleCurve2d (const Point<2> & acenter, double arad); + /// + virtual void Project (Point<2> & p) const; + /// + virtual void NormalVector (const Point<2> & p, Vec<2> & n) const; + }; + + /// + class QuadraticCurve2d : public Curve2d + { + /// + double cxx, cyy, cxy, cx, cy, c; + public: + /// + QuadraticCurve2d (); + /// + void Read (istream & ist); + /// + virtual void Project (Point<2> & p) const; + /// + virtual void NormalVector (const Point<2> & p, Vec<2> & n) const; + }; + + +} + +#endif diff --git a/libsrc/csg/edgeflw.cpp b/libsrc/csg/edgeflw.cpp new file mode 100644 index 00000000..edb943f3 --- /dev/null +++ b/libsrc/csg/edgeflw.cpp @@ -0,0 +1,1834 @@ +#include +#include +#include + +// #undef DEVELOP +// #define DEVELOP + +namespace netgen +{ + + EdgeCalculation :: + EdgeCalculation (const CSGeometry & ageometry, + Array & aspecpoints) + : geometry(ageometry), specpoints(aspecpoints) + { + Box<3> bbox = geometry.BoundingBox(); + + searchtree = new Point3dTree (bbox.PMin(), bbox.PMax()); + meshpoint_tree = new Point3dTree (bbox.PMin(), bbox.PMax()); + + for (int i = 0; i < specpoints.Size(); i++) + searchtree->Insert (specpoints[i].p, i); + + ideps = 1e-9; + } + + EdgeCalculation :: ~EdgeCalculation() + { + delete searchtree; + delete meshpoint_tree; + } + + + void EdgeCalculation :: Calc(double h, Mesh & mesh) + { + static int timer = NgProfiler::CreateTimer ("CSG: mesh edges"); + NgProfiler::RegionTimer reg (timer); + + + PrintMessage (1, "Find edges"); + PushStatus ("Find edges"); + + for (int i = 1; i <= mesh.GetNP(); i++) + meshpoint_tree->Insert (mesh.Point(i), i); + + + // add all special points before edge points (important for periodic identification) + // JS, Jan 2007 + const double di=1e-7*geometry.MaxSize(); + Array locsearch; + + for (int i = 0; i < specpoints.Size(); i++) + if (specpoints[i].unconditional) + { + Point<3> p = specpoints[i].p; + meshpoint_tree -> GetIntersecting (p-Vec<3> (di,di,di), + p+Vec<3> (di,di,di), locsearch); + + if (locsearch.Size() == 0) + { + PointIndex pi = mesh.AddPoint (p, specpoints[i].GetLayer(), FIXEDPOINT); + meshpoint_tree -> Insert (p, pi); + } + } + + /* + // slow version + for (int i = 0; i < specpoints.Size(); i++) + if (specpoints[i].unconditional) + { + Point<3> p = specpoints[i].p; + bool found = false; + for (int j = 1; j <= mesh.GetNP(); j++) + if (Dist (p, mesh.Point(j)) < 1e-8) + found = true; + if (!found) + mesh.AddPoint (p, specpoints[i].GetLayer(), FIXEDPOINT); + } + */ + + + + CalcEdges1 (h, mesh); + SplitEqualOneSegEdges (mesh); + FindClosedSurfaces (h, mesh); + PrintMessage (3, cntedge, " edges found"); + + PopStatus (); + } + + + + + + void EdgeCalculation :: CalcEdges1 (double h, Mesh & mesh) + { + Array hsp(specpoints.Size()); + Array glob2hsp(specpoints.Size()); + Array startpoints, endpoints; + + + int pos, ep; + int layer; + + Point<3> p, np; + int pi1, s1, s2, s1_orig, s2_orig; + + Array > edgepoints; + Array curvelength; + int copyedge = 0, copyfromedge = -1, copyedgeidentification = -1; + + Array locsurfind, locind; + + int checkedcopy = 0; + + // double size = geometry.MaxSize(); + // double epspointdist2 = sqr (size) * 1e-12; + + + // copy special points to work with + for (int i = 0; i < specpoints.Size(); i++) + { + hsp[i] = i; + glob2hsp[i] = i; + } + + //for(int i=0; i identification_used(100); // identification i already used for startpoint j + + mesh.GetIdentifications().Delete(); + + TABLE specpoint2surface(specpoints.Size()); + if (geometry.identifications.Size()) + { + for (int i = 0; i < specpoints.Size(); i++) + for (int j = 0; j < geometry.GetNSurf(); j++) + if (geometry.GetSurface(j)->PointOnSurface (specpoints[i].p)) + specpoint2surface.Add (i, j); + } + + TABLE specpoint2tlo(specpoints.Size()); + if (geometry.identifications.Size()) + { + for (int i = 0; i < specpoints.Size(); i++) + for (int j = 0; j < geometry.GetNTopLevelObjects(); j++) + { + const TopLevelObject * tlo = geometry.GetTopLevelObject (j); + if (tlo->GetSolid() && tlo->GetSolid()->VectorIn (specpoints[i].p,specpoints[i].v)) + //if (tlo->GetSolid() && tlo->GetSolid()->IsIn (specpoints[i].p)) + { +#ifdef DEVELOP + (*testout) << "point " << specpoints[i].p << " v " <GetSolid()->Name() << endl; +#endif + specpoint2tlo.Add (i, j); + } + } + } + + for (int i = 0; i < specpoints.Size(); i++) + specpoints[i].nr = i; + + while (hsp.Size()) + { + SetThreadPercent(100 - 100 * double (hsp.Size()) / specpoints.Size()); + +#ifdef DEVELOP + (*testout) << "hsp.Size() " << hsp.Size() << " specpoints.Size() " << specpoints.Size() << endl; + (*testout) << endl << "edge nr " << cntedge+1 << endl; +#endif + + edgepoints.SetSize (0); + curvelength.SetSize (0); + + + pi1 = 0; + copyedge = 0; + // identifyable point available ? + + + for (int i = 0; i < geometry.identifications.Size() && !pi1; i++) + for (int j = checkedcopy; j < startpoints.Size() && !pi1; j++) + { +#ifdef DEVELOP + (*testout) << "checking point " << specpoints[startpoints[j]].p + << ", v = " << specpoints[startpoints[j]].v + << " for copying (i,j = " << i << ", " << j << ")" << endl; +#endif + if (geometry.identifications[i]->IdentifyableCandidate (specpoints[startpoints[j]]) && + geometry.identifications[i]->IdentifyableCandidate (specpoints[endpoints[j]])) + + + { + int pi1cand = 0; + double mindist = 1e10; + + for (int k = 0; k < hsp.Size() && !pi1; k++) + { + //(*testout) << " ? identifyable with " << specpoints[hsp[k]].p + //<< ", v = " << specpoints[hsp[k]].v + // << endl; + if (identification_used.Used (INDEX_2(i, startpoints[j])) || + identification_used.Used (INDEX_2(i, hsp[k]))) + { + //(*testout) << "failed at pos0" << endl; + continue; + } + + if (geometry.identifications[i] + ->Identifyable(specpoints[startpoints[j]], specpoints[hsp[k]], specpoint2tlo, specpoint2surface) || + geometry.identifications[i] + ->Identifyable(specpoints[hsp[k]], specpoints[startpoints[j]], specpoint2tlo, specpoint2surface)) + { +#ifdef DEVELOP + (*testout) << "identifyable: " << specpoints[hsp[k]].p << ", v = " << specpoints[hsp[k]].v + << " and " << specpoints[startpoints[j]].p << ", v = " << specpoints[startpoints[j]].v + << " (identification " << i+1 << ")" << endl; +#endif + + if (Dist (specpoints[startpoints[j]].p, specpoints[hsp[k]].p) < mindist) + { + mindist = Dist (specpoints[startpoints[j]].p, specpoints[hsp[k]].p); + pi1cand = k+1; + } + } + } + + + if (pi1cand) + { + pi1 = pi1cand; + copyedge = 1; + copyfromedge = j+1; + copyedgeidentification = i+1; + + identification_used.Set (INDEX_2(i, startpoints[j]), 1); + identification_used.Set (INDEX_2(i, hsp.Get(pi1)), 1); + } + } + } + + + // cannot copy from other ege ? + if (!pi1) + checkedcopy = startpoints.Size(); + + // unconditional special point available ? + if (!pi1) + for (int i = 1; i <= hsp.Size(); i++) + if (specpoints[hsp.Get(i)].unconditional == 1) + { + pi1 = i; + break; + } + + + if (!pi1) + { + // no unconditional points available, choose first conitional + pi1 = 1; + } + + layer = specpoints[hsp.Get(pi1)].GetLayer(); + + + if (!specpoints[hsp.Get(pi1)].unconditional) + { + specpoints[hsp.Elem(pi1)].unconditional = 1; + for (int i = 1; i <= hsp.Size(); i++) + if (i != pi1 && + Dist (specpoints[hsp.Get(pi1)].p, specpoints[hsp.Get(i)].p) < 1e-8*geometry.MaxSize() && + (specpoints[hsp.Get(pi1)].v + specpoints[hsp.Get(i)].v).Length() < 1e-4) + { + // opposite direction + specpoints[hsp.Elem(i)].unconditional = 1; + } + } + + cntedge++; + startpoints.Append (hsp.Get(pi1)); + +#ifdef DEVELOP + (*testout) << "start followedge: p1 = " << specpoints[hsp.Get(pi1)].p + << ", v = " << specpoints[hsp.Get(pi1)].v << endl; +#endif + + FollowEdge (pi1, ep, pos, hsp, h, mesh, + edgepoints, curvelength); + + + if (multithread.terminate) + return; + + if (!ep) + { + // ignore starting point + hsp.DeleteElement (pi1); + cout << "yes, this happens" << endl; + continue; + } + + + + endpoints.Append (hsp.Get(ep)); + + + double elen = 0; + for (int i = 1; i <= edgepoints.Size()-1; i++) + elen += Dist (edgepoints.Get(i), edgepoints.Get(i+1)); + + + int shortedge = 0; + for (int i = 1; i <= geometry.identifications.Size(); i++) + if (geometry.identifications.Get(i)->ShortEdge(specpoints[hsp.Get(pi1)], specpoints[hsp.Get(ep)])) + shortedge = 1; + // (*testout) << "shortedge = " << shortedge << endl; + + + if (!shortedge) + { + mesh.RestrictLocalHLine (Point3d (specpoints[hsp.Get(pi1)].p), + Point3d (specpoints[hsp.Get(ep)].p), + elen / mparam.segmentsperedge); + } + + s1 = specpoints[hsp.Get(pi1)].s1; + s2 = specpoints[hsp.Get(pi1)].s2; + s1_orig = specpoints[hsp.Get(pi1)].s1_orig; + s2_orig = specpoints[hsp.Get(pi1)].s2_orig; + + + // delete initial, terminal and conditional points + +#ifdef DEVELOP + (*testout) << "terminal point: p = " << specpoints[hsp.Get(ep)].p + << ", v = " << specpoints[hsp.Get(ep)].v << endl; +#endif + + searchtree -> DeleteElement (hsp.Get(ep)); + searchtree -> DeleteElement (hsp.Get(pi1)); + + if (ep > pi1) + { + glob2hsp[hsp[ep-1]] = -1; + glob2hsp[hsp.Last()] = ep-1; + hsp.DeleteElement (ep); + + glob2hsp[hsp[pi1-1]] = -1; + glob2hsp[hsp.Last()] = pi1-1; + hsp.DeleteElement (pi1); + } + else + { + glob2hsp[hsp[pi1-1]] = -1; + glob2hsp[hsp.Last()] = pi1-1; + hsp.DeleteElement (pi1); + + glob2hsp[hsp[ep-1]] = -1; + glob2hsp[hsp.Last()] = ep-1; + hsp.DeleteElement (ep); + } + + + for (int j = 1; j <= edgepoints.Size()-1; j++) + { + p = edgepoints.Get(j); + np = Center (p, edgepoints.Get(j+1)); + double hd = Dist (p, np); + + + Box<3> boxp (np - (1.2 * hd) * Vec<3> (1, 1, 1), + np + (1.2 * hd) * Vec<3> (1, 1, 1)); + searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind); + + for (int i = 0; i < locind.Size(); i++) + { + if ( specpoints[locind[i]].HasSurfaces (s1, s2) && + specpoints[locind[i]].unconditional == 0) + { + searchtree -> DeleteElement (locind[i]); + + int li = glob2hsp[locind[i]]; + glob2hsp[locind[i]] = -1; + glob2hsp[hsp.Last()] = li; + hsp.Delete (li); + } + } + + + /* + for (int i = 1; i <= hsp.Size(); i++) + if ( specpoints[hsp.Get(i)].HasSurfaces (s1, s2) && + specpoints[hsp.Get(i)].unconditional == 0 && + Dist2 (np, specpoints[hsp.Get(i)].p) < 1.2 * hd) + { + searchtree -> DeleteElement (hsp.Get(i)+1); + hsp.DeleteElement (i); + i--; + } + */ + } + + + Array refedges; + Array refedgesinv; + + + AnalyzeEdge (s1_orig, s2_orig, s1, s2, pos, layer, + edgepoints, + refedges, refedgesinv); + + + for (int i = 0; i < refedges.Size(); i++) + refedges[i].edgenr = cntedge; + + +#ifdef DEVELOP + (*testout) << "edge " << cntedge << endl + << "startp: " << specpoints[startpoints.Last()].p + << ", v = " << specpoints[startpoints.Last()].v << endl + << "copy = " << copyedge << endl + << refedges.Size() << " refedges: "; + for (int i = 1; i <= refedges.Size(); i++) + (*testout) << " " << refedges.Get(i).si; + (*testout) << endl; + if (refedgesinv.Size()) + (*testout) << "inv[1] = " << refedgesinv.Get(1) << endl; +#endif + + if (refedges.Size() == 0) + throw NgException ("Problem in edge detection"); + + + if (!copyedge) + { + // (*testout) << "store edge" << endl; + // int oldnseg = mesh.GetNSeg(); + + if (!shortedge) + StoreEdge (refedges, refedgesinv, + edgepoints, curvelength, layer, mesh); + else + StoreShortEdge (refedges, refedgesinv, + edgepoints, curvelength, layer, mesh); + + + for(int i = 0; i < refedges.Size(); i++) + { + refedges[i].surfnr1 = geometry.GetSurfaceClassRepresentant(refedges[i].surfnr1); + refedges[i].surfnr2 = geometry.GetSurfaceClassRepresentant(refedges[i].surfnr2); + } + + + /* + for (int i = oldnseg+1; i <= mesh.GetNSeg(); i++) + for (int j = 1; j <= oldnseg; j++) + { + const Point<3> & l1p1 = mesh.Point (mesh.LineSegment(i).p1); + const Point<3> & l1p2 = mesh.Point (mesh.LineSegment(i).p2); + const Point<3> & l2p1 = mesh.Point (mesh.LineSegment(j).p1); + const Point<3> & l2p2 = mesh.Point (mesh.LineSegment(j).p2); + Vec<3> vl1(l1p1, l1p2); + for (double lamk = 0; lamk <= 1; lamk += 0.1) + { + Point<3> l2p = l1p1 + lamk * vl1; + double dist = sqrt (MinDistLP2 (l2p1, l2p2, l2p)); + if (dist > 1e-12) + mesh.RestrictLocalH (l2p, 3*dist); + } + } + */ + } + else + { + CopyEdge (refedges, refedgesinv, + copyfromedge, + specpoints[startpoints.Get(copyfromedge)].p, + specpoints[endpoints.Get(copyfromedge)].p, + edgepoints.Get(1), edgepoints.Last(), + copyedgeidentification, + layer, + mesh); + } + + + /* + // not available ... + for (int i = 0; i < refedges.Size(); i++) + { + EdgeDescriptor ed; + ed.SetSurfNr(0, refedges[i].surfnr1); + ed.SetSurfNr(1, refedges[i].surfnr2); + int hnr = mesh.AddEdgeDescriptor(ed); + if (hnr != refedges[i].edgenr) + { + cerr << "edgedescriptor index wrong: new : " << hnr << " old = " << refedges[i].edgenr << endl; + } + } + */ + + + +// for(int i=0; i osedges(cntedge); + INDEX_2_HASHTABLE osedgesht (cntedge+1); + + osedges = 2; + + // count segments on edges + for (si = 0; si < mesh.GetNSeg(); si++) + { + const Segment & seg = mesh[si]; + if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) + osedges.Elem(seg.edgenr)--; + } + + // flag one segment edges + for (int i = 0; i < cntedge; i++) + osedges[i] = (osedges[i] > 0) ? 1 : 0; + + for (si = 0; si < mesh.GetNSeg(); si++) + { + const Segment & seg = mesh[si]; + if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) + { + if (osedges.Get(seg.edgenr)) + { + INDEX_2 i2(seg[0], seg[1]); + i2.Sort (); + if (osedgesht.Used (i2)) + osedgesht.Set (i2, 2); + else + osedgesht.Set (i2, 1); + } + } + } + + + // one edge 1 segment, other 2 segments + // yes, it happens ! + point_on_edge_problem = 0; + for (int i = 1; i <= osedgesht.GetNBags(); i++) + for (int j = 1; j <= osedgesht.GetBagSize(i); j++) + { + INDEX_2 i2; + int val; + osedgesht.GetData (i, j, i2, val); + + const Point<3> & p1 = mesh[PointIndex(i2.I1())]; + const Point<3> & p2 = mesh[PointIndex(i2.I2())]; + Vec<3> v = p2 - p1; + double vlen = v.Length(); + v /= vlen; + for (pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + + if (pi != i2.I1() && pi != i2.I2()) + { + const Point<3> & p = mesh[pi]; + Vec<3> v2 = p - p1; + double lam = (v2 * v); + if (lam > 0 && lam < vlen) + { + Point<3> hp = p1 + lam * v; + if (Dist (p, hp) < 1e-4 * vlen) + { + PrintWarning ("Point on edge !!!"); + cout << "seg: " << i2 << ", p = " << pi << endl; + osedgesht.Set (i2, 2); + point_on_edge_problem = 1; + + (*testout) << "Point on edge" << endl + << "seg = " << i2 << ", p = " << pi << endl + << "pos = " << p << ", projected = " << hp << endl + << "seg is = " << mesh.Point(i2.I1()) << " - " << mesh.Point(i2.I2()) << endl; + } + } + } + } + + + // insert new points + osedges = -1; + + int nseg = mesh.GetNSeg(); + for (si = 0; si < nseg; si++) + { + const Segment & seg = mesh[si]; + if (seg.seginfo && seg.edgenr >= 1 && seg.edgenr <= cntedge) + { + INDEX_2 i2(seg[0], seg[1]); + i2.Sort (); + if (osedgesht.Used (i2) && + osedgesht.Get (i2) == 2 && + osedges.Elem(seg.edgenr) == -1) + { + Point<3> newp = Center (mesh[PointIndex(seg[0])], + mesh[PointIndex(seg[1])]); + + ProjectToEdge (geometry.GetSurface(seg.surfnr1), + geometry.GetSurface(seg.surfnr2), + newp); + + osedges.Elem(seg.edgenr) = + mesh.AddPoint (newp, mesh[PointIndex(seg[0])].GetLayer(), EDGEPOINT); + meshpoint_tree -> Insert (newp, osedges.Elem(seg.edgenr)); + } + } + } + + + for (int i = 1; i <= nseg; i++) + { + Segment & seg = mesh.LineSegment (i); + if (seg.edgenr >= 1 && seg.edgenr <= cntedge) + { + if (osedges.Get(seg.edgenr) != -1) + { + Segment newseg = seg; + newseg[0] = osedges.Get(seg.edgenr); + seg[1] = osedges.Get(seg.edgenr); + mesh.AddSegment (newseg); + } + } + } + + } + + + + void EdgeCalculation :: + FollowEdge (int pi1, int & ep, int & pos, + const Array & hsp, + double h, const Mesh & mesh, + Array > & edgepoints, + Array & curvelength) + { + int s1, s2, s1_rep, s2_rep; + double len, steplen, cursteplen, loch; + Point<3> p, np, pnp; + Vec<3> a1, a2, t; + + Array locind; + + double size = geometry.MaxSize(); + double epspointdist2 = size * 1e-6; + epspointdist2 = sqr (epspointdist2); + int uselocalh = mparam.uselocalh; + + + s1_rep = specpoints[hsp.Get(pi1)].s1; + s2_rep = specpoints[hsp.Get(pi1)].s2; + s1 = specpoints[hsp.Get(pi1)].s1_orig; + s2 = specpoints[hsp.Get(pi1)].s2_orig; + + p = specpoints[hsp.Get(pi1)].p; + //ProjectToEdge (geometry.GetSurface(s1), + // geometry.GetSurface(s2), p); + geometry.GetSurface(s1) -> CalcGradient (p, a1); + geometry.GetSurface(s2) -> CalcGradient (p, a2); + + t = Cross (a1, a2); + t.Normalize(); + + pos = (specpoints[hsp.Get(pi1)].v * t) > 0; + if (!pos) t *= -1; + + + edgepoints.Append (p); + curvelength.Append (0); + len = 0; + + // (*testout) << "geometry.GetSurface(s1) -> LocH (p, 3, 1, h) " << geometry.GetSurface(s1) -> LocH (p, 3, 1, h) + // << " geometry.GetSurface(s2) -> LocH (p, 3, 1, h) " << geometry.GetSurface(s2) -> LocH (p, 3, 1, h) << endl; + + loch = min2 (geometry.GetSurface(s1) -> LocH (p, 3, 1, h), + geometry.GetSurface(s2) -> LocH (p, 3, 1, h)); + + + + if (uselocalh) + { + double lh = mesh.GetH(p); + // (*testout) << "lh " << lh << endl; + if (lh < loch) + loch = lh; + } + + steplen = 0.1 * loch; + + do + { + if (multithread.terminate) + return; + + if (fabs (p(0)) + fabs (p(1)) + fabs (p(2)) > 100000*size) + { + ep = 0; + PrintWarning ("Give up line"); + break; + } + + if (steplen > 0.1 * loch) steplen = 0.1 * loch; + + steplen *= 2; + do + { + steplen *= 0.5; + np = p + steplen * t; + pnp = np; + ProjectToEdge (geometry.GetSurface(s1), + geometry.GetSurface(s2), pnp); + } + while (Dist (np, pnp) > 0.1 * steplen); + + + cursteplen = steplen; + if (Dist (np, pnp) < 0.01 * steplen) steplen *= 2; + + + np = pnp; + ep = 0; + + double hvtmin = 1.5 * cursteplen; + + Box<3> boxp (p - (2 * cursteplen) * Vec<3> (1, 1, 1), + p + (2 * cursteplen) * Vec<3> (1, 1, 1)); + + searchtree -> GetIntersecting (boxp.PMin(), boxp.PMax(), locind); + + for (int i = 0; i < locind.Size(); i++) + { + Vec<3> hv = specpoints[locind[i]].p - p; + if (hv.Length2() > 9 * cursteplen * cursteplen) + continue; + + double hvt = hv * t; + hv -= hvt * t; + + if (hv.Length() < 0.2 * cursteplen && + hvt > 0 && + // hvt < 1.5 * cursteplen && + hvt < hvtmin && + specpoints[locind[i]].unconditional == 1 && + (specpoints[locind[i]].v + t).Length() < 0.4 ) + { + Point<3> hep = specpoints[locind[i]].p; + ProjectToEdge (geometry.GetSurface(s1), + geometry.GetSurface(s2), hep); + + + if (Dist2 (hep, specpoints[locind[i]].p) < epspointdist2 ) + { + geometry.GetSurface(s1) -> CalcGradient (hep, a1); + geometry.GetSurface(s2) -> CalcGradient (hep, a2); + Vec<3> ept = Cross (a1, a2); + ept /= ept.Length(); + if (!pos) ept *= -1; + + if ( (specpoints[locind[i]].v + ept).Length() < 1e-4 ) + { + np = specpoints[locind[i]].p; + + for (int jj = 0; jj < hsp.Size(); jj++) + if (hsp[jj] == locind[i]) + ep = jj+1; + + if (!ep) + cerr << "endpoint not found" << endl; + // ep = i; + hvtmin = hvt; + // break; + } + } + } + } + + + + + /* + for (int i = 1; i <= hsp.Size(); i++) + { + if (!boxp.IsIn (specpoints[hsp.Get(i)].p)) + continue; + + Vec<3> hv = specpoints[hsp.Get(i)].p - p; + if (hv.Length2() > 9 * cursteplen * cursteplen) + continue; + + double hvt = hv * t; + hv -= hvt * t; + + if (hv.Length() < 0.2 * cursteplen && + hvt > 0 && + // hvt < 1.5 * cursteplen && + hvt < hvtmin && + specpoints[hsp.Get(i)].unconditional == 1 && + (specpoints[hsp.Get(i)].v + t).Length() < 0.4 ) + { + Point<3> hep = specpoints[hsp.Get(i)].p; + ProjectToEdge (geometry.GetSurface(s1), + geometry.GetSurface(s2), hep); + + + if (Dist2 (hep, specpoints[hsp.Get(i)].p) < epspointdist2 ) + { + geometry.GetSurface(s1) -> CalcGradient (hep, a1); + geometry.GetSurface(s2) -> CalcGradient (hep, a2); + Vec<3> ept = Cross (a1, a2); + ept /= ept.Length(); + if (!pos) ept *= -1; + + if ( (specpoints[hsp.Get(i)].v + ept).Length() < 1e-4 ) + { + np = specpoints[hsp.Get(i)].p; + ep = i; + hvtmin = hvt; + // break; + } + } + } + } + */ + + loch = min2 (geometry.GetSurface(s1_rep) -> LocH (np, 3, 1, h), + geometry.GetSurface(s2_rep) -> LocH (np, 3, 1, h)); + loch = max2 (loch, mparam.minh); + + if (uselocalh) + { + double lh = mesh.GetH(np); + if (lh < loch) + loch = lh; + } + + + len += Dist (p, np) / loch; + edgepoints.Append (np); + curvelength.Append (len); + + p = np; + + geometry.GetSurface(s1) -> CalcGradient (p, a1); + geometry.GetSurface(s2) -> CalcGradient (p, a2); + t = Cross (a1, a2); + t.Normalize(); + if (!pos) t *= -1; + } + while (! ep); + } + + + + + + + + void EdgeCalculation :: + AnalyzeEdge (int s1, int s2, int s1_rep, int s2_rep, int pos, int layer, + const Array > & edgepoints, + Array & refedges, + Array & refedgesinv) + { + Segment seg; + Array locsurfind, locsurfind2; + + Array edges_priority; + + double size = geometry.MaxSize(); + bool debug = 0; + +#ifdef DEVELOP + debug = 1; +#endif + + if (debug) + { + (*testout) << "debug edge !!!" << endl; + (*testout) << "edgepoints = " << edgepoints << endl; + (*testout) << "s1, s2 = " << s1 << " - " << s2 << endl; + (*testout) << "s1_rep, s2_rep = " << s1_rep << " - " << s2_rep << endl; + } + + refedges.SetSize(0); + refedgesinv.SetSize(0); + Point<3> hp = Center (edgepoints[0], edgepoints[1]); + ProjectToEdge (geometry.GetSurface(s1), geometry.GetSurface(s2), hp); + + if (debug) + *testout << "hp = " << hp << endl; + + Vec<3> t, a1, a2; + geometry.GetSurface(s1) -> CalcGradient (hp, a1); + geometry.GetSurface(s2) -> CalcGradient (hp, a2); + t = Cross (a1, a2); + t.Normalize(); + if (!pos) t *= -1; + + + + for (int i = 0; i < geometry.GetNTopLevelObjects(); i++) + { + Solid * locsol; + + if (geometry.GetTopLevelObject(i)->GetLayer() != layer) + continue; + + const Solid * sol = geometry.GetTopLevelObject(i)->GetSolid(); + const Surface * surf = geometry.GetTopLevelObject(i)->GetSurface(); + + sol -> TangentialSolid (hp, locsol, locsurfind, size*ideps); + + //*testout << "hp = " << hp << endl; + //(*testout) << "locsol: " << endl; + //if (locsol) locsol->Print(*testout); + //(*testout) << endl; + + + if (!locsol) continue; + + BoxSphere<3> boxp (hp, hp); + boxp.Increase (1e-8*size); + boxp.CalcDiamCenter(); + + ReducePrimitiveIterator rpi(boxp); + UnReducePrimitiveIterator urpi; + + ((Solid*)locsol) -> IterateSolid (rpi); + + locsol -> CalcSurfaceInverse (); + + if (!surf) + { + locsol -> GetTangentialSurfaceIndices (hp,locsurfind,ideps*size); + } + else + { + /* + if (fabs (surf->CalcFunctionValue (hp)) < 1e-6) + continue; + */ + locsurfind.SetSize(1); + locsurfind[0] = -1; + for (int j = 0; j < geometry.GetNSurf(); j++) + if (geometry.GetSurface(j) == surf) + { + locsurfind[0] = j; + // geometry.GetSurfaceClassRepresentant(j); + break; + } + } + + ((Solid*)locsol) -> IterateSolid (urpi); + + + if (debug) + (*testout) << "edge of tlo " << i << ", has " << locsurfind.Size() << " faces." << endl; + + + for (int j = locsurfind.Size()-1; j >= 0; j--) + if (fabs (geometry.GetSurface(locsurfind[j]) + ->CalcFunctionValue (hp) ) > ideps*size) + locsurfind.Delete(j); + + if (debug) + (*testout) << locsurfind.Size() << " faces on hp" << endl; + + + + for (int j = 0; j < locsurfind.Size(); j++) + { + int lsi = locsurfind[j]; + int rlsi = geometry.GetSurfaceClassRepresentant(lsi); + + + // n is outer normal to solid + Vec<3> n = geometry.GetSurface(lsi) -> GetNormalVector (hp); + if (debug) + *testout << "n1 = " << n << endl; + if (geometry.GetSurface (lsi)->Inverse()) + n *= -1; + + if (fabs (t * n) > 1e-4) continue; + if (debug) + { + (*testout) << "face " << locsurfind[j] << ", rep = " << rlsi + << " has (t*n) = " << (t*n) << endl; + (*testout) << "n = " << n << endl; + } + + // rn is normal to class representant + Vec<3> rn = geometry.GetSurface(rlsi) -> GetNormalVector (hp); + if (debug) + { + (*testout) << "rn = " << rn << endl; + } + + //if( n*rn < 0) + // rn *= -1; + + bool sameasref = ((n * rn) > 0); + + //m = Cross (t, rn); + Vec<3> m = Cross (t, n); + if(!sameasref) m*=-1.; + + m.Normalize(); + + + if (debug) + (*testout) << "m = " << m << endl; + + + //bool founddirection = false; + //int k; + double eps = 1e-8*size; + + Array pre_ok(2); + + do + { + eps *= 0.5; + pre_ok[0] = (locsol -> VectorIn2 (hp, m, n, eps) == IS_OUTSIDE && + locsol -> VectorIn2 (hp, m, -1. * n, eps) == IS_INSIDE); + pre_ok[1] = (locsol -> VectorIn2 (hp, -1.*m, n, eps) == IS_OUTSIDE && + locsol -> VectorIn2 (hp, -1.*m, -1. * n, eps) == IS_INSIDE); + + if (debug) + { + *testout << "eps = " << eps << endl; + *testout << "in,1 = " << locsol -> VectorIn2 (hp, m, n, eps) << endl; + *testout << "in,1 = " << locsol -> VectorIn2 (hp, m, -1. * n, eps) << endl; + *testout << "in,1 = " << locsol -> VectorIn2 (hp, -1.*m, n, eps) << endl; + *testout << "in,1 = " << locsol -> VectorIn2 (hp, -1.*m, -1. * n, eps) << endl; + } + } + while(pre_ok[0] && pre_ok[1] && eps > 1e-16*size); + + if (debug) + { + *testout << "eps = " << eps << ", size = " << size << endl; + *testout << "pre_ok[0,1] = " << pre_ok[0] << "," << pre_ok[1] << endl; + } + + eps = 1e-8*size; + + + for (int k = 1; k <= 2; k ++) + { + bool edgeinv = (k == 2); + + if (debug) + { + (*testout) << "onface(" << hp << ", " << m << ")= " << flush; + (*testout) << locsol->OnFace (hp, m, eps) << flush; + (*testout) << " n " << n << flush; + (*testout) << " vec2in = " + << locsol -> VectorIn2 (hp, m, n, eps) << " and " + << locsol -> VectorIn2 (hp, m, -1 * n, eps) << endl; + } + + // if (locsol -> OnFace (hp, m)) + + + // one side must be inside, the other must be outside + bool ok = (pre_ok[k-1] || + (locsol -> VectorIn2 (hp, m, n, eps) == IS_OUTSIDE && + locsol -> VectorIn2 (hp, m, -1 * n, eps) == IS_INSIDE)); + + if (debug) + (*testout) << "ok (before) " << ok << endl; + + // compute second order approximation + // curve = hp + t m + t*t/2 m2 + Vec<3> grad, m2; + Mat<3> hesse; + geometry.GetSurface(lsi) -> CalcGradient (hp, grad); + geometry.GetSurface(lsi) -> CalcHesse (hp, hesse); + double fac = -(m * (hesse * m)) / (grad * grad); + m2 = fac * grad; + // (*testout) << "hp = " << hp << ", m = " << m << ", m2 = " << m2 << endl; + + Solid * locsol2; + locsol -> TangentialSolid3 (hp, m, m2, locsol2, locsurfind2, ideps*size); + if (!locsol2) ok = 0; + delete locsol2; + + + if (ok) + { + if (debug) + (*testout) << "is true" << endl; + int hi = 0; + for (int l = 1; !hi && l <= refedges.Size(); l++) + { + if (refedges.Get(l).si == rlsi && // JS sept 2006 + // if (refedges.Get(l).si == lsi && + refedgesinv.Get(l) == edgeinv) + { + hi = l; + } + } + + if (!hi) + { + seg.si = rlsi; // JS Sept 2006 + // seg.si = lsi; + seg.domin = -1; + seg.domout = -1; + seg.tlosurf = -1; + //seg.surfnr1 = s1_rep; + //seg.surfnr2 = s2_rep; + seg.surfnr1 = s1; + seg.surfnr2 = s2; + hi = refedges.Append (seg); + refedgesinv.Append (edgeinv); + edges_priority.Append((pre_ok[k-1]) ? 1 : 0); + } + else + { + if(edges_priority[hi-1] / 10 == -i-1) + edges_priority[hi-1] = 10*(i+1); + else + edges_priority[hi-1] = -10*(i+1); + } + + if (!surf) + { + if (sameasref) + refedges.Elem(hi).domin = i; + else + refedges.Elem(hi).domout = i; + } + else + refedges.Elem(hi).tlosurf = i; + + if(pre_ok[k-1]) + edges_priority[hi-1] = 1; + + + if (debug) + (*testout) << "add ref seg:" + << "si = " << refedges.Get(hi).si + << ", domin = " << refedges.Get(hi).domin + << ", domout = " << refedges.Get(hi).domout + << ", surfnr1/2 = " << refedges.Get(hi).surfnr1 + << ", " << refedges.Get(hi).surfnr2 + << ", inv = " << refedgesinv.Get(hi) + << ", refedgenr = " << hi + << ", priority = " << edges_priority[hi-1] + << ", hi = " << hi + << endl; + } + else + { + if (debug) + (*testout) << "is false" << endl; + } + m *= -1; + } + } + delete locsol; + } + + + if (debug) + { + *testout << "Refsegments, before delete: " << endl << refedges << endl; + *testout << "inv: " << endl << refedgesinv << endl; + } + + BitArray todelete(refedges.Size()); + todelete.Clear(); + + + for(int i=0; i edges_priority[j]) + { + todelete.Set(j); + } + } + } + + } + + int num = refedges.Size(); + + for(int i=refedges.Size()-1; num>2 && i>=0; i--) + if(todelete.Test(i)) + { + refedges.Delete(i); + refedgesinv.Delete(i); + num--; + } + + + if (debug) + { + *testout << "Refsegments: " << endl << refedges << endl; + } + } + + + + void EdgeCalculation :: + StoreEdge (const Array & refedges, + const Array & refedgesinv, + const Array > & edgepoints, + const Array & curvelength, + int layer, + Mesh & mesh) + { + + // Calculate optimal element-length + int i, j, k; + PointIndex pi; + int ne; + + double len, corr, lam; + PointIndex thispi, lastpi; + Point<3> p, np; + Segment seg; + + const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); + const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); + + (*testout) << "s1 " << refedges.Get(1).surfnr1 << " s2 " << refedges.Get(1).surfnr2 + << " rs1 " << geometry.GetSurfaceClassRepresentant(refedges.Get(1).surfnr1) + << " rs2 " << geometry.GetSurfaceClassRepresentant(refedges.Get(1).surfnr2) << endl; + + len = curvelength.Last(); + ne = int (len + 0.5); + if (ne == 0) ne = 1; + if (Dist (edgepoints.Get(1), edgepoints.Last()) < 1e-8*geometry.MaxSize() && + ne <= 6) + ne = 6; + corr = len / ne; + + // generate initial point + p = edgepoints.Get(1); + lastpi = -1; + + /* + for (pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + if (Dist (mesh[pi], p) < 1e-6) + { + lastpi = pi; + break; + } + */ + + const double di=1e-7*geometry.MaxSize(); + + Array locsearch; + meshpoint_tree -> GetIntersecting (p-Vec<3> (di,di,di), + p+Vec<3> (di,di,di), locsearch); + if (locsearch.Size()) + lastpi = locsearch[0]; + + + + if (lastpi == -1) + { + lastpi = mesh.AddPoint (p, layer, FIXEDPOINT); + meshpoint_tree -> Insert (p, lastpi); + // (*testout) << "test1, store point " << lastpi << ", p = " << p << endl; + } + + j = 1; + for (i = 1; i <= ne; i++) + { + while (curvelength.Get(j) < i * corr && j < curvelength.Size()) j++; + + + lam = (i * corr - curvelength.Get(j-1)) / + (curvelength.Get(j) - curvelength.Get(j-1)); + + np(0) = (1-lam) * edgepoints.Get(j-1)(0) + lam * edgepoints.Get(j)(0); + np(1) = (1-lam) * edgepoints.Get(j-1)(1) + lam * edgepoints.Get(j)(1); + np(2) = (1-lam) * edgepoints.Get(j-1)(2) + lam * edgepoints.Get(j)(2); + + thispi = -1; + if (i == ne) + { + /* + for (pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + if (Dist(mesh[pi], np) < 1e-6) + thispi = pi; + */ + + meshpoint_tree -> GetIntersecting (np-Vec<3> (di,di,di), + np+Vec<3> (di,di,di), locsearch); + if (locsearch.Size()) + thispi = locsearch[0]; + } + + if (thispi == -1) + { + ProjectToEdge (surf1, surf2, np); + thispi = mesh.AddPoint (np, layer, (i==ne) ? FIXEDPOINT : EDGEPOINT); + + meshpoint_tree -> Insert (np, thispi); + // (*testout) << "test2, store point " << thispi << ", p = " << np << endl; + } + + for (k = 1; k <= refedges.Size(); k++) + { + if (refedgesinv.Get(k)) + { + seg[0] = lastpi; + seg[1] = thispi; + } + else + { + seg[0] = thispi; + seg[1] = lastpi; + } + seg.si = refedges.Get(k).si; + seg.domin = refedges.Get(k).domin; + seg.domout = refedges.Get(k).domout; + seg.tlosurf = refedges.Get(k).tlosurf; + seg.edgenr = refedges.Get(k).edgenr; + seg.surfnr1 = refedges.Get(k).surfnr1; + seg.surfnr2 = refedges.Get(k).surfnr2; + seg.seginfo = 0; + if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; + mesh.AddSegment (seg); + //(*testout) << "add seg " << mesh[seg.p1] << "-" << mesh[seg.p2] << endl; + //(*testout) << "refedge " << k << " surf1 " << seg.surfnr1 << " surf2 " << seg.surfnr2 << " inv " << refedgesinv.Get(k) << endl; + + double maxh = min2 (geometry.GetSurface(seg.surfnr1)->GetMaxH(), + geometry.GetSurface(seg.surfnr2)->GetMaxH()); + + if (seg.domin != -1) + { + const Solid * s1 = + geometry.GetTopLevelObject(seg.domin) -> GetSolid(); + maxh = min2 (maxh, s1->GetMaxH()); + maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domin)->GetMaxH()); + mesh.RestrictLocalH (p, maxh); + mesh.RestrictLocalH (np, maxh); + } + if (seg.domout != -1) + { + const Solid * s1 = + geometry.GetTopLevelObject(seg.domout) -> GetSolid(); + maxh = min2 (maxh, s1->GetMaxH()); + maxh = min2 (maxh, geometry.GetTopLevelObject(seg.domout)->GetMaxH()); + mesh.RestrictLocalH (p, maxh); + mesh.RestrictLocalH (np, maxh); + } + if (seg.tlosurf != -1) + { + double hi = geometry.GetTopLevelObject(seg.tlosurf) -> GetMaxH(); + maxh = min2 (maxh, hi); + mesh.RestrictLocalH (p, maxh); + mesh.RestrictLocalH (np, maxh); + } + } + + p = np; + lastpi = thispi; + } + +#ifdef DEVELOP + (*testout) << " eplast = " << lastpi << " = " << p << endl; +#endif + } + + + + + + + void EdgeCalculation :: + StoreShortEdge (const Array & refedges, + const Array & refedgesinv, + const Array > & edgepoints, + const Array & curvelength, + int layer, + Mesh & mesh) + { + + // Calculate optimal element-length + PointIndex pi; + // int ne; + Segment seg; + + /* + double len, corr, lam; + int thispi, lastpi; + Point<3> p, np; + + + const Surface * surf1 = geometry.GetSurface (refedges.Get(1).surfnr1); + const Surface * surf2 = geometry.GetSurface (refedges.Get(1).surfnr2); + + len = curvelength.Last(); + ne = int (len + 0.5); + if (ne == 0) ne = 1; + if (Dist2 (edgepoints[1], edgepoints.Last()) < 1e-8 && + ne <= 6) + ne = 6; + corr = len / ne; + */ + + // generate initial point + Point<3> p = edgepoints[0]; + PointIndex pi1 = -1; + for (pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + + if (Dist (mesh[pi], p) < 1e-6*geometry.MaxSize()) + { + pi1 = pi; + break; + } + + if (pi1 == -1) + { + pi1 = mesh.AddPoint (p, layer, FIXEDPOINT); + meshpoint_tree -> Insert (p, pi1); + // (*testout) << "test3, store point " << pi1 << ", p = " << p << endl; + } + + p = edgepoints.Last(); + PointIndex pi2 = -1; + for (pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + + if (Dist (mesh[pi], p) < 1e-6*geometry.MaxSize()) + { + pi2 = pi; + break; + } + if (pi2==-1) + { + pi2 = mesh.AddPoint (p, layer, FIXEDPOINT); + meshpoint_tree -> Insert (p, pi2); + // (*testout) << "test4, store point " << pi2 << ", p = " << p << endl; + } + + /* + + j = 1; + for (i = 1; i <= ne; i++) + { + while (curvelength[j] < i * corr && j < curvelength.Size()) j++; + + lam = (i * corr - curvelength[j-1]) / + (curvelength[j] - curvelength[j-1]); + + np(0) = (1-lam) * edgepoints[j-1](0) + lam * edgepoints[j](0); + np(1) = (1-lam) * edgepoints[j-1](1) + lam * edgepoints[j](1); + np(2) = (1-lam) * edgepoints[j-1](2) + lam * edgepoints[j](2); + + + thispi = 0; + if (i == ne) + for (j = 1; j <= mesh.GetNP(); j++) + if (Dist(mesh.Point(j), np) < 1e-6) + thispi = j; + + if (!thispi) + { + ProjectToEdge (surf1, surf2, np); + thispi = mesh.AddPoint (np); + } + */ + + // (*testout) << "short edge " << pi1 << " - " << pi2 << endl; + + for (int k = 1; k <= refedges.Size(); k++) + { + if (refedgesinv.Get(k)) + { + seg[0] = pi1; + seg[1] = pi2; + } + else + { + seg[0] = pi2; + seg[1] = pi1; + } + + seg.si = refedges.Get(k).si; + seg.domin = refedges.Get(k).domin; + seg.domout = refedges.Get(k).domout; + seg.tlosurf = refedges.Get(k).tlosurf; + seg.edgenr = refedges.Get(k).edgenr; + seg.surfnr1 = refedges.Get(k).surfnr1; + seg.surfnr2 = refedges.Get(k).surfnr2; + seg.seginfo = 0; + if (k == 1) seg.seginfo = (refedgesinv.Get(k)) ? 2 : 1; + mesh.AddSegment (seg); + // (*testout) << "add seg " << seg[0] << "-" << seg[1] << endl; + } + } + + + + + + + + void EdgeCalculation :: + CopyEdge (const Array & refedges, + const Array & refedgesinv, + int copyfromedge, + const Point<3> & fromstart, const Point<3> & fromend, + const Point<3> & tostart, const Point<3> & toend, + int copyedgeidentification, + int layer, + Mesh & mesh) + { + int k; + PointIndex pi; + + double size = geometry.MaxSize(); + + // copy start and end points + for (int i = 1; i <= 2; i++) + { + Point<3> fromp = + (i == 1) ? fromstart : fromend; + Point<3> top = + (i == 1) ? tostart : toend; + + PointIndex frompi = -1; + PointIndex topi = -1; + for (pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + { + if (Dist2 (mesh[pi], fromp) <= 1e-16*size) + frompi = pi; + if (Dist2 (mesh[pi], top) <= 1e-16*size) + topi = pi; + } + + + if (topi == -1) + { + topi = mesh.AddPoint (top, layer, FIXEDPOINT); + meshpoint_tree -> Insert (top, topi); + } + + const Identification & csi = + (*geometry.identifications.Get(copyedgeidentification)); + + + if (csi.Identifyable (mesh[frompi], mesh[topi])) + mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); + else if (csi.Identifyable (mesh[topi], mesh[frompi])) + mesh.GetIdentifications().Add(topi, frompi, copyedgeidentification); + else + { + cerr << "edgeflw.cpp: should identify, but cannot"; + exit(1); + } +#ifdef DEVELOP + (*testout) << "adding identification " << mesh[frompi] << "; " << mesh[topi] + << " (id " << copyedgeidentification <<")" << endl; +#endif + + + /* + (*testout) << "Add Identification from CopyEdge, p1 = " + << mesh[PointIndex(frompi)] << ", p2 = " + << mesh[PointIndex(topi)] << endl; + + mesh.GetIdentifications().Add(frompi, topi, copyedgeidentification); + */ + } + + int oldns = mesh.GetNSeg(); + for (int i = 1; i <= oldns; i++) + { + // real copy, since array might be reallocated !! + const Segment oldseg = mesh.LineSegment(i); + if (oldseg.edgenr != copyfromedge) + continue; + if (oldseg.seginfo == 0) + continue; + + int pi1 = oldseg[0]; + int pi2 = oldseg[1]; + + int npi1 = geometry.identifications.Get(copyedgeidentification) + -> GetIdentifiedPoint (mesh, pi1); + int npi2 = geometry.identifications.Get(copyedgeidentification) + -> GetIdentifiedPoint (mesh, pi2); + + //(*testout) << "copy edge, pts = " << npi1 << " - " << npi2 << endl; + + Segment seg; + + for (k = 1; k <= refedges.Size(); k++) + { + bool inv = refedgesinv.Get(k); + + // other edge is inverse + if (oldseg.seginfo == 1) + inv = !inv; + + // (*testout) << "inv, now = " << inv << endl; + + if (inv) + { + seg[0] = npi1; + seg[1] = npi2; + } + else + { + seg[0] = npi2; + seg[1] = npi1; + } + seg.si = refedges.Get(k).si; + seg.domin = refedges.Get(k).domin; + seg.domout = refedges.Get(k).domout; + seg.tlosurf = refedges.Get(k).tlosurf; + seg.edgenr = refedges.Get(k).edgenr; + seg.surfnr1 = refedges.Get(k).surfnr1; + seg.surfnr2 = refedges.Get(k).surfnr2; + seg.seginfo = 0; + if (k == 1) seg.seginfo = refedgesinv.Get(k) ? 2 : 1; + mesh.AddSegment (seg); + // (*testout) << "copy seg " << seg[0] << "-" << seg[1] << endl; +#ifdef DEVELOP + + (*testout) << "copy seg, face = " << seg.si << ": " + << " inv = " << inv << ", refinv = " << refedgesinv.Get(k) + << mesh.Point(seg[0]) << ", " << mesh.Point(seg[1]) << endl; +#endif + + } + + } + } + + + + + + + + void EdgeCalculation :: + FindClosedSurfaces (double h, Mesh & mesh) + { + // if there is no special point at a sphere, one has to add a segment pair + + int nsurf = geometry.GetNSurf(); + int layer = 0; + + Solid * tansol; + Array tansurfind; + + double size = geometry.MaxSize(); + int nsol = geometry.GetNTopLevelObjects(); + + + BitArray pointatsurface (nsurf); + pointatsurface.Clear(); + + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + +#ifdef DEVELOP + (*testout) << seg.surfnr1 << ", " << seg.surfnr2 << ", si = " << seg.si << endl; +#endif + int classrep = geometry.GetSurfaceClassRepresentant (seg.si); + pointatsurface.Set (classrep); + } + + + for (int i = 0; i < nsurf; i++) + { + int classrep = geometry.GetSurfaceClassRepresentant (i); + + if (!pointatsurface.Test(classrep)) + { + const Surface * s = geometry.GetSurface(i); + Point<3> p1 = s -> GetSurfacePoint(); + Vec<3> nv = s -> GetNormalVector (p1); + + double hloc = + min2 (s->LocH (p1, 3, 1, h), mesh.GetH(p1)); + + + + Segment seg1; + seg1.si = i; + seg1.domin = -1; + seg1.domout = -1; + + Segment seg2; + seg2.si = i; + seg2.domin = -1; + seg2.domout = -1; + + seg1.surfnr1 = i; + seg2.surfnr1 = i; + seg1.surfnr2 = i; + seg2.surfnr2 = i; + + for (int j = 0; j < nsol; j++) + { + if (geometry.GetTopLevelObject(j)->GetSurface()) + continue; + + const Solid * sol = geometry.GetTopLevelObject(j)->GetSolid(); + sol -> TangentialSolid (p1, tansol, tansurfind, ideps*size); + layer = geometry.GetTopLevelObject(j)->GetLayer(); + + + if (tansol) + { + tansol -> GetSurfaceIndices (tansurfind); + + if (tansurfind.Size() == 1 && tansurfind.Get(1) == i) + { + hloc = min2 (hloc, geometry.GetTopLevelObject(j)->GetMaxH()); + + if (!tansol->VectorIn(p1, nv)) + { + seg1.domin = j; + seg2.domin = j; + seg1.tlosurf = j; + seg2.tlosurf = j; + } + else + { + seg1.domout = j; + seg2.domout = j; + seg1.tlosurf = j; + seg2.tlosurf = j; + } + // seg.s2 = i; + // seg.invs1 = surfaces[i] -> Inverse(); + // seg.invs2 = ! (surfaces[i] -> Inverse()); + } + delete tansol; + } + } + + + Vec<3> tv = nv.GetNormal (); + tv *= (hloc / tv.Length()); + Point<3> p2 = p1 + tv; + s->Project (p2); + + + if (seg1.domin != -1 || seg1.domout != -1) + { + mesh.AddPoint (p1, layer, EDGEPOINT); + mesh.AddPoint (p2, layer, EDGEPOINT); + seg1[0] = mesh.GetNP()-1; + seg1[1] = mesh.GetNP(); + seg2[1] = mesh.GetNP()-1; + seg2[0] = mesh.GetNP(); + seg1.geominfo[0].trignum = 1; + seg1.geominfo[1].trignum = 1; + seg2.geominfo[0].trignum = 1; + seg2.geominfo[1].trignum = 1; + mesh.AddSegment (seg1); + mesh.AddSegment (seg2); + + PrintMessage (5, "Add line segment to smooth surface"); + +#ifdef DEVELOP + (*testout) << "Add segment at smooth surface " << i; + if (i != classrep) (*testout) << ", classrep = " << classrep; + (*testout) << ": " + << mesh.Point (mesh.GetNP()-1) << " - " + << mesh.Point (mesh.GetNP()) << endl; +#endif + } + } + } + } + +} diff --git a/libsrc/csg/edgeflw.hpp b/libsrc/csg/edgeflw.hpp new file mode 100644 index 00000000..4c2fc949 --- /dev/null +++ b/libsrc/csg/edgeflw.hpp @@ -0,0 +1,110 @@ +#ifndef FILE_EDGEFLW +#define FILE_EDGEFLW + +/**************************************************************************/ +/* File: edgeflw.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Okt. 95 */ +/**************************************************************************/ + +namespace netgen +{ + + + + /* + + Edge - following function and + Projection to edge of implicitly given edge + + */ + + + /** + Calculates edges. + The edges of a solid geometry are computed. Special + points have to be given. + */ + extern void CalcEdges (const CSGeometry & geometry, + const Array & specpoints, + double h, Mesh & mesh); + + + + + + class EdgeCalculation + { + const CSGeometry & geometry; + Array & specpoints; + Point3dTree * searchtree; + Point3dTree * meshpoint_tree; + int cntedge; + + double ideps; + + public: + EdgeCalculation (const CSGeometry & ageometry, + Array & aspecpoints); + + ~EdgeCalculation(); + + void SetIdEps(const double epsin) {ideps = epsin;} + + void Calc(double h, Mesh & mesh); + + + private: + void CalcEdges1 (double h, Mesh & mesh); + + + void FollowEdge (int pi1, int & ep, int & pos, + // const Array & hsp, + const Array & hsp, + double h, const Mesh & mesh, + Array > & edgepoints, + Array & curvelength); + + + void AnalyzeEdge (int s1, int s2, int s1_rep, int s2_rep, int pos, int layer, + const Array > & edgepoints, + Array & refedges, + Array & refedgesinv); + + void StoreEdge (const Array & refedges, + const Array & refedgesinv, + const Array > & edgepoints, + const Array & curvelength, + int layer, + Mesh & mesh); + + void StoreShortEdge (const Array & refedges, + const Array & refedgesinv, + const Array > & edgepoints, + const Array & curvelength, + int layer, + Mesh & mesh); + + void CopyEdge (const Array & refedges, + const Array & refedgesinv, + int copyfromedge, + const Point<3> & fromstart, const Point<3> & fromend, + const Point<3> & tostart, const Point<3> & toend, + int copyedgeidentification, + int layer, + Mesh & mesh); + + + void SplitEqualOneSegEdges (Mesh & mesh); + void FindClosedSurfaces (double h, Mesh & mesh); + + + public: + bool point_on_edge_problem; + + }; + +} + + +#endif diff --git a/libsrc/csg/explicitcurve2d.cpp b/libsrc/csg/explicitcurve2d.cpp new file mode 100644 index 00000000..81c0e7ac --- /dev/null +++ b/libsrc/csg/explicitcurve2d.cpp @@ -0,0 +1,160 @@ +#include +#include + +namespace netgen +{ +ExplicitCurve2d :: ExplicitCurve2d () + { + ; + } + + +void ExplicitCurve2d :: Project (Point<2> & p) const + { + double t; + t = ProjectParam (p); + p = Eval (t); + } + +double ExplicitCurve2d :: NumericalProjectParam (const Point<2> & p, double lb, double ub) const + { + double t(-1); + Vec<2> tan; + Vec<2> curv; + Point<2> cp; + double f, fl, fu; + int cnt; + + tan = EvalPrime (lb); + cp = Eval (lb); + fl = tan * (cp - p); + if (fl > 0) // changed by wmf, originally fl >= 0 + { + // cerr << "tan = " << tan << " cp - p = " << (cp - p) << endl; + // cerr << "ExplicitCurve2d::NumericalProject: lb wrong" << endl; + return 0; + } + + tan = EvalPrime (ub); + cp = Eval (ub); + fu = tan * (cp - p); + if (fu < 0) // changed by wmf, originally fu <= 0 + { + // cerr << "tan = " << tan << " cp - p = " << (cp - p) << endl; + // cerr << "ExplicitCurve2d::NumericalProject: ub wrong" << endl; + return 0; + } + + cnt = 0; + while (ub - lb > 1e-12 && fu - fl > 1e-12) + { + cnt++; + if (cnt > 50) + { + (*testout) << "Num Proj, cnt = " << cnt << endl; + } + + t = (lb * fu - ub * fl) / (fu - fl); + if (t > 0.9 * ub + 0.1 * lb) t = 0.9 * ub + 0.1 * lb; + if (t < 0.1 * ub + 0.9 * lb) t = 0.1 * ub + 0.9 * lb; + + tan = EvalPrime (t); + cp = Eval (t); + f = tan * (cp - p); + + if (f >= 0) + { + ub = t; + fu = f; + } + else + { + lb = t; + fl = f; + } + } + + return t; + } + + +Vec<2> ExplicitCurve2d :: Normal (double t) const +{ + Vec<2> tan = EvalPrime (t); + tan.Normalize(); + return Vec<2> (tan(1), -tan(0)); +} + + +void ExplicitCurve2d :: NormalVector (const Point<2> & p, Vec<2> & n) const + { + double t = ProjectParam (p); + n = Normal (t); + } + + +Point<2> ExplicitCurve2d :: CurvCircle (double t) const + { + Point<2> cp; + Vec<2> tan, n, curv; + double den; + + cp = Eval (t); + tan = EvalPrime (t); + n = Normal (t); + curv = EvalPrimePrime (t); + + den = n * curv; + if (fabs (den) < 1e-12) + return cp + 1e12 * n; + + return cp + (tan.Length2() / den) * n; + } + + +double ExplicitCurve2d :: MaxCurvature () const + { + double t, tmin, tmax, dt; + double curv; + Vec<2> tan; + double maxcurv; + + maxcurv = 0; + + tmin = MinParam (); + tmax = MaxParam (); + dt = (tmax - tmin) / 1000; + for (t = tmin; t <= tmax+dt; t += dt) + if (SectionUsed (t)) + { + tan = EvalPrime (t); + curv = fabs ( (Normal(t) * EvalPrimePrime(t)) / tan.Length2()); + if (curv > maxcurv) maxcurv = curv; + } + return maxcurv; + } + +double ExplicitCurve2d :: MaxCurvatureLoc (const Point<2> & p, double rad) const + { + double t, tmin, tmax, dt; + double curv; + Vec<2> tan; + double maxcurv; + + maxcurv = 0; + + tmin = MinParam (); + tmax = MaxParam (); + dt = (tmax - tmin) / 1000; + for (t = tmin; t <= tmax+dt; t += dt) + if (Dist (Eval(t), p) < rad) + { + tan = EvalPrime (t); + curv = fabs ( (Normal(t) * EvalPrimePrime(t)) / tan.Length2()); + if (curv > maxcurv) maxcurv = curv; + } + + return maxcurv; + } + +} diff --git a/libsrc/csg/explicitcurve2d.hpp b/libsrc/csg/explicitcurve2d.hpp new file mode 100644 index 00000000..559030b2 --- /dev/null +++ b/libsrc/csg/explicitcurve2d.hpp @@ -0,0 +1,113 @@ +#ifndef FILE_EXPLICITCURVE2D +#define FILE_EXPLICITCURVE2D + +/**************************************************************************/ +/* File: explicitcurve2d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 14. Oct. 96 */ +/**************************************************************************/ + + +namespace netgen +{ + + /* + + Explicit 2D Curve repesentation + + */ + + + + /// + class ExplicitCurve2d : public Curve2d + { + public: + /// + ExplicitCurve2d (); + + /// + virtual void Project (Point<2> & p) const; + /// + virtual double ProjectParam (const Point<2> & p) const = 0; + /// + virtual double NumericalProjectParam (const Point<2> & p, double lb, double ub) const; + /// + virtual double MinParam () const = 0; + /// + virtual double MaxParam () const = 0; + /// + virtual Point<2> Eval (double t) const = 0; + /// + virtual Vec<2> EvalPrime (double t) const = 0; + /// + virtual Vec<2> Normal (double t) const; + /// + virtual void NormalVector (const Point<2> & p, Vec<2> & n) const; + /// + virtual Vec<2> EvalPrimePrime (double t) const = 0; + + /// + virtual double MaxCurvature () const; + /// + virtual double MaxCurvatureLoc (const Point<2> & p, double rad) const; + + /// + virtual Point<2> CurvCircle (double t) const; + /// + virtual void Print (ostream & /* str */) const { }; + + /// + virtual int SectionUsed (double /* t */) const { return 1; } + /// + virtual void Reduce (const Point<2> & /* p */, double /* rad */) { }; + /// + virtual void UnReduce () { }; + }; + + + /// + class BSplineCurve2d : public ExplicitCurve2d + { + /// + Array > points; + /// + Array intervallused; + /// + int redlevel; + + public: + /// + BSplineCurve2d (); + /// + void AddPoint (const Point<2> & apoint); + + bool Inside (const Point<2> & p, double & dist) const; + + /// + virtual double ProjectParam (const Point<2> & p) const; + /// + virtual double MinParam () const { return 0; } + /// + virtual double MaxParam () const { return points.Size(); } + /// + virtual Point<2> Eval (double t) const; + /// + virtual Vec<2> EvalPrime (double t) const; + /// + virtual Vec<2> EvalPrimePrime (double t) const; + /// + virtual void Print (ostream & str) const; + + /// + virtual int SectionUsed (double t) const; + /// + virtual void Reduce (const Point<2> & p, double rad); + /// + virtual void UnReduce (); + }; + +} + + +#endif diff --git a/libsrc/csg/extrusion.cpp b/libsrc/csg/extrusion.cpp new file mode 100644 index 00000000..29676395 --- /dev/null +++ b/libsrc/csg/extrusion.cpp @@ -0,0 +1,876 @@ +#include + +#include +#include + + +namespace netgen +{ + + Array > project1, project2; + + + + void ExtrusionFace :: Init(void) + { + p0.SetSize(path->GetNSplines()); + x_dir.SetSize(path->GetNSplines()); + y_dir.SetSize(path->GetNSplines()); + z_dir.SetSize(path->GetNSplines()); + loc_z_dir.SetSize(path->GetNSplines()); + spline3_path.SetSize(path->GetNSplines()); + line_path.SetSize(path->GetNSplines()); + + for(int i=0; iGetNSplines(); i++) + { + spline3_path[i] = dynamic_cast < const SplineSeg3<3>* >(&path->GetSpline(i)); + line_path[i] = dynamic_cast < const LineSeg<3>* >(&path->GetSpline(i)); + + if(line_path[i]) + { + y_dir[i] = line_path[i]->EndPI() - line_path[i]->StartPI(); + y_dir[i].Normalize(); + z_dir[i] = glob_z_direction; + Orthogonalize(y_dir[i],z_dir[i]); + x_dir[i] = Cross(y_dir[i],z_dir[i]); + loc_z_dir[i] = z_dir[i]; + } + else + { + z_dir[i] = glob_z_direction; + loc_z_dir[i] = glob_z_direction; + } + } + + profile->GetCoeff(profile_spline_coeff); + latest_point3d = -1.111e30; + } + + + ExtrusionFace :: ExtrusionFace(const SplineSeg<2> * profile_in, + const SplineGeometry<3> * path_in, + const Vec<3> & z_direction) : + profile(profile_in), path(path_in), glob_z_direction(z_direction) + { + deletable = false; + + Init(); + } + + ExtrusionFace :: ExtrusionFace(const Array & raw_data) + { + deletable = true; + + int pos=0; + + Array< Point<2> > p(3); + + int ptype = int(raw_data[pos]); pos++; + + for(int i=0; i(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1)); + } + else if(ptype == 3) + { + profile = new SplineSeg3<2>(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1), + GeomPoint<2>(p[2],1)); + } + + path = new SplineGeometry<3>; + pos = const_cast< SplineGeometry<3> *>(path)->Load(raw_data,pos); + + for(int i = 0; i < 3; i++) + { + glob_z_direction(i) = raw_data[pos]; + pos++; + } + + Init(); + } + + ExtrusionFace :: ~ExtrusionFace() + { + if(deletable) + { + delete profile; + delete path; + } + } + + + int ExtrusionFace :: IsIdentic (const Surface & s2, int & inv, double eps) const + { + const ExtrusionFace * ext2 = dynamic_cast(&s2); + + if(!ext2) return 0; + + if(ext2 == this) + return 1; + + return 0; + } + + void ExtrusionFace :: Orthogonalize(const Vec<3> & v1, Vec<3> & v2) const + { + v2 -= (v1*v2)*v1; + v2.Normalize(); + } + + + void ExtrusionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d, + int & seg, double & t) const + { + if (Dist2 (point3d, latest_point3d) < + 1e-25 * Dist2(path->GetSpline(0).StartPI(), path->GetSpline(0).EndPI())) + { + point2d = latest_point2d; + seg = latest_seg; + t = latest_t; + return; + } + + latest_point3d = point3d; + + double cutdist = -1; + + + Array mindist(path->GetNSplines()); + + for(int i = 0; i < path->GetNSplines(); i++) + { + double auxcut = -1; + double auxmin = -1; + + if(spline3_path[i]) + { + Point<3> startp(path->GetSpline(i).StartPI()); + Point<3> endp(path->GetSpline(i).EndPI()); + Point<3> tanp(spline3_path[i]->TangentPoint()); + + // lower bound for dist + auxmin = sqrt (MinDistTP2 (startp, endp, tanp, point3d)); + + // upper bound for dist + auxcut = min2 (Dist (startp, point3d), Dist (endp, point3d)); + } + else if(line_path[i]) + { + auxmin = auxcut = sqrt (MinDistLP2 (path->GetSpline(i).StartPI(), + path->GetSpline(i).EndPI(), + point3d)); + } + + mindist[i] = auxmin; + + if(i==0 || auxcut < cutdist) + cutdist = auxcut; + } + + + + Point<2> testpoint2d; + Point<3> testpoint3d; + + double minproj(-1); + bool minproj_set(false); + + + + for(int i=0; iGetNSplines(); i++) + { + if(mindist[i] > cutdist) continue; + + double thist = CalcProj(point3d,testpoint2d,i); + + testpoint3d = p0[i] + testpoint2d(0)*x_dir[i] + testpoint2d(1)*loc_z_dir[i]; + double d = Dist2(point3d,testpoint3d); + + + if(!minproj_set || d < minproj) + { + minproj_set = true; + minproj = d; + point2d = testpoint2d; + t = thist; + seg = i; + latest_seg = i; + latest_t = t; + latest_point2d = point2d; + } + } + } + + double ExtrusionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d, + int seg) const + { + double t = -1; + + if(line_path[seg]) + { + point2d(0) = (point3d-line_path[seg]->StartPI())*x_dir[seg]; + point2d(1) = (point3d-line_path[seg]->StartPI())*z_dir[seg]; + double l = Dist(line_path[seg]->StartPI(), + line_path[seg]->EndPI()); + t = min2(max2((point3d - line_path[seg]->StartPI()) * y_dir[seg],0.), + l); + p0[seg] = line_path[seg]->StartPI() + t*y_dir[seg]; + t *= 1./l; + } + else if(spline3_path[seg]) + { + spline3_path[seg]->Project(point3d,p0[seg],t); + + y_dir[seg] = spline3_path[seg]->GetTangent(t); + y_dir[seg].Normalize(); + loc_z_dir[seg] = z_dir[seg]; + Orthogonalize(y_dir[seg],loc_z_dir[seg]); + x_dir[seg] = Cross(y_dir[seg],loc_z_dir[seg]); + Vec<3> dir = point3d-p0[seg]; + point2d(0) = x_dir[seg]*dir; + point2d(1) = loc_z_dir[seg]*dir; + } + return t; + } + + + + double ExtrusionFace :: CalcFunctionValue (const Point<3> & point) const + { + Point<2> p; + + double dummyd; + int dummyi; + + CalcProj(point, p, dummyi, dummyd); + + return + profile_spline_coeff(0)*p(0)*p(0) + + profile_spline_coeff(1)*p(1)*p(1) + + profile_spline_coeff(2)*p(0)*p(1) + + profile_spline_coeff(3)*p(0) + + profile_spline_coeff(4)*p(1) + + profile_spline_coeff(5); + } + + + + + void ExtrusionFace :: CalcGradient (const Point<3> & point, Vec<3> & grad) const + { + Point<2> p2d; + + double t_path; + int seg; + CalcProj (point, p2d, seg, t_path); + + + Point<3> phi; + Vec<3> phip, phipp, phi_minus_point; + + path->GetSpline(seg).GetDerivatives(t_path, phi, phip, phipp); + phi_minus_point = phi-point; + + Vec<3> grad_t = (1.0/(phipp*phi_minus_point + phip*phip)) * phip; + Vec<3> grad_xbar, grad_ybar; + + Vec<3> hex, hey, hez, dex, dey, dez; + CalcLocalCoordinatesDeriv (seg, t_path, hex, hey, hez, dex, dey, dez); + + grad_xbar = hex - (phi_minus_point*dex + hex*phip) * grad_t; + grad_ybar = hez - (phi_minus_point*dez + hez*phip) * grad_t; + + double dFdxbar = 2.*profile_spline_coeff(0)*p2d(0) + + profile_spline_coeff(2)*p2d(1) + profile_spline_coeff(3); + + double dFdybar = 2.*profile_spline_coeff(1)*p2d(1) + + profile_spline_coeff(2)*p2d(0) + profile_spline_coeff(4); + + + grad = dFdxbar * grad_xbar + dFdybar * grad_ybar; + } + + void ExtrusionFace :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const + { + const double eps = 1e-7*Dist(path->GetSpline(0).StartPI(),path->GetSpline(0).EndPI()); + + + Point<3> auxpoint1(point),auxpoint2(point); + Vec<3> auxvec,auxgrad1,auxgrad2; + + for(int i=0; i<3; i++) + { + auxpoint1(i) -= eps; + auxpoint2(i) += eps; + CalcGradient(auxpoint1,auxgrad1); + CalcGradient(auxpoint2,auxgrad2); + auxvec = (1./(2.*eps)) * (auxgrad2-auxgrad1); + for(int j=0; j<3; j++) + hesse(i,j) = auxvec(j); + auxpoint1(i) = point(i); + auxpoint2(i) = point(i); + } + + /* + Vec<3> grad; + CalcGradient(point,grad); + + Point<3> auxpoint(point); + Vec<3> auxvec,auxgrad; + + for(int i=0; i<3; i++) + { + auxpoint(i) -= eps; + CalcGradient(auxpoint,auxgrad); + auxvec = (1./eps) * (grad-auxgrad); + for(int j=0; j<3; j++) + hesse(i,j) = auxvec(j); + auxpoint(i) = point(i); + } + */ + + + for(int i=0; i<3; i++) + for(int j=i+1; j<3; j++) + hesse(i,j) = hesse(j,i) = 0.5*(hesse(i,j)+hesse(j,i)); + } + + + + double ExtrusionFace :: HesseNorm () const + { + return fabs(profile_spline_coeff(0) + profile_spline_coeff(1)) + + sqrt(pow(profile_spline_coeff(0)+profile_spline_coeff(1),2)+4.*pow(profile_spline_coeff(2),2)); + } + + double ExtrusionFace :: MaxCurvature () const + { + double retval,actmax; + + retval = profile->MaxCurvature(); + for(int i=0; iGetNSplines(); i++) + { + actmax = path->GetSpline(i).MaxCurvature(); + if(actmax > retval) + retval = actmax; + } + + return 2.*retval; + } + + + void ExtrusionFace :: Project (Point<3> & p) const + { + double dummyt; + int seg; + Point<2> p2d; + + CalcProj(p,p2d,seg,dummyt); + + profile->Project(p2d,p2d,profile_par); + + p = p0[seg] + p2d(0)*x_dir[seg] + p2d(1)*loc_z_dir[seg]; + + Vec<2> tangent2d = profile->GetTangent(profile_par); + profile_tangent = tangent2d(0)*x_dir[seg] + tangent2d(1)*y_dir[seg]; + } + + + + Point<3> ExtrusionFace :: GetSurfacePoint () const + { + p0[0] = path->GetSpline(0).GetPoint(0.5); + if(!line_path[0]) + { + y_dir[0] = path->GetSpline(0).GetTangent(0.5); + y_dir[0].Normalize(); + loc_z_dir[0] = z_dir[0]; + Orthogonalize(y_dir[0],loc_z_dir[0]); + x_dir[0] = Cross(y_dir[0],loc_z_dir[0]); + } + + Point<2> locpoint = profile->GetPoint(0.5); + + return p0[0] + locpoint(0)*x_dir[0] + locpoint(1)*loc_z_dir[0]; + } + + + bool ExtrusionFace :: BoxIntersectsFace(const Box<3> & box) const + { + Point<3> center = box.Center(); + + Project(center); + + //(*testout) << "box.Center() " << box.Center() << " projected " << center << " diam " << box.Diam() + // << " dist " << Dist(box.Center(),center) << endl; + + return (Dist(box.Center(),center) < 0.5*box.Diam()); + } + + + void ExtrusionFace :: LineIntersections ( const Point<3> & p, + const Vec<3> & v, + const double eps, + int & before, + int & after, + bool & intersecting ) const + { + Point<2> p2d; + Vec<2> v2d; + + intersecting = false; + + double segt; + int seg; + + CalcProj(p,p2d,seg,segt); + + if(seg == 0 && segt < 1e-20) + { + Vec<3> v1,v2; + v1 = path->GetSpline(0).GetTangent(0); + v2 = p-p0[seg]; + if(v1*v2 < -eps) + return; + } + if(seg == path->GetNSplines()-1 && 1.-segt < 1e-20) + { + Vec<3> v1,v2; + v1 = path->GetSpline(seg).GetTangent(1); + v2 = p-p0[seg]; + if(v1*v2 > eps) + return; + } + + v2d(0) = v * x_dir[seg]; + v2d(1) = v * loc_z_dir[seg]; + + Vec<2> n(v2d(1),-v2d(0)); + Array < Point<2> > ips; + + + profile->LineIntersections(v2d(1), + -v2d(0), + -v2d(1)*p2d(0) + v2d(0)*p2d(1), + ips,eps); + int comp; + + if(fabs(v2d(0)) >= fabs(v2d(1))) + comp = 0; + else + comp = 1; + + //(*testout) << "p2d " << p2d; + + for(int i=0; i eps) + after++; + else + intersecting = true; + } + //(*testout) << endl; + } + + void ExtrusionFace :: Print (ostream & str) const{} + + INSOLID_TYPE ExtrusionFace :: VecInFace ( const Point<3> & p, + const Vec<3> & v, + const double eps ) const + { + + Vec<3> normal1; + CalcGradient(p,normal1); normal1.Normalize(); + + double d1 = normal1*v; + + + if(d1 > eps) + return IS_OUTSIDE; + if(d1 < -eps) + return IS_INSIDE; + + + return DOES_INTERSECT; + + /* + Point<2> p2d; + + double t_path; + int seg; + CalcProj(p,p2d,seg,t_path); + + double t; + profile.Project(p2d,p2d,t); + + + + Vec<2> profile_tangent = profile.GetTangent(t); + + double d; + + Vec<3> normal1; + CalcGradient(p,normal1); normal1.Normalize(); + + double d1 = normal1*v; + + Vec<2> v2d; + + v2d(0) = v*x_dir[seg]; + v2d(1) = v*loc_z_dir[seg]; + + + Vec<2> normal(-profile_tangent(1),profile_tangent(0)); + + //d = normal*v2d; + + + d = d1; + + + if(d > eps) + return IS_OUTSIDE; + if(d < -eps) + return IS_INSIDE; + + + return DOES_INTERSECT; + */ + } + + + void ExtrusionFace :: GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const + { + int n = int(facets) + 1; + + for(int k = 0; k < path -> GetNSplines(); k++) + { + for(int i = 0; i <= n; i++) + { + Point<3> origin = path -> GetSpline(k).GetPoint(double(i)/double(n)); + if(!line_path[k]) + { + y_dir[k] = path->GetSpline(k).GetTangent(double(i)/double(n)); + y_dir[k].Normalize(); + } + loc_z_dir[k] = z_dir[k]; + Orthogonalize(y_dir[k],loc_z_dir[k]); + if(!line_path[k]) + x_dir[k] = Cross(y_dir[k],loc_z_dir[k]); + + for(int j = 0; j <= n; j++) + { + Point<2> locp = profile->GetPoint(double(j)/double(n)); + tas.AddPoint(origin + locp(0)*x_dir[k] + locp(1)*loc_z_dir[k]); + } + } + } + + for(int k = 0; k < path->GetNSplines(); k++) + for(int i = 0; i < n; i++) + for(int j = 0; j < n; j++) + { + int pi = k*(n+1)*(n+1) + (n+1)*i +j; + + tas.AddTriangle( TATriangle (0, pi,pi+1,pi+n+1) ); + tas.AddTriangle( TATriangle (0, pi+1,pi+n+1,pi+n+2) ); + } + } + + + void ExtrusionFace :: GetRawData(Array & data) const + { + data.DeleteAll(); + profile->GetRawData(data); + path->GetRawData(data); + for(int i=0; i<3; i++) + data.Append(glob_z_direction[i]); + } + + + void ExtrusionFace :: + CalcLocalCoordinates (int seg, double t, + Vec<3> & ex, Vec<3> & ey, Vec<3> & ez) const + { + ey = path->GetSpline(seg).GetTangent(t); + ey /= ey.Length(); + ex = Cross (ey, glob_z_direction); + ex /= ex.Length(); + ez = Cross (ex, ey); + } + + void ExtrusionFace :: + CalcLocalCoordinatesDeriv (int seg, double t, + Vec<3> & ex, Vec<3> & ey, Vec<3> & ez, + Vec<3> & dex, Vec<3> & dey, Vec<3> & dez) const + { + Point<3> point; + Vec<3> first, second; + path->GetSpline(seg).GetDerivatives (t, point, first, second); + + ey = first; + ex = Cross (ey, glob_z_direction); + ez = Cross (ex, ey); + + dey = second; + dex = Cross (dey, glob_z_direction); + dez = Cross (dex, ey) + Cross (ex, dey); + + double lenx = ex.Length(); + double leny = ey.Length(); + double lenz = ez.Length(); + + ex /= lenx; + ey /= leny; + ez /= lenz; + + dex /= lenx; + dex -= (dex * ex) * ex; + + dey /= leny; + dey -= (dey * ey) * ey; + + dez /= lenz; + dez -= (dez * ez) * ez; + } + + + Extrusion :: Extrusion(const SplineGeometry<3> & path_in, + const SplineGeometry<2> & profile_in, + const Vec<3> & z_dir) : + path(path_in), profile(profile_in), z_direction(z_dir) + { + surfaceactive.SetSize(0); + surfaceids.SetSize(0); + + for(int j=0; j & box) const + { + for(int i=0; iBoxIntersectsFace(box)) + return DOES_INTERSECT; + } + + return PointInSolid(box.Center(),0); + } + + + INSOLID_TYPE Extrusion :: PointInSolid (const Point<3> & p, + const double eps, + Array * const facenums) const + { + Vec<3> random_vec(-0.4561,0.7382,0.4970247); + + int before(0), after(0); + bool intersects(false); + bool does_intersect(false); + + for(int i=0; iLineIntersections(p,random_vec,eps,before,after,intersects); + + //(*testout) << "intersects " << intersects << " before " << before << " after " << after << endl; + if(intersects) + { + if(facenums) + { + facenums->Append(i); + does_intersect = true; + } + else + return DOES_INTERSECT; + } + } + + if(does_intersect) + return DOES_INTERSECT; + + + if(before % 2 == 0) + return IS_OUTSIDE; + + return IS_INSIDE; + } + + + INSOLID_TYPE Extrusion :: PointInSolid (const Point<3> & p, + double eps) const + { + return PointInSolid(p,eps,NULL); + } + + INSOLID_TYPE Extrusion :: VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const + { + Array facenums; + INSOLID_TYPE pInSolid = PointInSolid(p,eps,&facenums); + + if(pInSolid != DOES_INTERSECT) + return pInSolid; + + + double d(0); + + if(facenums.Size() == 1) + { + Vec<3> normal; + faces[facenums[0]]->CalcGradient(p,normal); + normal.Normalize(); + d = normal*v; + + latestfacenum = facenums[0]; + } + else if (facenums.Size() == 2) + { + Vec<3> checkvec; + + Point<3> dummy(p); + faces[facenums[0]]->Project(dummy); + if(fabs(faces[facenums[0]]->GetProfilePar()) < 0.1) + { + int aux = facenums[0]; + facenums[0] = facenums[1]; facenums[1] = aux; + } + + checkvec = faces[facenums[0]]->GetYDir(); + + Vec<3> n0, n1; + faces[facenums[0]]->CalcGradient(p,n0); + faces[facenums[1]]->CalcGradient(p,n1); + n0.Normalize(); + n1.Normalize(); + + + Vec<3> t = Cross(n0,n1); + if(checkvec*t < 0) t*= (-1.); + + Vec<3> t0 = Cross(n0,t); + Vec<3> t1 = Cross(t,n1); + + t0.Normalize(); + t1.Normalize(); + + + const double t0v = t0*v; + const double t1v = t1*v; + + if(t0v > t1v) + { + latestfacenum = facenums[0]; + d = n0*v; + } + else + { + latestfacenum = facenums[1]; + d = n1*v; + } + + if(fabs(t0v) < eps && fabs(t1v) < eps) + latestfacenum = -1; + } + + else + { + cerr << "WHY ARE THERE " << facenums.Size() << " FACES?" << endl; + } + + if(d > eps) + return IS_OUTSIDE; + if(d < -eps) + return IS_INSIDE; + + return DOES_INTERSECT; + } + + + + // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid + INSOLID_TYPE Extrusion :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const + { + INSOLID_TYPE retval; + retval = VecInSolid(p,v1,eps); + + // *testout << "extr, vecinsolid=" << int(retval) << endl; + + if(retval != DOES_INTERSECT) + return retval; + + if(latestfacenum >= 0) + return faces[latestfacenum]->VecInFace(p,v2,0); + else + return VecInSolid(p,v2,eps); + } + + + int Extrusion :: GetNSurfaces() const + { + return faces.Size(); + } + + Surface & Extrusion :: GetSurface (int i) + { + return *faces[i]; + } + + const Surface & Extrusion :: GetSurface (int i) const + { + return *faces[i]; + } + + + void Extrusion :: Reduce (const BoxSphere<3> & box) + { + for(int i = 0; i < faces.Size(); i++) + surfaceactive[i] = faces[i]->BoxIntersectsFace(box); + } + + void Extrusion :: UnReduce () + { + for(int i = 0; i < faces.Size(); i++) + surfaceactive[i] = true; + } + + +} diff --git a/libsrc/csg/extrusion.hpp b/libsrc/csg/extrusion.hpp new file mode 100644 index 00000000..189639bd --- /dev/null +++ b/libsrc/csg/extrusion.hpp @@ -0,0 +1,155 @@ +#ifndef _EXTRUSION_HPP +#define _EXTRUSION_HPP + +namespace netgen +{ + + class Extrusion; + + class ExtrusionFace : public Surface + { + private: + const SplineSeg<2> * profile; + const SplineGeometry<3> * path; + Vec<3> glob_z_direction; + + bool deletable; + + Array< const SplineSeg3<3> * > spline3_path; + Array< const LineSeg<3> * > line_path; + + mutable Array < Vec<3> > x_dir, y_dir, z_dir, loc_z_dir; + mutable Array < Point<3> > p0; + + mutable Vec<3> profile_tangent; + mutable double profile_par; + + mutable Vector profile_spline_coeff; + + mutable int latest_seg; + mutable double latest_t; + mutable Point<2> latest_point2d; + mutable Point<3> latest_point3d; + + + private: + void Orthogonalize(const Vec<3> & v1, Vec<3> & v2) const; + + void Init(void); + + public: + double CalcProj(const Point<3> & point3d, Point<2> & point2d, + int seg) const; + void CalcProj(const Point<3> & point3d, Point<2> & point2d, + int & seg, double & t) const; + + public: + ExtrusionFace(const SplineSeg<2> * profile_in, + const SplineGeometry<3> * path_in, + const Vec<3> & z_direction); + + ExtrusionFace(const Array & raw_data); + + + ~ExtrusionFace(); + + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + + virtual double CalcFunctionValue (const Point<3> & point) const; + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + virtual double HesseNorm () const; + + virtual double MaxCurvature () const; + //virtual double MaxCurvatureLoc (const Point<3> & /* c */ , + // double /* rad */) const; + + virtual void Project (Point<3> & p) const; + + virtual Point<3> GetSurfacePoint () const; + virtual void Print (ostream & str) const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const; + + const SplineGeometry<3> & GetPath(void) const {return *path;} + const SplineSeg<2> & GetProfile(void) const {return *profile;} + + bool BoxIntersectsFace(const Box<3> & box) const; + + void LineIntersections ( const Point<3> & p, + const Vec<3> & v, + const double eps, + int & before, + int & after, + bool & intersecting ) const; + + INSOLID_TYPE VecInFace ( const Point<3> & p, + const Vec<3> & v, + const double eps ) const; + + const Vec<3> & GetYDir ( void ) const {return y_dir[latest_seg];} + const Vec<3> & GetProfileTangent (void) const {return profile_tangent;} + double GetProfilePar(void) const {return profile_par;} + + void GetRawData(Array & data) const; + + void CalcLocalCoordinates (int seg, double t, + Vec<3> & ex, Vec<3> & ey, Vec<3> & ez) const; + + void CalcLocalCoordinatesDeriv (int seg, double t, + Vec<3> & ex, Vec<3> & ey, Vec<3> & ez, + Vec<3> & dex, Vec<3> & dey, Vec<3> & dez) const; + + }; + + + + class Extrusion : public Primitive + { + private: + const SplineGeometry<3> & path; + const SplineGeometry<2> & profile; + + const Vec<3> & z_direction; + + Array faces; + + mutable int latestfacenum; + + public: + Extrusion(const SplineGeometry<3> & path_in, + const SplineGeometry<2> & profile_in, + const Vec<3> & z_dir); + ~Extrusion(); + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + virtual INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const; + INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps, + Array * const facenums) const; + virtual INSOLID_TYPE VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const; + + // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid + virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + + virtual int GetNSurfaces() const; + virtual Surface & GetSurface (int i = 0); + virtual const Surface & GetSurface (int i = 0) const; + + + virtual void Reduce (const BoxSphere<3> & box); + virtual void UnReduce (); + + }; + +} + +#endif //_EXTRUSION_HPP diff --git a/libsrc/csg/gencyl.cpp b/libsrc/csg/gencyl.cpp new file mode 100644 index 00000000..1305c1b8 --- /dev/null +++ b/libsrc/csg/gencyl.cpp @@ -0,0 +1,179 @@ +#include +#include + + +namespace netgen +{ + + GeneralizedCylinder :: GeneralizedCylinder (ExplicitCurve2d & acrosssection, + Point<3> ap, Vec<3> ae1, Vec<3> ae2) + : crosssection(acrosssection) + { + planep = ap; + planee1 = ae1; + planee2 = ae2; + planee3 = Cross (planee1, planee2); + (*testout) << "Vecs = " << planee1 << " " << planee2 << " " << planee3 << endl; + }; + + + void GeneralizedCylinder :: Project (Point<3> & p) const + { + Point<2> p2d; + double z; + + p2d = Point<2> (planee1 * (p - planep), planee2 * (p - planep)); + z = planee3 * (p - planep); + + crosssection.Project (p2d); + + p = planep + p2d(0) * planee1 + p2d(1) * planee2 + z * planee3; + } + + int GeneralizedCylinder ::BoxInSolid (const BoxSphere<3> & box) const + { + Point<3> p3d; + Point<2> p2d, projp; + double t; + Vec<2> tan, n; + + p3d = box.Center(); + + p2d = Point<2> (planee1 * (p3d - planep), planee2 * (p3d - planep)); + t = crosssection.ProjectParam (p2d); + + projp = crosssection.Eval (t); + tan = crosssection.EvalPrime (t); + n(0) = tan(1); + n(1) = -tan(0); + + if (Dist (p2d, projp) < box.Diam()/2) + return 2; + + if (n * (p2d - projp) > 0) + { + return 0; + } + + return 1; + } + + double GeneralizedCylinder :: CalcFunctionValue (const Point<3> & point) const + { + Point<2> p2d, projp; + double t; + Vec<2> tan, n; + + + p2d = Point<2> (planee1 * (point - planep), planee2 * (point - planep)); + t = crosssection.ProjectParam (p2d); + + projp = crosssection.Eval (t); + tan = crosssection.EvalPrime (t); + n(0) = tan(1); + n(1) = -tan(0); + + n /= n.Length(); + return n * (p2d - projp); + } + + void GeneralizedCylinder :: CalcGradient (const Point<3> & point, Vec<3> & grad) const + { + Point<2> p2d, projp; + double t; + Vec<2> tan, n; + + + p2d = Point<2> (planee1 * (point - planep), planee2 * (point - planep)); + t = crosssection.ProjectParam (p2d); + + projp = crosssection.Eval (t); + tan = crosssection.EvalPrime (t); + n(0) = tan(1); + n(1) = -tan(0); + + n /= n.Length(); + grad = n(0) * planee1 + n(1) * planee2; + } + + + void GeneralizedCylinder :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const + { + Point<2> p2d, projp; + double t, dist, val; + Point<2> curvp; + Vec<2> curvpp; + Mat<2> h2d; + Mat<3,2> vmat; + int i, j, k, l; + + p2d = Point<2> (planee1 * (point - planep), planee2 * (point - planep)); + t = crosssection.ProjectParam (p2d); + + curvp = crosssection.CurvCircle (t); + curvpp = p2d-curvp; + dist = curvpp.Length(); + curvpp /= dist; + + h2d(0, 0) = (1 - curvpp(0) * curvpp(0) ) / dist; + h2d(0, 1) = h2d(1, 0) = (- curvpp(0) * curvpp(1) ) / dist; + h2d(1, 1) = (1 - curvpp(1) * curvpp(1) ) / dist; + + vmat(0,0) = planee1(0); + vmat(1,0) = planee1(1); + vmat(2,0) = planee1(2); + vmat(0,1) = planee2(0); + vmat(1,1) = planee2(1); + vmat(2,1) = planee2(2); + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + { + val = 0; + for (k = 0; k < 2; k++) + for (l = 0; l < 2; l++) + val += vmat(i,k) * h2d(k,l) * vmat(j,l); + hesse(i,j) = val; + } + } + + + double GeneralizedCylinder :: HesseNorm () const + { + return crosssection.MaxCurvature(); + } + + double GeneralizedCylinder :: MaxCurvatureLoc (const Point<3> & c, double rad) const + { + Point<2> c2d = Point<2> (planee1 * (c - planep), planee2 * (c - planep)); + return crosssection.MaxCurvatureLoc(c2d, rad); + } + + + + Point<3> GeneralizedCylinder :: GetSurfacePoint () const + { + Point<2> p2d; + p2d = crosssection.Eval(0); + return planep + p2d(0) * planee1 + p2d(1) * planee2; + } + + void GeneralizedCylinder :: Reduce (const BoxSphere<3> & box) + { + Point<2> c2d = Point<2> (planee1 * (box.Center() - planep), + planee2 * (box.Center() - planep)); + crosssection.Reduce (c2d, box.Diam()/2); + } + + void GeneralizedCylinder :: UnReduce () + { + crosssection.UnReduce (); + } + + void GeneralizedCylinder :: Print (ostream & str) const + { + str << "Generalized Cylinder" << endl; + crosssection.Print (str); + } + +} diff --git a/libsrc/csg/gencyl.hpp b/libsrc/csg/gencyl.hpp new file mode 100644 index 00000000..e5db270d --- /dev/null +++ b/libsrc/csg/gencyl.hpp @@ -0,0 +1,70 @@ +#ifndef FILE_GENCYL +#define FILE_GENCYL + +/**************************************************************************/ +/* File: gencyl.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 14. Oct. 96 */ +/**************************************************************************/ + +namespace netgen +{ + + + /* + + Generalized Cylinder + + */ + + + /// + class GeneralizedCylinder : public Surface + { + /// + ExplicitCurve2d & crosssection; + /// + Point<3> planep; + /// + Vec<3> planee1, planee2, planee3; + + /// Vec<3> ex, ey, ez; + Vec2d e2x, e2y; + /// + Point<3> cp; + + public: + /// + GeneralizedCylinder (ExplicitCurve2d & acrosssection, + Point<3> ap, Vec<3> ae1, Vec<3> ae2); + + /// + virtual void Project (Point<3> & p) const; + + /// + virtual int BoxInSolid (const BoxSphere<3> & box) const; + /// 0 .. no, 1 .. yes, 2 .. maybe + + virtual double CalcFunctionValue (const Point<3> & point) const; + /// + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + /// + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + /// + virtual double HesseNorm () const; + /// + virtual double MaxCurvatureLoc (const Point<3> & c, double rad) const; + /// + virtual Point<3> GetSurfacePoint () const; + /// + virtual void Print (ostream & str) const; + + /// + virtual void Reduce (const BoxSphere<3> & box); + /// + virtual void UnReduce (); + }; + +} + +#endif diff --git a/libsrc/csg/genmesh.cpp b/libsrc/csg/genmesh.cpp new file mode 100644 index 00000000..5e891639 --- /dev/null +++ b/libsrc/csg/genmesh.cpp @@ -0,0 +1,849 @@ +#include + + +#include + +#include +#include +#include + + +namespace netgen +{ + Array specpoints; + static Array spoints; + +#define TCL_OK 0 +#define TCL_ERROR 1 + + + + static void FindPoints (CSGeometry & geom, Mesh & mesh) + { + PrintMessage (1, "Start Findpoints"); + + const char * savetask = multithread.task; + multithread.task = "Find points"; + + for (int i = 0; i < geom.GetNUserPoints(); i++) + { + mesh.AddPoint(geom.GetUserPoint (i)); + mesh.Points().Last().Singularity (geom.GetUserPointRefFactor(i)); + mesh.AddLockedPoint (PointIndex (i+1)); + } + + SpecialPointCalculation spc; + + spc.SetIdEps(geom.GetIdEps()); + + if (spoints.Size() == 0) + spc.CalcSpecialPoints (geom, spoints); + + PrintMessage (2, "Analyze spec points"); + spc.AnalyzeSpecialPoints (geom, spoints, specpoints); + + PrintMessage (5, "done"); + + (*testout) << specpoints.Size() << " special points:" << endl; + for (int i = 0; i < specpoints.Size(); i++) + specpoints[i].Print (*testout); + + /* + for (int i = 1; i <= geom.identifications.Size(); i++) + geom.identifications.Elem(i)->IdentifySpecialPoints (specpoints); + */ + multithread.task = savetask; + } + + + + + + + static void FindEdges (CSGeometry & geom, Mesh & mesh, const bool setmeshsize = false) + { + EdgeCalculation ec (geom, specpoints); + ec.SetIdEps(geom.GetIdEps()); + ec.Calc (mparam.maxh, mesh); + + for (int i = 0; i < geom.singedges.Size(); i++) + { + geom.singedges[i]->FindPointsOnEdge (mesh); + if(setmeshsize) + geom.singedges[i]->SetMeshSize(mesh,10.*geom.BoundingBox().Diam()); + } + for (int i = 0; i < geom.singpoints.Size(); i++) + geom.singpoints[i]->FindPoints (mesh); + + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + //(*testout) << "segment " << mesh.LineSegment(i) << endl; + int ok = 0; + for (int k = 1; k <= mesh.GetNFD(); k++) + if (mesh.GetFaceDescriptor(k).SegmentFits (mesh.LineSegment(i))) + { + ok = k; + //(*testout) << "fits to " << k << endl; + } + + if (!ok) + { + ok = mesh.AddFaceDescriptor (FaceDescriptor (mesh.LineSegment(i))); + //(*testout) << "did not find, now " << ok << endl; + } + + //(*testout) << "change from " << mesh.LineSegment(i).si; + mesh.LineSegment(i).si = ok; + //(*testout) << " to " << mesh.LineSegment(i).si << endl; + } + + if (geom.identifications.Size()) + { + PrintMessage (3, "Find Identifications"); + for (int i = 0; i < geom.identifications.Size(); i++) + { + geom.identifications[i]->IdentifyPoints (mesh); + //(*testout) << "identification " << i << " is " + // << *geom.identifications[i] << endl; + + } + for (int i = 0; i < geom.identifications.Size(); i++) + geom.identifications[i]->IdentifyFaces (mesh); + } + + + // find intersecting segments + PrintMessage (3, "Check intersecting edges"); + + Point3d pmin, pmax; + mesh.GetBox (pmin, pmax); + Box3dTree segtree (pmin, pmax); + + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + if (mesh[si].seginfo) + { + Box<3> hbox; + hbox.Set (mesh[mesh[si][0]]); + hbox.Add (mesh[mesh[si][1]]); + segtree.Insert (hbox.PMin(), hbox.PMax(), si); + } + } + + Array loc; + if (!ec.point_on_edge_problem) + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + if (!mesh[si].seginfo) continue; + + Box<3> hbox; + hbox.Set (mesh[mesh[si][0]]); + hbox.Add (mesh[mesh[si][1]]); + hbox.Increase (1e-6); + segtree.GetIntersecting (hbox.PMin(), hbox.PMax(), loc); + + // for (SegmentIndex sj = 0; sj < si; sj++) + for (int j = 0; j < loc.Size(); j++) + { + SegmentIndex sj = loc[j]; + if (sj >= si) continue; + if (!mesh[si].seginfo || !mesh[sj].seginfo) continue; + if (mesh[mesh[si][0]].GetLayer() != mesh[mesh[sj][1]].GetLayer()) continue; + + Point<3> pi1 = mesh[mesh[si][0]]; + Point<3> pi2 = mesh[mesh[si][1]]; + Point<3> pj1 = mesh[mesh[sj][0]]; + Point<3> pj2 = mesh[mesh[sj][1]]; + Vec<3> vi = pi2 - pi1; + Vec<3> vj = pj2 - pj1; + + if (sqr (vi * vj) > (1.-1e-6) * Abs2 (vi) * Abs2 (vj)) continue; + + // pi1 + vi t = pj1 + vj s + Mat<3,2> mat; + Vec<3> rhs; + Vec<2> sol; + + for (int jj = 0; jj < 3; jj++) + { + mat(jj,0) = vi(jj); + mat(jj,1) = -vj(jj); + rhs(jj) = pj1(jj)-pi1(jj); + } + + mat.Solve (rhs, sol); + + //(*testout) << "mat " << mat << endl << "rhs " << rhs << endl << "sol " << sol << endl; + + if (sol(0) > 1e-6 && sol(0) < 1-1e-6 && + sol(1) > 1e-6 && sol(1) < 1-1e-6 && + Abs (rhs - mat*sol) < 1e-6) + { + Point<3> ip = pi1 + sol(0) * vi; + + //(*testout) << "ip " << ip << endl; + + Point<3> pip = ip; + ProjectToEdge (geom.GetSurface (mesh[si].surfnr1), + geom.GetSurface (mesh[si].surfnr2), pip); + + //(*testout) << "Dist (ip, pip_si) " << Dist (ip, pip) << endl; + if (Dist (ip, pip) > 1e-6*geom.MaxSize()) continue; + pip = ip; + ProjectToEdge (geom.GetSurface (mesh[sj].surfnr1), + geom.GetSurface (mesh[sj].surfnr2), pip); + + //(*testout) << "Dist (ip, pip_sj) " << Dist (ip, pip) << endl; + if (Dist (ip, pip) > 1e-6*geom.MaxSize()) continue; + + + + cout << "Intersection at " << ip << endl; + + geom.AddUserPoint (ip); + spoints.Append (MeshPoint (ip, mesh[mesh[si][0]].GetLayer())); + mesh.AddPoint (ip); + + (*testout) << "found intersection at " << ip << endl; + (*testout) << "sol = " << sol << endl; + (*testout) << "res = " << (rhs - mat*sol) << endl; + (*testout) << "segs = " << pi1 << " - " << pi2 << endl; + (*testout) << "and = " << pj1 << " - " << pj2 << endl << endl; + } + } + } + } + + + + + + + static void MeshSurface (CSGeometry & geom, Mesh & mesh) + { + const char * savetask = multithread.task; + multithread.task = "Surface meshing"; + + Array segments; + int noldp = mesh.GetNP(); + + double starttime = GetTime(); + + // find master faces from identified + Array masterface(mesh.GetNFD()); + for (int i = 1; i <= mesh.GetNFD(); i++) + masterface.Elem(i) = i; + + Array fpairs; + bool changed; + do + { + changed = 0; + for (int i = 0; i < geom.identifications.Size(); i++) + { + geom.identifications[i]->GetIdentifiedFaces (fpairs); + + for (int j = 0; j < fpairs.Size(); j++) + { + if (masterface.Get(fpairs[j].I1()) < + masterface.Get(fpairs[j].I2())) + { + changed = 1; + masterface.Elem(fpairs[j].I2()) = + masterface.Elem(fpairs[j].I1()); + } + if (masterface.Get(fpairs[j].I2()) < + masterface.Get(fpairs[j].I1())) + { + changed = 1; + masterface.Elem(fpairs[j].I1()) = + masterface.Elem(fpairs[j].I2()); + } + } + } + } + while (changed); + + + int bccnt=0; + for (int k = 0; k < geom.GetNSurf(); k++) + bccnt = max2 (bccnt, geom.GetSurface(k)->GetBCProperty()); + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + bool increased = false; + + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + const Surface * surf = geom.GetSurface(fd.SurfNr()); + + if (fd.TLOSurface() && + geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetBCProp() > 0) + fd.SetBCProperty (geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetBCProp()); + else if (surf -> GetBCProperty() != -1) + fd.SetBCProperty (surf->GetBCProperty()); + else + { + bccnt++; + fd.SetBCProperty (bccnt); + increased = true; + } + + for (int l = 0; l < geom.bcmodifications.Size(); l++) + { + if (geom.GetSurfaceClassRepresentant (fd.SurfNr()) == + geom.GetSurfaceClassRepresentant (geom.bcmodifications[l].si) && + (fd.DomainIn() == geom.bcmodifications[l].tlonr+1 || + fd.DomainOut() == geom.bcmodifications[l].tlonr+1)) + { + if(geom.bcmodifications[l].bcname == NULL) + fd.SetBCProperty (geom.bcmodifications[l].bcnr); + else + { + if(!increased) + { + bccnt++; + fd.SetBCProperty (bccnt); + increased = true; + } + } + } + } + } + + mesh.SetNBCNames( bccnt ); + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + const Surface * surf = geom.GetSurface(fd.SurfNr()); + if (fd.TLOSurface() ) + { + int bcp = fd.BCProperty(); + string nextbcname = geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetBCName(); + if ( nextbcname != "default" ) + mesh.SetBCName ( bcp - 1 , nextbcname ); + } + else // if (surf -> GetBCProperty() != -1) + { + int bcp = fd.BCProperty(); + string nextbcname = surf->GetBCName(); + if ( nextbcname != "default" ) + mesh.SetBCName ( bcp - 1, nextbcname ); + } + } + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + fd.SetBCName ( mesh.GetBCNamePtr ( fd.BCProperty() - 1 ) ); + } + + + //!! + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + //const Surface * surf = geom.GetSurface(fd.SurfNr()); + + for (int l = 0; l < geom.bcmodifications.Size(); l++) + { + if (geom.GetSurfaceClassRepresentant (fd.SurfNr()) == + geom.GetSurfaceClassRepresentant (geom.bcmodifications[l].si) && + (fd.DomainIn() == geom.bcmodifications[l].tlonr+1 || + fd.DomainOut() == geom.bcmodifications[l].tlonr+1) && + geom.bcmodifications[l].bcname != NULL + ) + { + int bcp = fd.BCProperty(); + mesh.SetBCName ( bcp - 1, *(geom.bcmodifications[l].bcname) ); + fd.SetBCName ( mesh.GetBCNamePtr ( bcp - 1) ); + } + } + } + + for(int k = 0; k surfs; + geom.GetIndependentSurfaceIndices (geom.singfaces[j]->GetSolid(), + geom.BoundingBox(), surfs); + for (int k = 1; k <= mesh.GetNFD(); k++) + { + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + for (int l = 0; l < surfs.Size(); l++) + if (surfs[l] == fd.SurfNr()) + { + if (geom.singfaces[j]->GetDomainNr() == fd.DomainIn()) + fd.SetDomainInSingular (1); + if (geom.singfaces[j]->GetDomainNr() == fd.DomainOut()) + fd.SetDomainOutSingular (1); + } + } + } + + + // assemble edge hash-table + mesh.CalcSurfacesOfNode(); + + for (int k = 1; k <= mesh.GetNFD(); k++) + { + multithread.percent = 100.0 * k / (mesh.GetNFD()+1e-10); + + if (masterface.Get(k) != k) + continue; + + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + + (*testout) << "Surface " << k << endl; + (*testout) << "Face Descriptor: " << fd << endl; + PrintMessage (1, "Surface ", k, " / ", mesh.GetNFD()); + + int oldnf = mesh.GetNSE(); + + const Surface * surf = + geom.GetSurface((mesh.GetFaceDescriptor(k).SurfNr())); + + + Meshing2Surfaces meshing(*surf, mparam, geom.BoundingBox()); + meshing.SetStartTime (starttime); + + double eps = 1e-8 * geom.MaxSize(); + for (PointIndex pi = PointIndex::BASE; pi < noldp+PointIndex::BASE; pi++) + { + // if(surf->PointOnSurface(mesh[pi])) + meshing.AddPoint (mesh[pi], pi, NULL, + (surf->PointOnSurface(mesh[pi], eps) != 0)); + } + + segments.SetSize (0); + + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + if (mesh[si].si == k) + { + segments.Append (mesh[si]); + (*testout) << "appending segment " << mesh[si] << endl; + //<< " from " << mesh[mesh[si][0]] + // << " to " < + BuildSurfaceElements(segments, mesh, surf); + } + + for (int si = 0; si < segments.Size(); si++) + { + PointGeomInfo gi; + gi.trignum = k; + meshing.AddBoundaryElement (segments[si][0] + 1 - PointIndex::BASE, + segments[si][1] + 1 - PointIndex::BASE, + gi, gi); + } + + double maxh = mparam.maxh; + if (fd.DomainIn() != 0) + { + const Solid * s1 = + geom.GetTopLevelObject(fd.DomainIn()-1) -> GetSolid(); + if (s1->GetMaxH() < maxh) + maxh = s1->GetMaxH(); + maxh = min2(maxh, geom.GetTopLevelObject(fd.DomainIn()-1)->GetMaxH()); + } + if (fd.DomainOut() != 0) + { + const Solid * s1 = + geom.GetTopLevelObject(fd.DomainOut()-1) -> GetSolid(); + if (s1->GetMaxH() < maxh) + maxh = s1->GetMaxH(); + maxh = min2(maxh, geom.GetTopLevelObject(fd.DomainOut()-1)->GetMaxH()); + } + if (fd.TLOSurface() != 0) + { + double hi = geom.GetTopLevelObject(fd.TLOSurface()-1) -> GetMaxH(); + if (hi < maxh) maxh = hi; + } + + (*testout) << "domin = " << fd.DomainIn() << ", domout = " << fd.DomainOut() + << ", tlo-surf = " << fd.TLOSurface() + << " mpram.maxh = " << mparam.maxh << ", maxh = " << maxh << endl; + + mparam.checkoverlap = 0; + + MESHING2_RESULT res = + meshing.GenerateMesh (mesh, mparam, maxh, k); + + if (res != MESHING2_OK) + { + PrintError ("Problem in Surface mesh generation"); + throw NgException ("Problem in Surface mesh generation"); + } + + if (multithread.terminate) return; + + for (SurfaceElementIndex sei = oldnf; sei < mesh.GetNSE(); sei++) + mesh[sei].SetIndex (k); + + + // mesh.CalcSurfacesOfNode(); + + if (segments.Size()) + { + // surface was meshed, not copied + + static int timer = NgProfiler::CreateTimer ("total surface mesh optimization"); + NgProfiler::RegionTimer reg (timer); + + + PrintMessage (2, "Optimize Surface"); + for (int i = 1; i <= mparam.optsteps2d; i++) + { + if (multithread.terminate) return; + + { + MeshOptimize2dSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + meshopt.EdgeSwapping (mesh, (i > mparam.optsteps2d/2)); + } + + if (multithread.terminate) return; + { + // mesh.CalcSurfacesOfNode(); + + MeshOptimize2dSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + meshopt.ImproveMesh (mesh, mparam); + } + + { + MeshOptimize2dSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + meshopt.CombineImprove (mesh); + // mesh.CalcSurfacesOfNode(); + } + + if (multithread.terminate) return; + { + MeshOptimize2dSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + meshopt.ImproveMesh (mesh, mparam); + } + } + } + + + PrintMessage (3, (mesh.GetNSE() - oldnf), " elements, ", mesh.GetNP(), " points"); + + extern void Render(); + Render(); + } + + mesh.Compress(); + + do + { + changed = 0; + for (int k = 1; k <= mesh.GetNFD(); k++) + { + multithread.percent = 100.0 * k / (mesh.GetNFD()+1e-10); + + if (masterface.Get(k) == k) + continue; + + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + + (*testout) << "Surface " << k << endl; + (*testout) << "Face Descriptor: " << fd << endl; + PrintMessage (2, "Surface ", k); + + int oldnf = mesh.GetNSE(); + + const Surface * surf = + geom.GetSurface((mesh.GetFaceDescriptor(k).SurfNr())); + + /* + if (surf -> GetBCProperty() != -1) + fd.SetBCProperty (surf->GetBCProperty()); + else + { + bccnt++; + fd.SetBCProperty (bccnt); + } + */ + + segments.SetSize (0); + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + Segment * seg = &mesh.LineSegment(i); + if (seg->si == k) + segments.Append (*seg); + } + + for (int i = 1; i <= geom.identifications.Size(); i++) + { + geom.identifications.Elem(i)->GetIdentifiedFaces (fpairs); + int found = 0; + for (int j = 1; j <= fpairs.Size(); j++) + if (fpairs.Get(j).I1() == k || fpairs.Get(j).I2() == k) + found = 1; + + if (!found) + continue; + + geom.identifications.Get(i)-> + BuildSurfaceElements(segments, mesh, surf); + if (!segments.Size()) + break; + } + + + if (multithread.terminate) return; + + for (SurfaceElementIndex sei = oldnf; sei < mesh.GetNSE(); sei++) + mesh[sei].SetIndex (k); + + + if (!segments.Size()) + { + masterface.Elem(k) = k; + changed = 1; + } + + PrintMessage (3, (mesh.GetNSE() - oldnf), " elements, ", mesh.GetNP(), " points"); + } + + extern void Render(); + Render(); + } + while (changed); + + + mesh.SplitSeparatedFaces(); + mesh.CalcSurfacesOfNode(); + + multithread.task = savetask; + } + + + + int CSGGenerateMesh (CSGeometry & geom, + Mesh *& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend) + { + if (mesh && mesh->GetNSE() && + !geom.GetNSolids()) + { + if (perfstepsstart < MESHCONST_MESHVOLUME) + perfstepsstart = MESHCONST_MESHVOLUME; + } + + if (perfstepsstart <= MESHCONST_ANALYSE) + { + if (mesh) + mesh -> DeleteMesh(); + else + mesh = new Mesh(); + + mesh->SetGlobalH (mparam.maxh); + mesh->SetMinimalH (mparam.minh); + + Array maxhdom(geom.GetNTopLevelObjects()); + for (int i = 0; i < maxhdom.Size(); i++) + maxhdom[i] = geom.GetTopLevelObject(i)->GetMaxH(); + + mesh->SetMaxHDomain (maxhdom); + + if (mparam.uselocalh) + { + double maxsize = geom.MaxSize(); + mesh->SetLocalH (Point<3>(-maxsize, -maxsize, -maxsize), + Point<3>(maxsize, maxsize, maxsize), + mparam.grading); + + mesh -> LoadLocalMeshSize (mparam.meshsizefilename); + } + + spoints.SetSize(0); + FindPoints (geom, *mesh); + + PrintMessage (5, "find points done"); + +#ifdef LOG_STREAM + (*logout) << "Special points found" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl << endl; +#endif + } + + + if (multithread.terminate || perfstepsend <= MESHCONST_ANALYSE) + return TCL_OK; + + + if (perfstepsstart <= MESHCONST_MESHEDGES) + { + FindEdges (geom, *mesh, true); + if (multithread.terminate) return TCL_OK; +#ifdef LOG_STREAM + (*logout) << "Edges meshed" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + + + if (multithread.terminate) + return TCL_OK; + + if (mparam.uselocalh) + { + mesh->CalcLocalH(mparam.grading); + mesh->DeleteMesh(); + + FindPoints (geom, *mesh); + if (multithread.terminate) return TCL_OK; + FindEdges (geom, *mesh, true); + if (multithread.terminate) return TCL_OK; + + mesh->DeleteMesh(); + + FindPoints (geom, *mesh); + if (multithread.terminate) return TCL_OK; + FindEdges (geom, *mesh); + if (multithread.terminate) return TCL_OK; + } + } + + if (multithread.terminate || perfstepsend <= MESHCONST_MESHEDGES) + return TCL_OK; + + + if (perfstepsstart <= MESHCONST_MESHSURFACE) + { + MeshSurface (geom, *mesh); + if (multithread.terminate) return TCL_OK; + +#ifdef LOG_STREAM + (*logout) << "Surfaces meshed" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + + if (mparam.uselocalh && 0) + { + mesh->CalcLocalH(mparam.grading); + mesh->DeleteMesh(); + + FindPoints (geom, *mesh); + if (multithread.terminate) return TCL_OK; + FindEdges (geom, *mesh); + if (multithread.terminate) return TCL_OK; + + MeshSurface (geom, *mesh); + if (multithread.terminate) return TCL_OK; + } + +#ifdef LOG_STREAM + (*logout) << "Surfaces remeshed" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + +#ifdef STAT_STREAM + (*statout) << mesh->GetNSeg() << " & " + << mesh->GetNSE() << " & - &" + << GetTime() << " & " << endl; +#endif + + MeshQuality2d (*mesh); + mesh->CalcSurfacesOfNode(); + } + + if (multithread.terminate || perfstepsend <= MESHCONST_OPTSURFACE) + return TCL_OK; + + + if (perfstepsstart <= MESHCONST_MESHVOLUME) + { + multithread.task = "Volume meshing"; + + MESHING3_RESULT res = + MeshVolume (mparam, *mesh); + + if (res != MESHING3_OK) return TCL_ERROR; + + if (multithread.terminate) return TCL_OK; + + RemoveIllegalElements (*mesh); + if (multithread.terminate) return TCL_OK; + + MeshQuality3d (*mesh); + + for (int i = 0; i < geom.GetNTopLevelObjects(); i++) + mesh->SetMaterial (i+1, geom.GetTopLevelObject(i)->GetMaterial().c_str()); + + +#ifdef STAT_STREAM + (*statout) << GetTime() << " & "; +#endif + +#ifdef LOG_STREAM + (*logout) << "Volume meshed" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + } + + if (multithread.terminate || perfstepsend <= MESHCONST_MESHVOLUME) + return TCL_OK; + + + if (perfstepsstart <= MESHCONST_OPTVOLUME) + { + multithread.task = "Volume optimization"; + + OptimizeVolume (mparam, *mesh); + if (multithread.terminate) return TCL_OK; + +#ifdef STAT_STREAM + (*statout) << GetTime() << " & " + << mesh->GetNE() << " & " + << mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl; +#endif + +#ifdef LOG_STREAM + (*logout) << "Volume optimized" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + } + + return TCL_OK; + } +} diff --git a/libsrc/csg/geoml.hpp b/libsrc/csg/geoml.hpp new file mode 100644 index 00000000..e7974ad2 --- /dev/null +++ b/libsrc/csg/geoml.hpp @@ -0,0 +1,16 @@ +#ifndef FILE_GEOML +#define FILE_GEOML + +/* *************************************************************************/ +/* File: geoml.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 21. Jun. 98 */ +/* *************************************************************************/ + +#include + +#include +#include +#include +#include +#endif diff --git a/libsrc/csg/identify.cpp b/libsrc/csg/identify.cpp new file mode 100644 index 00000000..e3086a3b --- /dev/null +++ b/libsrc/csg/identify.cpp @@ -0,0 +1,1662 @@ +#include +#include + +#include +#include +#include + + +namespace netgen +{ +Identification :: Identification (int anr, const CSGeometry & ageom) + : geom(ageom), identfaces(10) +{ + nr = anr; +} + +Identification :: ~Identification () +{ + ; +} + + +ostream & operator<< (ostream & ost, Identification & ident) +{ + ident.Print (ost); + return ost; +} + + +/* +void Identification :: IdentifySpecialPoints (Array & points) +{ + ; +} +*/ + + +int Identification :: +Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const +{ + cout << "Identification::Identifyable called for base-class" << endl; + return 0; +} + +int Identification :: +Identifyable (const Point<3> & p1, const Point<3> & sp2) const +{ + cout << "Identification::Identifyable called for base-class" << endl; + return 0; +} + + +int Identification :: +IdentifyableCandidate (const SpecialPoint & sp1) const +{ + return 1; +} + + +int Identification :: +ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const +{ + return 0; +} + +int Identification :: GetIdentifiedPoint (class Mesh & mesh, int pi) +{ + cout << "Identification::GetIdentifiedPoint called for base-class" << endl; + return -1; +} + +void Identification :: IdentifyPoints (Mesh & mesh) +{ + cout << "Identification::IdentifyPoints called for base-class" << endl; + ; +} + +void Identification :: IdentifyFaces (class Mesh & mesh) +{ + cout << "Identification::IdentifyFaces called for base-class" << endl; + ; +} + +void Identification :: +BuildSurfaceElements (Array & segs, + Mesh & mesh, const Surface * surf) +{ + cout << "Identification::BuildSurfaceElements called for base-class" << endl; + ; +} + + +void Identification :: +BuildVolumeElements (Array & surfels, + class Mesh & mesh) +{ + ; +} + +void Identification :: +GetIdentifiedFaces (Array & idfaces) const +{ + idfaces.SetSize(0); + for (int i = 1; i <= identfaces.GetNBags(); i++) + for (int j = 1; j <= identfaces.GetBagSize(i); j++) + { + INDEX_2 i2; + int val; + identfaces.GetData (i, j, i2, val); + idfaces.Append (i2); + } +} + + + + +PeriodicIdentification :: +PeriodicIdentification (int anr, + const CSGeometry & ageom, + const Surface * as1, + const Surface * as2) + : Identification(anr, ageom) +{ + s1 = as1; + s2 = as2; +} + +PeriodicIdentification :: ~PeriodicIdentification () +{ + ; +} + +/* +void PeriodicIdentification :: IdentifySpecialPoints +(Array & points) +{ + int i, j; + int bestj; + double bestval, val; + + for (i = 1; i <= points.Size(); i++) + { + Point<3> p1 = points.Get(i).p; + Point<3> hp1 = p1; + s1->Project (hp1); + if (Dist (p1, hp1) > 1e-6) continue; + + Vec<3> n1; + s1->GetNormalVector (p1, n1); + n1 /= n1.Length(); + if ( fabs(n1 * points.Get(i).v) > 1e-3) + continue; + + bestval = 1e8; + bestj = 1; + for (j = 1; j <= points.Size(); j++) + { + Point<3> p2= points.Get(j).p; + Point<3> hp2 = p2; + s2->Project (hp2); + if (Dist (p2, hp2) > 1e-6) continue; + + Vec<3> n2; + s2->GetNormalVector (p2, n2); + n2 /= n2.Length(); + if ( fabs(n2 * points.Get(j).v) > 1e-3) + continue; + + + Vec<3> v(p1, p2); + double vl = v.Length(); + double cl = fabs (v*n1); + + val = 1 - cl*cl/(vl*vl); + + val += (points.Get(i).v - points.Get(j).v).Length(); + + if (val < bestval) + { + bestj = j; + bestval = val; + } + } + + (*testout) << "Identify Periodic special points: pi = " + << points.Get(i).p << ", vi = " << points.Get(i).v + << " pj = " << points.Get(bestj).p + << ", vj = " << points.Get(bestj).v + << " bestval = " << bestval << endl; + } +} +*/ + +int PeriodicIdentification :: +Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const +{ + int i; + double val; + + SpecialPoint hsp1 = sp1; + SpecialPoint hsp2 = sp2; + + for (i = 1; i <= 1; i++) + { + // Swap (hsp1, hsp2); + + if (!s1->PointOnSurface (hsp1.p)) + continue; + + Vec<3> n1; + n1 = s1->GetNormalVector (hsp1.p); + n1 /= n1.Length(); + if ( fabs(n1 * hsp1.v) > 1e-3) + continue; + + + if (!s2->PointOnSurface(hsp2.p)) + continue; + + Vec<3> n2; + n2 = s2->GetNormalVector (hsp2.p); + n2 /= n2.Length(); + if ( fabs(n2 * hsp2.v) > 1e-3) + continue; + + + Vec<3> v = hsp2.p - hsp1.p; + double vl = v.Length(); + double cl = fabs (v*n1); + + + val = 1 - cl*cl/(vl*vl); + val += (hsp1.v - hsp2.v).Length(); + + if (val < 1e-6) + return 1; + } + + return 0; +} + +int PeriodicIdentification :: +Identifyable (const Point<3> & p1, const Point<3> & p2) const +{ + return (s1->PointOnSurface (p1) && + s2->PointOnSurface (p2)); +} + + + + +int PeriodicIdentification :: +GetIdentifiedPoint (class Mesh & mesh, int pi) +{ + const Surface *snew; + const Point<3> & p = mesh.Point (pi); + + if (s1->PointOnSurface (p)) + { + snew = s2; + } + else + { + if (s2->PointOnSurface (p)) + { + snew = s1; + } + else + { + cerr << "GetIdenfifiedPoint: Not possible" << endl; + exit (1); + } + } + + // project to other surface + Point<3> hp = p; + snew->Project (hp); + + int newpi = 0; + for (int i = 1; i <= mesh.GetNP(); i++) + if (Dist2 (mesh.Point(i), hp) < 1e-12) + { + newpi = i; + break; + } + if (!newpi) + newpi = mesh.AddPoint (hp); + + if (snew == s2) + mesh.GetIdentifications().Add (pi, newpi, nr); + else + mesh.GetIdentifications().Add (newpi, pi, nr); + + mesh.GetIdentifications().SetType(nr,Identifications::PERIODIC); + + /* + (*testout) << "Identify points(periodic), nr = " << nr << ": " << mesh.Point(pi) + << " and " << mesh.Point(newpi) + << ((snew == s2) ? "" : " inverse") + << endl; + */ + return newpi; +} + + +void PeriodicIdentification :: IdentifyPoints (class Mesh & mesh) +{ + int i, j; + for (i = 1; i <= mesh.GetNP(); i++) + { + Point<3> p = mesh.Point(i); + if (s1->PointOnSurface (p)) + { + Point<3> pp = p; + s2->Project (pp); + for (j = 1; j <= mesh.GetNP(); j++) + if (Dist2(mesh.Point(j), pp) < 1e-6) + { + mesh.GetIdentifications().Add (i, j, nr); + /* + (*testout) << "Identify points(periodic:), nr = " << nr << ": " + << mesh.Point(i) << " - " << mesh.Point(j) << endl; + */ + } + } + } + + mesh.GetIdentifications().SetType(nr,Identifications::PERIODIC); +} + + +void PeriodicIdentification :: IdentifyFaces (class Mesh & mesh) +{ + int i, j, k, l; + int fi1, fi2, side; + for (i = 1; i <= mesh.GetNFD(); i++) + for (j = 1; j <= mesh.GetNFD(); j++) + { + int surfi = mesh.GetFaceDescriptor(i).SurfNr(); + int surfj = mesh.GetFaceDescriptor(j).SurfNr(); + if (surfi == surfj) + continue; + + if (geom.GetSurface (surfi) != s1 || + geom.GetSurface (surfj) != s2) + continue; + + int idok = 1; + + + // (*testout) << "check faces " << i << " and " << j << endl; + for (side = 1; side <= 2 && idok; side++) + { + if (side == 1) + { + fi1 = i; + fi2 = j; + } + else + { + fi1 = j; + fi2 = i; + } + + for (k = 1; k <= mesh.GetNSeg(); k++) + { + const Segment & seg1 = mesh.LineSegment(k); + if (seg1.si != fi1) + continue; + + int foundother = 0; + for (l = 1; l <= mesh.GetNSeg(); l++) + { + const Segment & seg2 = mesh.LineSegment(l); + if (seg2.si != fi2) + continue; + + // (*testout) << "seg1 = " << seg1[0] << "-" << seg1[1] << ", seg2 = " << seg2[0] << "-" << seg2[1]; + + if (side == 1) + { + if (mesh.GetIdentifications().Get (seg1[0], seg2[0]) && + mesh.GetIdentifications().Get (seg1[1], seg2[1])) + { + foundother = 1; + break; + } + + if (mesh.GetIdentifications().Get (seg1[0], seg2[1]) && + mesh.GetIdentifications().Get (seg1[1], seg2[0])) + { + foundother = 1; + break; + } + } + else + { + if (mesh.GetIdentifications().Get (seg2[0], seg1[0]) && + mesh.GetIdentifications().Get (seg2[1], seg1[1])) + { + foundother = 1; + break; + } + + if (mesh.GetIdentifications().Get (seg2[0], seg1[1]) && + mesh.GetIdentifications().Get (seg2[1], seg1[0])) + { + foundother = 1; + break; + } + } + } + + if (!foundother) + { + idok = 0; + break; + } + } + } + + + if (idok) + { + // (*testout) << "Identify faces " << i << " and " << j << endl; + INDEX_2 fpair(i,j); + fpair.Sort(); + identfaces.Set (fpair, 1); + } + } +} + + + +void PeriodicIdentification :: +BuildSurfaceElements (Array & segs, + Mesh & mesh, const Surface * surf) +{ + int found = 0; + int fother = -1; + + int facei = segs.Get(1).si; + int surfnr = mesh.GetFaceDescriptor(facei).SurfNr(); + + if (geom.GetSurface(surfnr) == s1 || + geom.GetSurface(surfnr) == s2) + { + Array copy_points; + + for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & sel = mesh[sei]; + INDEX_2 fpair (facei, sel.GetIndex()); + fpair.Sort(); + if (identfaces.Used (fpair)) + { + for (int k = 0; k < sel.GetNP(); k++) + if (!copy_points.Contains (sel[k])) + copy_points.Append (sel[k]); + } + } + BubbleSort (copy_points); + for (int k = 0; k < copy_points.Size(); k++) + GetIdentifiedPoint (mesh, copy_points[k]); + + + + for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & sel = mesh[sei]; + INDEX_2 fpair (facei, sel.GetIndex()); + fpair.Sort(); + if (identfaces.Used (fpair)) + { + found = 1; + fother = sel.GetIndex(); + + // copy element + Element2d newel(sel.GetType()); + newel.SetIndex (facei); + for (int k = 0; k < sel.GetNP(); k++) + newel[k] = GetIdentifiedPoint (mesh, sel[k]); + + Vec<3> nt = Cross (Point<3> (mesh[newel[1]])- Point<3> (mesh[newel[0]]), + Point<3> (mesh[newel[2]])- Point<3> (mesh[newel[0]])); + + Vec<3> nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh[newel[0]]); + if (nsurf * nt < 0) + Swap (newel[0], newel[2]); + + mesh.AddSurfaceElement (newel); + } + } + } + + if (found) + { + // (*mycout) << " copy face " << facei << " from face " << fother; + PrintMessage (4, " copy face ", facei, " from face ", fother); + + segs.SetSize(0); + } +} + + + + + + + + +void PeriodicIdentification :: Print (ostream & ost) const +{ + ost << "Periodic Identifiaction, surfaces: " + << s1->Name() << " - " << s2->Name() << endl; + s1->Print (ost); + ost << " - "; + s2->Print (ost); + ost << endl; +} + + +void PeriodicIdentification :: GetData (ostream & ost) const +{ + ost << "periodic " << s1->Name() << " " << s2->Name(); +} + + + + + + + +CloseSurfaceIdentification :: +CloseSurfaceIdentification (int anr, + const CSGeometry & ageom, + const Surface * as1, + const Surface * as2, + const TopLevelObject * adomain, + const Flags & flags) + : Identification(anr, ageom) +{ + s1 = as1; + s2 = as2; + domain = adomain; + ref_levels = int (flags.GetNumFlag ("reflevels", 2)); + ref_levels_s1 = int (flags.GetNumFlag ("reflevels1", 0)); + ref_levels_s2 = int (flags.GetNumFlag ("reflevels2", 0)); + slices = flags.GetNumListFlag ("slices"); + for(int i=0; i0 && slices[i] <= slices[i-1]) || + (slices[i] >= 1)) + throw NgException ("slices have to be in ascending order, between 0 and 1"); + + // eps_n = 1e-3; + eps_n = 1e-6; + + dom_surf_valid = 0; + + if (domain) + for (int i = 0; i < geom.GetNTopLevelObjects(); i++) + if (domain == geom.GetTopLevelObject(i)) + dom_nr = i; + + usedirection = flags.NumListFlagDefined("direction"); + if(usedirection) + { + for(int i=0; i<3; i++) + direction(i) = flags.GetNumListFlag("direction")[i]; + + direction.Normalize(); + } +} + +CloseSurfaceIdentification :: ~CloseSurfaceIdentification () +{ + ; +} + +void CloseSurfaceIdentification :: Print (ostream & ost) const +{ + ost << "CloseSurface Identifiaction, surfaces: " + << s1->Name() << " - " << s2->Name() << endl; + s1->Print (ost); + s2->Print (ost); + ost << endl; +} + + +void CloseSurfaceIdentification :: GetData (ostream & ost) const +{ + ost << "close surface " << s1->Name() << " " << s2->Name(); +} + + +/* +void CloseSurfaceIdentification :: IdentifySpecialPoints +(Array & points) +{ + int i, j; + int bestj; + double bestval, val; + + for (i = 1; i <= points.Size(); i++) + { + Point<3> p1 = points.Get(i).p; + Vec<3> n1; + + if (!s1->PointOnSurface (p1)) + continue; + + s1->GetNormalVector (p1, n1); + n1 /= n1.Length(); + if ( fabs(n1 * points.Get(i).v) > 1e-3) + continue; + + bestval = 1e8; + bestj = 1; + for (j = 1; j <= points.Size(); j++) + { + Point<3> p2= points.Get(j).p; + if (!s2->PointOnSurface (p2)) + continue; + + Vec<3> n2; + s2->GetNormalVector (p2, n2); + n2 /= n2.Length(); + if ( fabs(n2 * points.Get(j).v) > 1e-3) + continue; + + + Vec<3> v(p1, p2); + double vl = v.Length(); + double cl = fabs (v*n1); + + val = 1 - cl*cl/(vl*vl); + + val += (points.Get(i).v - points.Get(j).v).Length(); + + if (val < bestval) + { + bestj = j; + bestval = val; + } + } + + (*testout) << "Identify close surfaces special points: pi = " + << points.Get(i).p << ", vi = " << points.Get(i).v + << " pj = " << points.Get(bestj).p + << ", vj = " << points.Get(bestj).v + << " bestval = " << bestval << endl; + } +} +*/ + +int CloseSurfaceIdentification :: +Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const +{ + //(*testout) << "identcheck: " << sp1.p << "; " << sp2.p << endl; + + if (!dom_surf_valid) + { + const_cast (dom_surf_valid) = 1; + Array & hsurf = const_cast&> (domain_surfaces); + + if (domain) + { + BoxSphere<3> hbox (geom.BoundingBox()); + geom.GetIndependentSurfaceIndices (domain->GetSolid(), hbox, hsurf); + //(*testout) << "surfs of identification " << nr << ": " << endl << hsurf << endl; + } + else + { + hsurf.SetSize (geom.GetNSurf()); + for (int j = 0; j < hsurf.Size(); j++) + hsurf[j] = j; + } + } + + if (domain) + { + bool has1 = 0, has2 = 0; + for (int i = 0; i < specpoint2solid[sp1.nr].Size(); i++) + if (specpoint2solid[sp1.nr][i] == dom_nr) + { has1 = 1; break; } + for (int i = 0; i < specpoint2solid[sp2.nr].Size(); i++) + if (specpoint2solid[sp2.nr][i] == dom_nr) + { has2 = 1; break; } + + if (!has1 || !has2) + { + //(*testout) << "failed at pos1" << endl; + return 0; + } + } + + if (!s1->PointOnSurface (sp1.p)) + { + //(*testout) << "failed at pos2" << endl; + return 0; + } + +// (*testout) << "sp1 " << sp1.p << " sp2 " << sp2.p << endl +// << "specpoint2solid[sp1.nr] " << specpoint2solid[sp1.nr] << endl +// << "specpoint2solid[sp2.nr] " << specpoint2solid[sp2.nr] << endl; + + + Vec<3> n1 = s1->GetNormalVector (sp1.p); + n1.Normalize(); + if ( fabs(n1 * sp1.v) > eps_n) + { + //(*testout) << "failed at pos3" << endl; + return 0; + } + + if (!s2->PointOnSurface(sp2.p)) + { + //(*testout) << "failed at pos4" << endl; + return 0; + } + + + Vec<3> n2 = s2->GetNormalVector (sp2.p); + n2.Normalize(); + if ( fabs(n2 * sp2.v) > eps_n) + { + //(*testout) << "failed at pos5" << endl; + return 0; + } + + // must have joint surface + bool joint = 0; + + int j = 0, k = 0; + while (1) + { + int snr1 = specpoint2surface[sp1.nr][j]; + int snr2 = specpoint2surface[sp2.nr][k]; + if (snr1 < snr2) + { + j++; + if (j == specpoint2surface[sp1.nr].Size()) break; + } + else if (snr2 < snr1) + { + k++; + if (k == specpoint2surface[sp2.nr].Size()) break; + } + else + { + bool dom_surf = 0; + for (int l = 0; l < domain_surfaces.Size(); l++) + if (domain_surfaces[l] == snr1) + dom_surf = 1; + + if (dom_surf) + { + Vec<3> hn1 = geom.GetSurface(snr1)->GetNormalVector (sp1.p); + Vec<3> hn2 = geom.GetSurface(snr1)->GetNormalVector (sp2.p); + + if (hn1 * hn2 > 0) + { + joint = 1; + break; + } + } + + j++; + if (j == specpoint2surface[sp1.nr].Size()) break; + k++; + if (k == specpoint2surface[sp2.nr].Size()) break; + } + } + + if (!joint) + { + //(*testout) << "failed at pos6" << endl; + return 0; + } + + Vec<3> v = sp2.p - sp1.p; + double vl = v.Length(); + double cl = (usedirection) ? fabs(v*direction) : fabs (v*n1); + + + if(cl <= (1-eps_n*eps_n) * vl) + { + //(*testout) << "failed at pos7" << endl; + return 0; + } + + double dl; + + if(usedirection) + { + Vec<3> v1 = sp1.v - (sp1.v*direction)*direction; v1.Normalize(); + Vec<3> v2 = sp2.v - (sp2.v*direction)*direction; v2.Normalize(); + + dl = (v1 - v2).Length(); + } + else + dl = (sp1.v - sp2.v).Length(); + + if (dl < 0.1) + return 1; + + + //(*testout) << "failed at pos8" << endl; + return 0; +} + +int CloseSurfaceIdentification :: +Identifyable (const Point<3> & p1, const Point<3> & p2) const +{ +// if (domain) +// if (!domain->GetSolid()->IsIn (p1) || !domain->GetSolid()->IsIn (p2)) +// return 0; + return (s1->PointOnSurface (p1) && s2->PointOnSurface (p2)); +} + + + + +int CloseSurfaceIdentification :: +IdentifyableCandidate (const SpecialPoint & sp1) const +{ + if (domain) + if (!domain->GetSolid()->IsIn (sp1.p)) + return 0; + + if (s1->PointOnSurface (sp1.p)) + { + Vec<3> n1; + n1 = s1->GetNormalVector (sp1.p); + n1.Normalize(); + if ( fabs(n1 * sp1.v) > eps_n) + return 0; + return 1; + } + + if (s2->PointOnSurface (sp1.p)) + { + Vec<3> n1; + n1 = s2->GetNormalVector (sp1.p); + n1.Normalize(); + if ( fabs(n1 * sp1.v) > eps_n) + return 0; + return 1; + } + return 0; +} + + + +int CloseSurfaceIdentification :: +ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const +{ + if ( (s1->PointOnSurface (sp1.p) && s2->PointOnSurface (sp2.p)) || + (s1->PointOnSurface (sp2.p) && s2->PointOnSurface (sp1.p)) ) + { + return 1; + } + return 0; +} + + + +int CloseSurfaceIdentification :: +GetIdentifiedPoint (class Mesh & mesh, int pi) +{ + const Surface *snew; + const Point<3> & p = mesh.Point (pi); + + Array identmap(mesh.GetNP()); + mesh.GetIdentifications().GetMap (nr, identmap); + if (identmap.Get(pi)) + return identmap.Get(pi); + + + if (s1->PointOnSurface (p)) + snew = s2; + else if (s2->PointOnSurface (p)) + snew = s1; + else + { + (*testout) << "GetIdenfifiedPoint: Not possible" << endl; + (*testout) << "p = " << p << endl; + (*testout) << "surf1: " << (*s1) << endl + << "surf2: " << (*s2) << endl; + + cerr << "GetIdenfifiedPoint: Not possible" << endl; + throw NgException ("GetIdenfifiedPoint: Not possible"); + } + + // project to other surface + Point<3> hp = p; + if(usedirection) + snew->SkewProject(hp,direction); + else + snew->Project (hp); + + //(*testout) << "projecting " << p << " to " << hp << endl; + + int newpi = 0; + for (int i = 1; i <= mesh.GetNP(); i++) + if (Dist2 (mesh.Point(i), hp) < 1e-12) + // if (Dist2 (mesh.Point(i), hp) < 1 * Dist2 (hp, p)) + { + newpi = i; + break; + } + if (!newpi) + newpi = mesh.AddPoint (hp); + + if (snew == s2) + { + mesh.GetIdentifications().Add (pi, newpi, nr); + //(*testout) << "add identification(1) " << pi << " - " << newpi << ", " << nr << endl; + } + else + { + mesh.GetIdentifications().Add (newpi, pi, nr); + //(*testout) << "add identification(2) " << newpi << " - " << pi << ", " << nr << endl; + } + mesh.GetIdentifications().SetType(nr,Identifications::CLOSESURFACES); + + + /* + (*testout) << "Identify points(closesurface), nr = " << nr << ": " << mesh.Point(pi) + << " and " << mesh.Point(newpi) + << ((snew == s2) ? "" : " inverse") + << endl; + */ + return newpi; +} + + + + + +void CloseSurfaceIdentification :: IdentifyPoints (Mesh & mesh) +{ + int np = mesh.GetNP(); + + Array points_on_surf2; + + for (int i2 = 1; i2 <= np; i2++) + if (s2->PointOnSurface (mesh.Point(i2))) + points_on_surf2.Append (i2); + + Array surfs_of_p1; + + for (int i1 = 1; i1 <= np; i1++) + { + Point<3> p1 = mesh.Point(i1); + // (*testout) << "p1 = " << i1 << " = " << p1 << endl; + if (domain && !domain->GetSolid()->IsIn (p1)) + continue; + + //if(domain) (*testout) << "p1 is in " << domain->GetSolid()->Name() << endl; + + if (s1->PointOnSurface (p1)) + { + int candi2 = 0; + double mindist = 1e10; + + Vec<3> n1; + n1 = s1->GetNormalVector (p1); + n1.Normalize(); + + surfs_of_p1.SetSize(0); + for (int jj = 0; jj < domain_surfaces.Size(); jj++) + { + int j = domain_surfaces[jj]; + if (geom.GetSurface(j) -> PointOnSurface(p1)) + surfs_of_p1.Append (j); + } + //(*testout) << " surfs of p1 = " << endl << surfs_of_p1 << endl; + + for (int ii2 = 0; ii2 < points_on_surf2.Size(); ii2++) + { + int i2 = points_on_surf2[ii2]; + if (i2 == i1) continue; + const Point<3> p2 = mesh.Point(i2); + + Vec<3> n = p2 - p1; + n.Normalize(); + + bool joint = 0; + for (int jj = 0; jj < surfs_of_p1.Size(); jj++) + { + int j = surfs_of_p1[jj]; + if (geom.GetSurface(j) -> PointOnSurface(p2)) + { + Vec<3> hn1 = geom.GetSurface(j)->GetNormalVector (p1); + Vec<3> hn2 = geom.GetSurface(j)->GetNormalVector (p2); + + if (hn1 * hn2 > 0) + { + joint = 1; + break; + } + } + } + + if (!joint) continue; + + if(usedirection) + { + if (fabs (n*direction) > 0.9) + { + Vec<3> p1p2 = p2-p1; + double ndist = p1p2.Length2() - pow(p1p2*direction,2); + if(ndist < mindist) + { + candi2 = i2; + mindist = ndist; + } + } + + } + else + { + if (fabs (n * n1) > 0.9 && + Dist (p1, p2) < mindist) + { + candi2 = i2; + mindist = Dist (p1, p2); + } + } + + } + + if (candi2) + { + //(*testout) << "identify points " << p1 << " - " << mesh.Point(candi2) << endl; + + /* + (*testout) << "Add Identification from CSI2, nr = " << nr << ", p1 = " + << i1 << " = " + << mesh[PointIndex(i1)] << ", p2 = " << candi2 << " = " + << mesh[PointIndex(candi2)] << endl; + */ + mesh.GetIdentifications().Add (i1, candi2, nr); + mesh.GetIdentifications().SetType(nr,Identifications::CLOSESURFACES); + //(*testout) << "add identification " << i1 << " - " << candi2 << ", " << nr << endl; + } + } + } +} + + + +void CloseSurfaceIdentification :: IdentifyFaces (class Mesh & mesh) +{ + int fi1, fi2, side; + int s1rep = -1, s2rep = -1; + + for (int i = 0; i < geom.GetNSurf(); i++) + { + if (geom.GetSurface (i) == s1) + s1rep = geom.GetSurfaceClassRepresentant(i); + if (geom.GetSurface (i) == s2) + s2rep = geom.GetSurfaceClassRepresentant(i); + } + + Array segs_on_face1, segs_on_face2; + + identfaces.DeleteData(); + + //(*testout) << "identify faces, nr = " << nr << endl; + + for (int i = 1; i <= mesh.GetNFD(); i++) + { + int surfi = mesh.GetFaceDescriptor(i).SurfNr(); + if (s1rep != surfi) continue; + + + if (domain && + domain != geom.GetTopLevelObject (mesh.GetFaceDescriptor(i).DomainIn()-1) && + domain != geom.GetTopLevelObject (mesh.GetFaceDescriptor(i).DomainOut()-1)) + continue; + + for (int j = 1; j <= mesh.GetNFD(); j++) + { + int surfj = mesh.GetFaceDescriptor(j).SurfNr(); + + if (surfi == surfj) continue; + if (s2rep != surfj) continue; + + + int idok = 1; + + for (side = 1; side <= 2 && idok; side++) + { + if (side == 1) + { + fi1 = i; + fi2 = j; + } + else + { + fi1 = j; + fi2 = i; + } + + + segs_on_face1.SetSize(0); + segs_on_face2.SetSize(0); + + for (int k = 1; k <= mesh.GetNSeg(); k++) + { + if (mesh.LineSegment(k).si == fi1) + segs_on_face1.Append (k); + if (mesh.LineSegment(k).si == fi2) + segs_on_face2.Append (k); + } + + + for (int k = 1; k <= mesh.GetNSeg(); k++) + { + const Segment & seg1 = mesh.LineSegment(k); + if (seg1.si != fi1) + continue; + + int foundother = 0; + /* + for (int l = 1; l <= mesh.GetNSeg(); l++) + { + const Segment & seg2 = mesh.LineSegment(l); + if (seg2.si != fi2) + continue; + */ + for (int ll = 0; ll < segs_on_face2.Size(); ll++) + { + int l = segs_on_face2[ll]; + const Segment & seg2 = mesh.LineSegment(l); + + if (side == 1) + { + if (mesh.GetIdentifications().Get (seg1[0], seg2[0]) && + mesh.GetIdentifications().Get (seg1[1], seg2[1])) + { + foundother = 1; + break; + } + + if (mesh.GetIdentifications().Get (seg1[0], seg2[1]) && + mesh.GetIdentifications().Get (seg1[1], seg2[0])) + { + foundother = 1; + break; + } + } + else + { + if (mesh.GetIdentifications().Get (seg2[0], seg1[0]) && + mesh.GetIdentifications().Get (seg2[1], seg1[1])) + { + foundother = 1; + break; + } + + if (mesh.GetIdentifications().Get (seg2[0], seg1[1]) && + mesh.GetIdentifications().Get (seg2[1], seg1[0])) + { + foundother = 1; + break; + } + } + } + + if (!foundother) + { + idok = 0; + break; + } + } + } + + + if (idok) + { + //(*testout) << "Identification " << nr << ", identify faces " << i << " and " << j << endl; + INDEX_2 fpair(i,j); + fpair.Sort(); + identfaces.Set (fpair, 1); + } + } + } +} + + + +void CloseSurfaceIdentification :: +BuildSurfaceElements (Array & segs, + Mesh & mesh, const Surface * surf) +{ + bool found = 0; + int cntquads = 0; + + Array identmap; + identmap = 0; + + mesh.GetIdentifications().GetMap (nr, identmap); + + for (int i = PointIndex::BASE; i < identmap.Size()+PointIndex::BASE; i++) + if (identmap[i]) identmap[identmap[i]] = i; + + + //(*testout) << "identification nr = " << nr << endl; + //(*testout) << "surf = " << (*surf) << endl; + //(*testout) << "domain = " << domain->GetSolid()->Name() << endl; + //(*testout) << "segs = " << endl << segs << endl; + //(*testout) << "identmap = " << endl << identmap << endl; + + //Array foundseg(segs.Size()); + //foundseg = false; + + // insert quad layer: + for (int i1 = 0; i1 < segs.Size(); i1++) + { + const Segment & s1 = segs[i1]; + if (identmap[s1[0]] && identmap[s1[1]]) + for (int i2 = 0; i2 < i1; i2++) + { + const Segment & s2 = segs[i2]; + //(*testout) << "checking " << s1 << " and " << s2 << " for ident." << endl; + + if(domain && !((s1.domin == dom_nr || + s1.domout == dom_nr) && + (s2.domin == dom_nr || + s2.domout == dom_nr))) + continue; + + if ((mesh.GetIdentifications().Get (s1[0], s2[1], nr) && + mesh.GetIdentifications().Get (s1[1], s2[0], nr)) || + (mesh.GetIdentifications().Get (s2[0], s1[1], nr) && + mesh.GetIdentifications().Get (s2[1], s1[0], nr))) + { + Element2d el(s1[0], s1[1], s2[0], s2[1]); + + Vec<3> n = Cross (mesh[el[1]] - mesh[el[0]], + mesh[el[3]] - mesh[el[0]]); + + Vec<3> ns = surf->GetNormalVector (mesh[el[0]]); + + if (n * ns < 0) + { + Swap (el.PNum(1), el.PNum(2)); + Swap (el.PNum(3), el.PNum(4)); + } + + mesh.AddSurfaceElement (el); +// (*testout) << "(id nr "<< nr <<") add rect element: " +// << mesh.Point (el.PNum(1)) << " - " +// << mesh.Point (el.PNum(2)) << " - " +// << mesh.Point (el.PNum(3)) << " - " +// << mesh.Point (el.PNum(4)) << endl; + found = true; + //foundseg[i1]=foundseg[i2] = true; + cntquads++; + } + } + } + if (found) + { + PrintMessage(3, "insert quad layer of ", cntquads, + " elements at face ", segs.Get(1).si); + //Array aux; + //for(int i=0; i & segs, + Mesh & mesh, const Surface * surf) +{ + // copy mesh + + + // (*testout) << "copy trig face, identnr = " << nr << endl; + // (*testout) << "identfaces = " << endl << identfaces << endl; + + if (!segs.Size()) return; + + bool found = 0; + int fother = -1; + + int facei = segs[0].si; + int surfnr = mesh.GetFaceDescriptor(facei).SurfNr(); + + + bool foundid = 0; + for (INDEX_2_HASHTABLE::Iterator it = identfaces.Begin(); + it != identfaces.End(); it++) + { + INDEX_2 i2; + int data; + identfaces.GetData (it, i2, data); + if (i2.I1() == facei || i2.I2() == facei) + foundid = 1; + } + + /* + for (int i = 1; i <= identfaces.GetNBags(); i++) + for (int j = 1; j <= identfaces.GetBagSize(i); j++) + { + INDEX_2 i2; + int data; + identfaces.GetData (i, j, i2, data); + if (i2.I1() == facei || i2.I2() == facei) + foundid = 1; + + (*testout) << "identface = " << i2 << endl; + (*testout) << "face " << i2.I1() << " = " << mesh.GetFaceDescriptor(i2.I1()) << endl; + (*testout) << "face " << i2.I2() << " = " << mesh.GetFaceDescriptor(i2.I2()) << endl; + } + */ + + if (foundid) + { + // (*testout) << "surfaces found" << endl; + // copy surface + for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & sel = mesh[sei]; + INDEX_2 fpair (facei, sel.GetIndex()); + fpair.Sort(); + if (identfaces.Used (fpair)) + { + found = 1; + fother = sel.GetIndex(); + + // copy element + Element2d newel(sel.GetType()); + newel.SetIndex (facei); + for (int k = 1; k <= sel.GetNP(); k++) + newel.PNum(k) = GetIdentifiedPoint (mesh, sel.PNum(k)); + + Vec<3> nt = Cross (Point<3> (mesh.Point (newel.PNum(2)))- + Point<3> (mesh.Point (newel.PNum(1))), + Point<3> (mesh.Point (newel.PNum(3)))- + Point<3> (mesh.Point (newel.PNum(1)))); + Vec<3> nsurf; + nsurf = geom.GetSurface (surfnr)->GetNormalVector (mesh.Point(newel.PNum(1))); + if (nsurf * nt < 0) + Swap (newel.PNum(2), newel.PNum(3)); + + mesh.AddSurfaceElement (newel); + } + } + } + + if (found) + { + // (*mycout) << " copy face " << facei << " from face " << fother; + PrintMessage (4, " copy face ", facei, " from face ", fother); + segs.SetSize(0); + } +} + + + + + + + + + + + + + + +void CloseSurfaceIdentification :: +BuildVolumeElements (Array & surfels, + class Mesh & mesh) +{ + ; +} + + + + + + + + + + + + + +/* ***************** Close Edges Identification ********** */ + + + +CloseEdgesIdentification :: +CloseEdgesIdentification (int anr, + const CSGeometry & ageom, + const Surface * afacet, + const Surface * as1, + const Surface * as2) + : Identification(anr, ageom) +{ + facet = afacet; + s1 = as1; + s2 = as2; +} + +CloseEdgesIdentification :: ~CloseEdgesIdentification () +{ + ; +} + +void CloseEdgesIdentification :: Print (ostream & ost) const +{ + ost << "CloseEdges Identifiaction, facet = " + << facet->Name() << ", surfaces: " + << s1->Name() << " - " << s2->Name() << endl; + facet->Print (ost); + s1->Print (ost); + s2->Print (ost); + ost << endl; +} + + +void CloseEdgesIdentification :: GetData (ostream & ost) const +{ + ost << "closeedges " << facet->Name() << " " + << s1->Name() << " " << s2->Name(); +} + + +/* +void CloseEdgesIdentification :: IdentifySpecialPoints +(Array & points) +{ + int i, j; + int bestj; + double bestval, val; + + for (i = 1; i <= points.Size(); i++) + { + Point<3> p1 = points.Get(i).p; + Vec<3> n1; + + if (!s1->PointOnSurface (p1)) + continue; + + s1->GetNormalVector (p1, n1); + n1 /= n1.Length(); + if ( fabs(n1 * points.Get(i).v) > 1e-3) + continue; + + bestval = 1e8; + bestj = 1; + for (j = 1; j <= points.Size(); j++) + { + Point<3> p2= points.Get(j).p; + if (!s2->PointOnSurface (p2)) + continue; + + Vec<3> n2; + s2->GetNormalVector (p2, n2); + n2 /= n2.Length(); + if ( fabs(n2 * points.Get(j).v) > 1e-3) + continue; + + + Vec<3> v(p1, p2); + double vl = v.Length(); + double cl = fabs (v*n1); + + val = 1 - cl*cl/(vl*vl); + + val += (points.Get(i).v - points.Get(j).v).Length(); + + if (val < bestval) + { + bestj = j; + bestval = val; + } + } + + (*testout) << "Identify close surfaces special points: pi = " + << points.Get(i).p << ", vi = " << points.Get(i).v + << " pj = " << points.Get(bestj).p + << ", vj = " << points.Get(bestj).v + << " bestval = " << bestval << endl; + } +} +*/ + +int CloseEdgesIdentification :: +Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const +{ + int i; + double val; + + SpecialPoint hsp1 = sp1; + SpecialPoint hsp2 = sp2; + + for (i = 1; i <= 1; i++) + { + if (!s1->PointOnSurface (hsp1.p)) + continue; + + Vec<3> n1; + n1 = s1->GetNormalVector (hsp1.p); + n1 /= n1.Length(); + if ( fabs(n1 * hsp1.v) > 1e-3) + continue; + + + if (!s2->PointOnSurface(hsp2.p)) + continue; + + Vec<3> n2; + n2 = s2->GetNormalVector (hsp2.p); + n2 /= n2.Length(); + if ( fabs(n2 * hsp2.v) > 1e-3) + continue; + + + Vec<3> v = hsp2.p - hsp1.p; + double vl = v.Length(); + double cl = fabs (v*n1); + + + val = 1 - cl*cl/(vl*vl); + val += (hsp1.v - hsp2.v).Length(); + + if (val < 1e-3) + { + return 1; + } + } + + return 0; +} + + + + +void CloseEdgesIdentification :: IdentifyPoints (Mesh & mesh) +{ + int np = mesh.GetNP(); + for (int i1 = 1; i1 <= np; i1++) + for (int i2 = 1; i2 <= np; i2++) + { + if (i2 == i1) + continue; + + const Point<3> p1 = mesh.Point(i1); + const Point<3> p2 = mesh.Point(i2); + Point<3> pp1 = p1; + Point<3> pp2 = p2; + + s1->Project (pp1); + facet->Project (pp1); + s2->Project (pp2); + facet->Project (pp2); + + if (Dist (p1, pp1) > 1e-6 || Dist (p2, pp2) > 1e-6) + continue; + + Vec<3> n1, nf, t; + Vec<3> n = p2 - p1; + n.Normalize(); + + n1 = s1->GetNormalVector (p1); + nf = facet->GetNormalVector (p1); + t = Cross (n1, nf); + t /= t.Length(); + + if (fabs (n * t) < 0.5) + { + (*testout) << "close edges identify points " << p1 << " - " << p2 << endl; + mesh.GetIdentifications().Add (i1, i2, nr); + mesh.GetIdentifications().SetType(nr,Identifications::CLOSEEDGES); + } + } +} + +void CloseEdgesIdentification :: +BuildSurfaceElements (Array & segs, + Mesh & mesh, const Surface * surf) +{ + int found = 0; + + if (surf != facet) + return; + + for (int i1 = 1; i1 <= segs.Size(); i1++) + for (int i2 = 1; i2 < i1; i2++) + { + const Segment & s1 = segs.Get(i1); + const Segment & s2 = segs.Get(i2); + if (mesh.GetIdentifications().Get (s1[0], s2[1]) && + mesh.GetIdentifications().Get (s1[1], s2[0])) + { + Element2d el(QUAD); + el.PNum(1) = s1[0]; + el.PNum(2) = s1[1]; + el.PNum(3) = s2[1]; + el.PNum(4) = s2[0]; + + Vec<3> n = Cross (Point<3> (mesh.Point(el.PNum(2)))- + Point<3> (mesh.Point(el.PNum(1))), + Point<3> (mesh.Point(el.PNum(3)))- + Point<3> (mesh.Point(el.PNum(1)))); + Vec<3> ns; + ns = surf->GetNormalVector (mesh.Point(el.PNum(1))); + //(*testout) << "n = " << n << " ns = " << ns << endl; + if (n * ns < 0) + { + //(*testout) << "Swap the quad" << endl; + Swap (el.PNum(1), el.PNum(2)); + Swap (el.PNum(3), el.PNum(4)); + } + + + Swap (el.PNum(3), el.PNum(4)); + mesh.AddSurfaceElement (el); +// (*testout) << "add rect element: " +// << mesh.Point (el.PNum(1)) << " - " +// << mesh.Point (el.PNum(2)) << " - " +// << mesh.Point (el.PNum(3)) << " - " +// << mesh.Point (el.PNum(4)) << endl; + found = 1; + } + } + + if (found) + segs.SetSize(0); +} + +} + diff --git a/libsrc/csg/identify.hpp b/libsrc/csg/identify.hpp new file mode 100644 index 00000000..ef3f7556 --- /dev/null +++ b/libsrc/csg/identify.hpp @@ -0,0 +1,210 @@ + +#ifndef FILE_IDENTIFY +#define FILE_IDENTIFY + +/**************************************************************************/ +/* File: identify.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 1. Aug. 99 */ +/**************************************************************************/ + + +namespace netgen +{ + + /** + Identify surfaces for periodic b.c. or + thin domains + */ + + + class SpecialPoint; + class Identification + { + protected: + const CSGeometry & geom; + // identified faces, index sorted + INDEX_2_HASHTABLE identfaces; + int nr; + + public: + DLL_HEADER Identification (int anr, const CSGeometry & ageom); + DLL_HEADER virtual ~Identification (); + DLL_HEADER virtual void Print (ostream & ost) const = 0; + DLL_HEADER virtual void GetData (ostream & ost) const = 0; + + /// obsolete + // virtual void IdentifySpecialPoints (Array & points); + + /// can identify both special points (fixed direction) + /// (identified points, same tangent) + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const; + /// + virtual int Identifyable (const Point<3> & p1, const Point<3> & sp2) const; + /// is it possible to identify sp1 with some other ? + virtual int IdentifyableCandidate (const SpecialPoint & sp1) const; + + /// are points (if connected) by a short edge (direction anyhow) ? + virtual int ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const; + + /// add entries in mesh identification tables + virtual void IdentifyPoints (class Mesh & mesh); + + /// add entries to identified faces (based on segment infos) + virtual void IdentifyFaces (class Mesh & mesh); + + /// get point on other surface, add entry in mesh identifications + virtual int GetIdentifiedPoint (class Mesh & mesh, int pi1); + + /// copy surfaces, or fill rectangles + virtual void BuildSurfaceElements (Array & segs, + class Mesh & mesh, + const Surface * surf); + + /// insert volume elements in thin layers + virtual void BuildVolumeElements (Array & surfels, + class Mesh & mesh); + + /// get list of identified faces + virtual void GetIdentifiedFaces (Array & idfaces) const; + + friend ostream & operator<< (ostream & ost, Identification & ident); + }; + + + class PeriodicIdentification : public Identification + { + const Surface * s1; + const Surface * s2; + public: + PeriodicIdentification (int anr, + const CSGeometry & ageom, + const Surface * as1, + const Surface * as2); + virtual ~PeriodicIdentification (); + virtual void Print (ostream & ost) const; + virtual void GetData (ostream & ost) const; + + + // virtual void IdentifySpecialPoints (Array & points); + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const; + + virtual int Identifyable (const Point<3> & p1, const Point<3> & sp2) const; + virtual int GetIdentifiedPoint (class Mesh & mesh, int pi1); + virtual void IdentifyPoints (class Mesh & mesh); + virtual void IdentifyFaces (class Mesh & mesh); + virtual void BuildSurfaceElements (Array & segs, + class Mesh & mesh, + const Surface * surf); + }; + + + /// + class TopLevelObject; + class CloseSurfaceIdentification : public Identification + { + const Surface * s1; + const Surface * s2; + const TopLevelObject * domain; + /// + int dom_nr; + /// number of refinement levels (in Z-refinement) + int ref_levels; + /// number of refinement levels for layer next to s1 (in Z-refinement) + int ref_levels_s1; + /// number of refinement levels for layer next to s2 (in Z-refinement) + int ref_levels_s2; + /// + double eps_n; + Array slices; + /// used only for domain-local identification: + Array domain_surfaces; + /// + bool dom_surf_valid; + + /// + Vec<3> direction; + /// + bool usedirection; + public: + CloseSurfaceIdentification (int anr, + const CSGeometry & ageom, + const Surface * as1, + const Surface * as2, + const TopLevelObject * adomain, + const Flags & flags); + virtual ~CloseSurfaceIdentification (); + + virtual void Print (ostream & ost) const; + virtual void GetData (ostream & ost) const; + + + // virtual void IdentifySpecialPoints (Array & points); + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const; + virtual int Identifyable (const Point<3> & p1, const Point<3> & sp2) const; + virtual int IdentifyableCandidate (const SpecialPoint & sp1) const; + virtual int ShortEdge (const SpecialPoint & sp1, const SpecialPoint & sp2) const; + virtual int GetIdentifiedPoint (class Mesh & mesh, int pi1); + const Array & GetSlices () const { return slices; } + virtual void IdentifyPoints (class Mesh & mesh); + virtual void IdentifyFaces (class Mesh & mesh); + virtual void BuildSurfaceElements (Array & segs, + class Mesh & mesh, + const Surface * surf); + void BuildSurfaceElements2 (Array & segs, + class Mesh & mesh, + const Surface * surf); + + virtual void BuildVolumeElements (Array & surfels, + class Mesh & mesh); + + int RefLevels () const { return ref_levels; } + int RefLevels1 () const { return ref_levels_s1; } + int RefLevels2 () const { return ref_levels_s2; } + + bool IsSkewIdentification(void) const {return usedirection;} + const Vec<3> & GetDirection(void) const {return direction;} + + const Surface & GetSurface1(void) const + { return *s1;} + const Surface & GetSurface2(void) const + { return *s2;} + }; + + + class CloseEdgesIdentification : public Identification + { + const Surface * facet; + const Surface * s1; + const Surface * s2; + public: + CloseEdgesIdentification (int anr, + const CSGeometry & ageom, + const Surface * afacet, + const Surface * as1, + const Surface * as2); + virtual ~CloseEdgesIdentification (); + virtual void Print (ostream & ost) const; + virtual void GetData (ostream & ost) const; + + // virtual void IdentifySpecialPoints (Array & points); + virtual int Identifyable (const SpecialPoint & sp1, const SpecialPoint & sp2, + const TABLE & specpoint2solid, + const TABLE & specpoint2surface) const; + + + virtual void IdentifyPoints (class Mesh & mesh); + virtual void BuildSurfaceElements (Array & segs, + class Mesh & mesh, + const Surface * surf); + }; + +} + +#endif diff --git a/libsrc/csg/manifold.cpp b/libsrc/csg/manifold.cpp new file mode 100644 index 00000000..9733389d --- /dev/null +++ b/libsrc/csg/manifold.cpp @@ -0,0 +1,14 @@ +#include + +namespace netgen +{ +Manifold :: Manifold () +{ + ; +} + +Manifold :: ~Manifold () +{ + ; +} +} diff --git a/libsrc/csg/manifold.hpp b/libsrc/csg/manifold.hpp new file mode 100644 index 00000000..cc60e955 --- /dev/null +++ b/libsrc/csg/manifold.hpp @@ -0,0 +1,29 @@ +#ifndef FILE_MANIFOLD +#define FILE_MANIFOLD + +/**************************************************************************/ +/* File: manifold.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 7. Aug. 96 */ +/**************************************************************************/ + +namespace netgen +{ + + + /** + Basis class for manifolds in 2d and 3d + */ + class Manifold + { + public: + /// + Manifold (); + /// + virtual ~Manifold (); + }; + +} + + +#endif diff --git a/libsrc/csg/meshsurf.cpp b/libsrc/csg/meshsurf.cpp new file mode 100644 index 00000000..19e12eb2 --- /dev/null +++ b/libsrc/csg/meshsurf.cpp @@ -0,0 +1,211 @@ +#include + +#include +#include + + + +namespace netgen +{ + /* +Meshing2Surfaces :: Meshing2Surfaces (const Surface & asurface) + : surface(asurface) +{ + ; +} + */ +Meshing2Surfaces :: Meshing2Surfaces (const Surface & asurf, + const MeshingParameters & mp, + const Box<3> & abb) + : Meshing2(mp, abb), surface(asurf) +{ + ; +} + + +void Meshing2Surfaces :: DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo1, + const PointGeomInfo * geominfo2) +{ + ((Surface&)surface).DefineTangentialPlane (p1, p2); +} + +void Meshing2Surfaces :: TransformToPlain (const Point3d & locpoint, + const MultiPointGeomInfo & geominfo, + Point2d & planepoint, + double h, int & zone) +{ + Point<2> hp; + surface.ToPlane (locpoint, hp, h, zone); + planepoint.X() = hp(0); + planepoint.Y() = hp(1); +} + +int Meshing2Surfaces :: TransformFromPlain (Point2d & planepoint, + Point3d & locpoint, + PointGeomInfo & gi, + double h) +{ + Point<3> hp; + Point<2> hp2 (planepoint.X(), planepoint.Y()); + surface.FromPlane (hp2, hp, h); + locpoint = hp; + gi.trignum = 1; + return 0; +} + + + +double Meshing2Surfaces :: CalcLocalH (const Point3d & p, double gh) const +{ + return surface.LocH (p, 3, 1, gh); + /* + double loch = mesh.lochfunc->GetH(p); + if (gh < loch) loch = gh; + return loch; + */ +} + + + + + + +MeshOptimize2dSurfaces :: MeshOptimize2dSurfaces (const CSGeometry & ageometry) + : MeshOptimize2d(), geometry(ageometry) +{ + ; +} + + +void MeshOptimize2dSurfaces :: ProjectPoint (INDEX surfind, Point<3> & p) const +{ + Point<3> hp = p; + geometry.GetSurface(surfind)->Project (hp); + p = hp; +} + +void MeshOptimize2dSurfaces :: ProjectPoint2 (INDEX surfind, INDEX surfind2, + Point<3> & p) const +{ + Point<3> hp = p; + ProjectToEdge ( geometry.GetSurface(surfind), + geometry.GetSurface(surfind2), hp); + p = hp; +} + + +void MeshOptimize2dSurfaces :: +GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const +{ + Vec<3> hn = n; + geometry.GetSurface(surfind)->CalcGradient (p, hn); + hn.Normalize(); + n = hn; + + /* + if (geometry.GetSurface(surfind)->Inverse()) + n *= -1; + */ +} + + + + + + + +RefinementSurfaces :: RefinementSurfaces (const CSGeometry & ageometry) + : Refinement(), geometry(ageometry) +{ + if(geometry.GetNSurf() == 0) + *testout << endl + << "WARNING: Intializing 2D refinement with 0-surface geometry" << endl + << "==========================================================" << endl + << endl << endl; +} + +RefinementSurfaces :: ~RefinementSurfaces () +{ + ; +} + +void RefinementSurfaces :: +PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const +{ + Point<3> hnewp; + hnewp = p1+secpoint*(p2-p1); + if (surfi != -1) + { + geometry.GetSurface (surfi) -> Project (hnewp); + newgi.trignum = 1; + } + + newp = hnewp; +} + +void RefinementSurfaces :: +PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const +{ + Point<3> hnewp = p1+secpoint*(p2-p1); + //(*testout) << "hnewp " << hnewp << " s1 " << surfi1 << " s2 " << surfi2 << endl; + if (surfi1 != -1 && surfi2 != -1 && surfi1 != surfi2) + { + netgen::ProjectToEdge (geometry.GetSurface(surfi1), + geometry.GetSurface(surfi2), + hnewp); + // (*testout) << "Pointbetween, newp = " << hnewp << endl + // << ", err = " << sqrt (sqr (hnewp(0))+ sqr(hnewp(1)) + sqr (hnewp(2))) - 1 << endl; + newgi.edgenr = 1; + //(*testout) << "hnewp (a1) " << hnewp << endl; + } + else if (surfi1 != -1) + { + geometry.GetSurface (surfi1) -> Project (hnewp); + //(*testout) << "hnewp (a2) " << hnewp << endl; + } + + newp = hnewp; +}; + +Vec<3> RefinementSurfaces :: GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const +{ + Vec<3> n1 = geometry.GetSurface (surfi1)->GetNormalVector (p); + Vec<3> n2 = geometry.GetSurface (surfi2)->GetNormalVector (p); + Vec<3> tau = Cross (n1, n2).Normalize(); + return tau; +} + +Vec<3> RefinementSurfaces :: GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const +{ + return geometry.GetSurface (surfi1)->GetNormalVector (p); +} + + + +void RefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi) const +{ + if (surfi != -1) + geometry.GetSurface (surfi) -> Project (p); +}; + +void RefinementSurfaces :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const +{ + netgen::ProjectToEdge (geometry.GetSurface(surfi1), + geometry.GetSurface(surfi2), + p); + +} + + +} diff --git a/libsrc/csg/meshsurf.hpp b/libsrc/csg/meshsurf.hpp new file mode 100644 index 00000000..e6c69225 --- /dev/null +++ b/libsrc/csg/meshsurf.hpp @@ -0,0 +1,97 @@ +#ifndef FILE_MESHSURF +#define FILE_MESHSURF + +namespace netgen +{ + + /// + class Meshing2Surfaces : public Meshing2 + { + /// + const Surface & surface; + + public: + /// + // Meshing2Surfaces (const Surface & asurf); + /// + Meshing2Surfaces (const Surface & asurf, const MeshingParameters & mp, + const Box<3> & aboundingbox); + + protected: + /// + virtual void DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo1, + const PointGeomInfo * geominfo2); + /// + virtual void TransformToPlain (const Point3d & locpoint, + const MultiPointGeomInfo & geominfo, + Point2d & plainpoint, + double h, int & zone); + /// + virtual int TransformFromPlain (Point2d & plainpoint, + Point3d & locpoint, + PointGeomInfo & gi, + double h); + /// + virtual double CalcLocalH (const Point3d & p, double gh) const; + }; + + + + /// + class MeshOptimize2dSurfaces : public MeshOptimize2d + { + /// + const CSGeometry & geometry; + + public: + /// + MeshOptimize2dSurfaces (const CSGeometry & ageometry); + + /// + virtual void ProjectPoint (INDEX surfind, Point<3> & p) const; + /// + virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const; + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const; + }; + + + + class RefinementSurfaces : public Refinement + { + const CSGeometry & geometry; + + public: + RefinementSurfaces (const CSGeometry & ageometry); + virtual ~RefinementSurfaces (); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const; + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const; + + virtual Vec<3> GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const; + + virtual Vec<3> GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const; + + + virtual void ProjectToSurface (Point<3> & p, int surfi) const; + + virtual void ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const; + + }; + +} + +#endif + diff --git a/libsrc/csg/polyhedra.cpp b/libsrc/csg/polyhedra.cpp new file mode 100644 index 00000000..a09d7433 --- /dev/null +++ b/libsrc/csg/polyhedra.cpp @@ -0,0 +1,738 @@ +#include + +#include +#include + +namespace netgen +{ + +Polyhedra::Face::Face (int pi1, int pi2, int pi3, + const Array > & points, + int ainputnr) +{ + inputnr = ainputnr; + + pnums[0] = pi1; + pnums[1] = pi2; + pnums[2] = pi3; + + + bbox.Set (points[pi1]); + bbox.Add (points[pi2]); + bbox.Add (points[pi3]); + + v1 = points[pi2] - points[pi1]; + v2 = points[pi3] - points[pi1]; + + n = Cross (v1, v2); + + nn = n; + nn.Normalize(); + // PseudoInverse (v1, v2, w1, w2); + + Mat<2,3> mat; + Mat<3,2> inv; + for (int i = 0; i < 3; i++) + { + mat(0,i) = v1(i); + mat(1,i) = v2(i); + } + CalcInverse (mat, inv); + for (int i = 0; i < 3; i++) + { + w1(i) = inv(i,0); + w2(i) = inv(i,1); + } +} + + +Polyhedra :: Polyhedra () +{ + surfaceactive.SetSize(0); + surfaceids.SetSize(0); + eps_base1 = 1e-8; +} + +Polyhedra :: ~Polyhedra () +{ + ; +} + +Primitive * Polyhedra :: CreateDefault () +{ + return new Polyhedra(); +} + +INSOLID_TYPE Polyhedra :: BoxInSolid (const BoxSphere<3> & box) const +{ + /* + for (i = 1; i <= faces.Size(); i++) + if (FaceBoxIntersection (i, box)) + return DOES_INTERSECT; + */ + for (int i = 0; i < faces.Size(); i++) + { + if (!faces[i].bbox.Intersect (box)) + continue; + //(*testout) << "face " << i << endl; + + const Point<3> & p1 = points[faces[i].pnums[0]]; + const Point<3> & p2 = points[faces[i].pnums[1]]; + const Point<3> & p3 = points[faces[i].pnums[2]]; + + if (fabs (faces[i].nn * (p1 - box.Center())) > box.Diam()/2) + continue; + + //(*testout) << "still in loop" << endl; + + double dist2 = MinDistTP2 (p1, p2, p3, box.Center()); + //(*testout) << "p1 " << p1 << " p2 " << p2 << " p3 " << p3 << endl + // << " box.Center " << box.Center() << " box.Diam() " << box.Diam() << endl + // << " dist2 " << dist2 << " sqr(box.Diam()/2) " << sqr(box.Diam()/2) << endl; + if (dist2 < sqr (box.Diam()/2)) + { + //(*testout) << "DOES_INTERSECT" << endl; + return DOES_INTERSECT; + } + }; + + return PointInSolid (box.Center(), 1e-3 * box.Diam()); +} + + +INSOLID_TYPE Polyhedra :: PointInSolid (const Point<3> & p, + double eps) const +{ + //(*testout) << "PointInSolid p " << p << " eps " << eps << endl; + //(*testout) << "bbox " << poly_bbox << endl; + + if((p(0) > poly_bbox.PMax()(0) + eps) || (p(0) < poly_bbox.PMin()(0) - eps) || + (p(1) > poly_bbox.PMax()(1) + eps) || (p(1) < poly_bbox.PMin()(1) - eps) || + (p(2) > poly_bbox.PMax()(2) + eps) || (p(2) < poly_bbox.PMin()(2) - eps)) + { + //(*testout) << "returning IS_OUTSIDE" << endl; + return IS_OUTSIDE; + } + + Vec<3> n, v1, v2; + + // random (?) numbers: + n(0) = -0.424621; + n(1) = 0.15432; + n(2) = 0.89212238; + + int cnt = 0; + + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + + double lam3 = faces[i].nn * v0; + + if(fabs(lam3) < eps) + { + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + { + //(*testout) << "returning DOES_INTERSECT" << endl; + return DOES_INTERSECT; + } + } + else + { + lam3 = -(faces[i].n * v0) / (faces[i].n * n); + + if (lam3 < 0) continue; + + Vec<3> rs = v0 + lam3 * n; + + double lam1 = (faces[i].w1 * rs); + double lam2 = (faces[i].w2 * rs); + if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1) + cnt++; + } + + } + + //(*testout) << " cnt = " << cnt%2 << endl; + return (cnt % 2) ? IS_INSIDE : IS_OUTSIDE; +} + + + + +void Polyhedra :: GetTangentialSurfaceIndices (const Point<3> & p, + Array & surfind, double eps) const +{ + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + double lam3 = -(faces[i].nn * v0); // n->nn + + if (fabs (lam3) > eps) continue; + + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + if (!surfind.Contains (GetSurfaceId(i))) + surfind.Append (GetSurfaceId(i)); + } + +} + + + +INSOLID_TYPE Polyhedra :: VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const +{ + Array point_on_faces; + INSOLID_TYPE res(DOES_INTERSECT); + + Vec<3> vn = v; + vn.Normalize(); + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + double lam3 = -(faces[i].nn * v0); // n->nn + + + if (fabs (lam3) > eps) continue; + //(*testout) << "lam3 <= eps" << endl; + + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + { + point_on_faces.Append(i); + + double scal = vn * faces[i].nn; // n->nn + + res = DOES_INTERSECT; + if (scal > eps_base1) res = IS_OUTSIDE; + if (scal < -eps_base1) res = IS_INSIDE; + } + } + + //(*testout) << "point_on_faces.Size() " << point_on_faces.Size() + // << " res " << res << endl; + + if (point_on_faces.Size() == 0) + return PointInSolid (p, 0); + if (point_on_faces.Size() == 1) + return res; + + + + + double mindist(0); + bool first = true; + + for(int i=0; i eps && (first || dist < mindist)) + { + mindist = dist; + first = false; + } + } + } + + Point<3> p2 = p + (1e-2*mindist) * vn; + res = PointInSolid (p2, eps); + + // (*testout) << "mindist " << mindist << " res " << res << endl; + + return res; + + +} + + +/* +INSOLID_TYPE Polyhedra :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + INSOLID_TYPE res; + + res = VecInSolid(p,v1,eps); + if(res != DOES_INTERSECT) + return res; + + int point_on_n_faces = 0; + + Vec<3> v1n = v1; + v1n.Normalize(); + Vec<3> v2n = v2; + v2n.Normalize(); + + + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + double lam3 = -(faces[i].n * v0); + + if (fabs (lam3) > eps) continue; + + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + + if (lam1 >= -eps && lam2 >= -eps && lam1+lam2 <= 1+eps) + { + double scal1 = v1n * faces[i].n; + if (fabs (scal1) > eps) continue; + + + point_on_n_faces++; + + double scal2 = v2n * faces[i].n; + res = DOES_INTERSECT; + if (scal2 > eps) res = IS_OUTSIDE; + if (scal2 < -eps) res = IS_INSIDE; + } + } + + if (point_on_n_faces == 1) + return res; + + cerr << "primitive::vecinsolid2 makes nonsense for polyhedra" << endl; + + return Primitive :: VecInSolid2 (p, v1, v2, eps); +} +*/ + + + +INSOLID_TYPE Polyhedra :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + //(*testout) << "VecInSolid2 eps " << eps << endl; + INSOLID_TYPE res = VecInSolid(p,v1,eps); + //(*testout) << "VecInSolid = " < v1n = v1; + v1n.Normalize(); + Vec<3> v2n = v2 - (v2 * v1n) * v1n; + v2n.Normalize(); + + double cosv2, cosv2max = -99; + + + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + if (fabs (faces[i].nn * v0) > eps) continue; // n->nn + if (fabs (v1n * faces[i].nn) > eps_base1) continue; // n->nn + + double lam1 = (faces[i].w1 * v0); + double lam2 = (faces[i].w2 * v0); + + if (lam1 >= -eps_base1 && lam2 >= -eps_base1 && lam1+lam2 <= 1+eps_base1) + { + // v1 is in face + + Point<3> fc = Center (points[faces[i].pnums[0]], + points[faces[i].pnums[1]], + points[faces[i].pnums[2]]); + + Vec<3> vpfc = fc - p; + cosv2 = (v2n * vpfc) / vpfc.Length(); + if (cosv2 > cosv2max) + { + cosv2max = cosv2; + point_on_n_faces++; + + double scal2 = v2n * faces[i].nn; // n->nn + res = DOES_INTERSECT; + if (scal2 > eps_base1) res = IS_OUTSIDE; + if (scal2 < -eps_base1) res = IS_INSIDE; + + } + } + } + + if (point_on_n_faces >= 1) + return res; + + (*testout) << "primitive::vecinsolid2 makes nonsense for polyhedra" << endl; + cerr << "primitive::vecinsolid2 makes nonsense for polyhedra" << endl; + + return Primitive :: VecInSolid2 (p, v1, v2, eps); +} + + + +void Polyhedra :: GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + Array & surfind, double eps) const +{ + Vec<3> v1n = v1; + v1n.Normalize(); + Vec<3> v2n = v2; // - (v2 * v1n) * v1n; + v2n.Normalize(); + + + for (int i = 0; i < faces.Size(); i++) + { + const Point<3> & p1 = points[faces[i].pnums[0]]; + + Vec<3> v0 = p - p1; + if (fabs (v0 * faces[i].nn) > eps) continue; // n->nn + if (fabs (v1n * faces[i].nn) > eps_base1) continue; // n->nn + if (fabs (v2n * faces[i].nn) > eps_base1) continue; // n->nn + + double lam01 = (faces[i].w1 * v0); + double lam02 = (faces[i].w2 * v0); + double lam03 = 1-lam01-lam02; + double lam11 = (faces[i].w1 * v1); + double lam12 = (faces[i].w2 * v1); + double lam13 = -lam11-lam12; + double lam21 = (faces[i].w1 * v2); + double lam22 = (faces[i].w2 * v2); + double lam23 = -lam21-lam22; + + bool ok1 = lam01 > eps_base1 || + (lam01 > -eps_base1 && lam11 > eps_base1) || + (lam01 > -eps_base1 && lam11 > -eps_base1 && lam21 > eps_base1); + + bool ok2 = lam02 > eps_base1 || + (lam02 > -eps_base1 && lam12 > eps_base1) || + (lam02 > -eps_base1 && lam12 > -eps_base1 && lam22 > eps_base1); + + bool ok3 = lam03 > eps_base1 || + (lam03 > -eps_base1 && lam13 > eps_base1) || + (lam03 > -eps_base1 && lam13 > -eps_base1 && lam23 > eps_base1); + + if (ok1 && ok2 && ok3) + { + if (!surfind.Contains (GetSurfaceId(faces[i].planenr))) + surfind.Append (GetSurfaceId(faces[i].planenr)); + } + } +} + + + + + + + + + + + + +void Polyhedra :: GetPrimitiveData (const char *& classname, + Array & coeffs) const +{ + classname = "Polyhedra"; + coeffs.SetSize(0); + coeffs.Append (points.Size()); + coeffs.Append (faces.Size()); + coeffs.Append (planes.Size()); + + /* + int i, j; + for (i = 1; i <= planes.Size(); i++) + { + planes.Elem(i)->Print (*testout); + } + for (i = 1; i <= faces.Size(); i++) + { + (*testout) << "face " << i << " has plane " << faces.Get(i).planenr << endl; + for (j = 1; j <= 3; j++) + (*testout) << points.Get(faces.Get(i).pnums[j-1]); + (*testout) << endl; + } + */ +} + +void Polyhedra :: SetPrimitiveData (Array & /* coeffs */) +{ + ; +} + +void Polyhedra :: Reduce (const BoxSphere<3> & box) +{ + for (int i = 0; i < planes.Size(); i++) + surfaceactive[i] = 0; + + for (int i = 0; i < faces.Size(); i++) + if (FaceBoxIntersection (i, box)) + surfaceactive[faces[i].planenr] = 1; +} + +void Polyhedra :: UnReduce () +{ + for (int i = 0; i < planes.Size(); i++) + surfaceactive[i] = 1; +} + +int Polyhedra :: AddPoint (const Point<3> & p) +{ + if(points.Size() == 0) + poly_bbox.Set(p); + else + poly_bbox.Add(p); + + return points.Append (p); +} + +int Polyhedra :: AddFace (int pi1, int pi2, int pi3, int inputnum) +{ + (*testout) << "polyhedra, add face " << pi1 << ", " << pi2 << ", " << pi3 << endl; + + if(pi1 == pi2 || pi2 == pi3 || pi3 == pi1) + { + ostringstream msg; + msg << "Illegal point numbers for polyhedron face: " << pi1+1 << ", " << pi2+1 << ", " << pi3+1; + throw NgException(msg.str()); + } + + faces.Append (Face (pi1, pi2, pi3, points, inputnum)); + + Point<3> p1 = points[pi1]; + Point<3> p2 = points[pi2]; + Point<3> p3 = points[pi3]; + + Vec<3> v1 = p2 - p1; + Vec<3> v2 = p3 - p1; + + Vec<3> n = Cross (v1, v2); + n.Normalize(); + + Plane pl (p1, n); +// int inverse; +// int identicto = -1; +// for (int i = 0; i < planes.Size(); i++) +// if (pl.IsIdentic (*planes[i], inverse, 1e-9*max3(v1.Length(),v2.Length(),Dist(p2,p3)))) +// { +// if (!inverse) +// identicto = i; +// } +// // cout << "is identic = " << identicto << endl; +// identicto = -1; // changed April 10, JS + +// if (identicto != -1) +// faces.Last().planenr = identicto; +// else + { + planes.Append (new Plane (p1, n)); + surfaceactive.Append (1); + surfaceids.Append (0); + faces.Last().planenr = planes.Size()-1; + } + +// (*testout) << "is plane nr " << faces.Last().planenr << endl; + + return faces.Size(); +} + + + +int Polyhedra :: FaceBoxIntersection (int fnr, const BoxSphere<3> & box) const +{ + /* + (*testout) << "check face box intersection, fnr = " << fnr << endl; + (*testout) << "box = " << box << endl; + (*testout) << "face-box = " << faces[fnr].bbox << endl; + */ + + if (!faces[fnr].bbox.Intersect (box)) + return 0; + + const Point<3> & p1 = points[faces[fnr].pnums[0]]; + const Point<3> & p2 = points[faces[fnr].pnums[1]]; + const Point<3> & p3 = points[faces[fnr].pnums[2]]; + + double dist2 = MinDistTP2 (p1, p2, p3, box.Center()); + /* + (*testout) << "p1 = " << p1 << endl; + (*testout) << "p2 = " << p2 << endl; + (*testout) << "p3 = " << p3 << endl; + + (*testout) << "box.Center() = " << box.Center() << endl; + (*testout) << "center = " << box.Center() << endl; + (*testout) << "dist2 = " << dist2 << endl; + (*testout) << "diam = " << box.Diam() << endl; + */ + if (dist2 < sqr (box.Diam()/2)) + { + // (*testout) << "intersect" << endl; + return 1; + } + return 0; +} + + +void Polyhedra :: GetPolySurfs(Array < Array * > & polysurfs) +{ + int maxnum = -1; + + for(int i = 0; i maxnum) + maxnum = faces[i].inputnr; + } + + polysurfs.SetSize(maxnum+1); + for(int i=0; i; + + for(int i = 0; iAppend(faces[i].planenr); +} + + +void Polyhedra::CalcSpecialPoints (Array > & pts) const +{ + for (int i = 0; i < points.Size(); i++) + pts.Append (points[i]); +} + + +void Polyhedra :: AnalyzeSpecialPoint (const Point<3> & /* pt */, + Array > & /* specpts */) const +{ + ; +} + +Vec<3> Polyhedra :: SpecialPointTangentialVector (const Point<3> & p, int s1, int s2) const +{ + const double eps = 1e-10*poly_bbox.Diam(); + + for (int fi1 = 0; fi1 < faces.Size(); fi1++) + for (int fi2 = 0; fi2 < faces.Size(); fi2++) + { + int si1 = faces[fi1].planenr; + int si2 = faces[fi2].planenr; + + if (surfaceids[si1] != s1 || surfaceids[si2] != s2) continue; + + //(*testout) << "check pair fi1/fi2 " << fi1 << "/" << fi2 << endl; + + Vec<3> n1 = GetSurface(si1) . GetNormalVector (p); + Vec<3> n2 = GetSurface(si2) . GetNormalVector (p); + Vec<3> t = Cross (n1, n2); + + //(*testout) << "t = " << t << endl; + + + /* + int samepts = 0; + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + if (Dist(points[faces[fi1].pnums[j]], + points[faces[fi2].pnums[k]]) < eps) + samepts++; + if (samepts < 2) continue; + */ + + bool shareedge = false; + for(int j = 0; !shareedge && j < 3; j++) + { + Vec<3> v1 = points[faces[fi1].pnums[(j+1)%3]] - points[faces[fi1].pnums[j]]; + double smax = v1.Length(); + v1 *= 1./smax; + + int pospos; + if(fabs(v1(0)) > 0.5) + pospos = 0; + else if(fabs(v1(1)) > 0.5) + pospos = 1; + else + pospos = 2; + + double sp = (p(pospos) - points[faces[fi1].pnums[j]](pospos)) / v1(pospos); + if(sp < -eps || sp > smax+eps) + continue; + + for (int k = 0; !shareedge && k < 3; k ++) + { + Vec<3> v2 = points[faces[fi2].pnums[(k+1)%3]] - points[faces[fi2].pnums[k]]; + v2.Normalize(); + if(v2 * v1 > 0) + v2 -= v1; + else + v2 += v1; + + //(*testout) << "v2.Length2() " << v2.Length2() << endl; + + if(v2.Length2() > 1e-18) + continue; + + double sa,sb; + + sa = (points[faces[fi2].pnums[k]](pospos) - points[faces[fi1].pnums[j]](pospos)) / v1(pospos); + sb = (points[faces[fi2].pnums[(k+1)%3]](pospos) - points[faces[fi1].pnums[j]](pospos)) / v1(pospos); + + + if(Dist(points[faces[fi1].pnums[j]] + sa*v1, points[faces[fi2].pnums[k]]) > eps) + continue; + + if(sa > sb) + { + double aux = sa; sa = sb; sb = aux; + } + + //testout->precision(20); + //(*testout) << "sa " << sa << " sb " << sb << " smax " << smax << " sp " << sp << " v1 " << v1 << endl; + //testout->precision(8); + + + shareedge = (sa < -eps && sb > eps) || + (sa < smax-eps && sb > smax+eps) || + (sa > -eps && sb < smax+eps); + + if(!shareedge) + continue; + + sa = max2(sa,0.); + sb = min2(sb,smax); + + if(sp < sa+eps) + shareedge = (t * v1 > 0); + else if (sp > sb-eps) + shareedge = (t * v1 < 0); + + } + } + if (!shareedge) continue; + + t.Normalize(); + + + return t; + } + + return Vec<3> (0,0,0); +} + + +} + + diff --git a/libsrc/csg/polyhedra.hpp b/libsrc/csg/polyhedra.hpp new file mode 100644 index 00000000..0a785042 --- /dev/null +++ b/libsrc/csg/polyhedra.hpp @@ -0,0 +1,104 @@ +#ifndef FILE_POLYHEDRA +#define FILE_POLYHEDRA + + +/**************************************************************************/ +/* File: polyhedra.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 19. Mar. 2000 */ +/**************************************************************************/ + +namespace netgen +{ + + /* + + Polyhedral primitive + + */ + + class Polyhedra : public Primitive + { + class Face { + public: + int pnums[3]; + int planenr; + + int inputnr; + + Box<3> bbox; + // Point<3> center; + Vec<3> v1, v2; // edges + Vec<3> w1, w2; // pseudo-inverse + Vec<3> n; // normal to face + Vec<3> nn; // normed normal + + Face () { ; } + Face (int pi1, int pi2, int pi3, + const Array > & points, + int ainputnr); + }; + + Array > points; + Array faces; + Array planes; + Box<3> poly_bbox; + + double eps_base1; + + public: + Polyhedra (); + virtual ~Polyhedra (); + static Primitive * CreateDefault (); + + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + virtual INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const; + virtual INSOLID_TYPE VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const; + + // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid + virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual void GetTangentialSurfaceIndices (const Point<3> & p, + Array & surfind, double eps) const; + + + virtual void GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + Array & surfind, double eps) const; + + virtual void CalcSpecialPoints (Array > & pts) const; + virtual void AnalyzeSpecialPoint (const Point<3> & pt, + Array > & specpts) const; + virtual Vec<3> SpecialPointTangentialVector (const Point<3> & p, int s1, int s2) const; + + virtual int GetNSurfaces() const + { return planes.Size(); } + virtual Surface & GetSurface (int i) + { return *planes[i]; } + virtual const Surface & GetSurface (int i) const + { return *planes[i]; } + + virtual void GetPrimitiveData (const char *& classname, Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + + virtual void Reduce (const BoxSphere<3> & box); + virtual void UnReduce (); + + int AddPoint (const Point<3> & p); + int AddFace (int pi1, int pi2, int pi3, int inputnum); + + void GetPolySurfs(Array < Array * > & polysurfs); + + protected: + int FaceBoxIntersection (int fnr, const BoxSphere<3> & box) const; + // void CalcData(); + }; + +} + +#endif diff --git a/libsrc/csg/revolution.cpp b/libsrc/csg/revolution.cpp new file mode 100644 index 00000000..89863b6d --- /dev/null +++ b/libsrc/csg/revolution.cpp @@ -0,0 +1,900 @@ +#include + +#include +#include + +namespace netgen +{ + void RevolutionFace :: Init(void) + { + const LineSeg<2> * line = dynamic_cast*>(spline); + const SplineSeg3<2> * spline3 = dynamic_cast*>(spline); + + if(line) + { + checklines_start.Append(new Point<2>(line->StartPI())); + checklines_vec.Append(new Vec<2>(line->EndPI() - line->StartPI())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + } + else if (spline3) + { + checklines_start.Append(new Point<2>(spline3->EndPI())); + checklines_start.Append(new Point<2>(spline3->TangentPoint())); + checklines_start.Append(new Point<2>(spline3->StartPI())); + checklines_vec.Append(new Vec<2>(spline3->StartPI() - spline3->EndPI())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + checklines_vec.Append(new Vec<2>(spline3->EndPI() - spline3->TangentPoint())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + checklines_vec.Append(new Vec<2>(spline3->TangentPoint() - spline3->StartPI())); + (*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!! + + } + + for(int i=0; i); + (*checklines_normal.Last())(0) = - (*checklines_vec[i])(1); + (*checklines_normal.Last())(1) = (*checklines_vec[i])(0); + checklines_normal.Last()->Normalize(); + } + } + + RevolutionFace :: RevolutionFace(const SplineSeg<2> & spline_in, + const Point<3> & p, + const Vec<3> & vec, + bool first, + bool last, + const int id_in) : + isfirst(first), islast(last), spline(&spline_in), p0(p), v_axis(vec), id(id_in) + { + deletable = false; + Init(); + } + + + RevolutionFace :: RevolutionFace(const Array & raw_data) + { + deletable = true; + + int pos = 0; + + Array< Point<2> > p(3); + + int stype = int(raw_data[pos]); pos++; + + for(int i=0; i(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1)); + //(*testout) << "appending LineSeg<2> " << p[0] + // << " to " << p[1] << endl; + } + else if(stype == 3) + { + spline = new SplineSeg3<2>(GeomPoint<2>(p[0],1), + GeomPoint<2>(p[1],1), + GeomPoint<2>(p[2],1)); + //(*testout) << "appending SplineSeg<3> " + // << p[0] << " -- " << p[1] << " -- " << p[2] << endl; + } + + for(int i=0; i<3; i++) + { + p0(i) = raw_data[pos]; + pos++; + } + for(int i=0; i<3; i++) + { + v_axis(i) = raw_data[pos]; + pos++; + } + isfirst = (raw_data[pos] > 0.9); + pos++; + islast = (raw_data[pos] < 0.1); + pos++; + + + } + + + RevolutionFace :: ~RevolutionFace() + { + for(int i=0; i & point3d, Point<2> & point2d, + const Vec<3> & vector3d, Vec<2> & vector2d) const + { + Vec<3> pmp0 = point3d-p0; + CalcProj0(pmp0,point2d); + Vec<3> y=pmp0-point2d(0)*v_axis; y.Normalize(); + vector2d(0) = vector3d*v_axis; + vector2d(1) = vector3d*y; + } + + + void RevolutionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d) const + { + Vec<3> pmp0 = point3d-p0; + CalcProj0(pmp0,point2d); + } + + void RevolutionFace :: CalcProj0(const Vec<3> & point3d_minus_p0, Point<2> & point2d) const + { + point2d(0) = point3d_minus_p0 * v_axis; + point2d(1) = sqrt( point3d_minus_p0 * point3d_minus_p0 - point2d(0)*point2d(0) ); + } + + + int RevolutionFace ::IsIdentic (const Surface & s2, int & inv, double eps) const + { + const RevolutionFace * rev2 = dynamic_cast(&s2); + + if(!rev2) return 0; + + if(rev2 == this) + return 1; + + return 0; + } + + double RevolutionFace :: CalcFunctionValue (const Point<3> & point) const + { + if(spline_coefficient.Size() == 0) + spline->GetCoeff(spline_coefficient); + + Point<2> p; + CalcProj(point,p); + + return spline_coefficient(0)*p(0)*p(0) + spline_coefficient(1)*p(1)*p(1) + + spline_coefficient(2)*p(0)*p(1) + spline_coefficient(3)*p(0) + + spline_coefficient(4)*p(1) + spline_coefficient(5); + } + + void RevolutionFace :: CalcGradient (const Point<3> & point, Vec<3> & grad) const + { + if(spline_coefficient.Size() == 0) + spline->GetCoeff(spline_coefficient); + + Vec<3> point_minus_p0 = point-p0; + + Point<2> p; + CalcProj0(point_minus_p0,p); + + const double dFdxbar = 2.*spline_coefficient(0)*p(0) + spline_coefficient(2)*p(1) + spline_coefficient(3); + + if(fabs(p(1)) > 1e-10) + { + const double dFdybar = 2.*spline_coefficient(1)*p(1) + spline_coefficient(2)*p(0) + spline_coefficient(4); + + grad(0) = dFdxbar*v_axis(0) + dFdybar * ( point_minus_p0(0)-v_axis(0)*p(0) )/p(1); + grad(1) = dFdxbar*v_axis(1) + dFdybar * ( point_minus_p0(1)-v_axis(1)*p(0) )/p(1); + grad(2) = dFdxbar*v_axis(2) + dFdybar * ( point_minus_p0(2)-v_axis(2)*p(0) )/p(1); + //(*testout) << "grad1("< 1e-10) + { + double aux = spline_coefficient(0)-spline_coefficient(1); + + hesse(0,0) = aux*v_axis(0)*v_axis(0) + spline_coefficient(1); + hesse(0,0) = aux*v_axis(1)*v_axis(1) + spline_coefficient(1); + hesse(0,0) = aux*v_axis(2)*v_axis(2) + spline_coefficient(1); + + hesse(0,1) = hesse(1,0) = aux*v_axis(0)*v_axis(1); + hesse(0,2) = hesse(2,0) = aux*v_axis(0)*v_axis(2); + hesse(1,2) = hesse(2,1) = aux*v_axis(1)*v_axis(2); + //(*testout) << "hesse2: " << hesse < 1e-10) + return 2.*max2(fabs(spline_coefficient(0)),fabs(spline_coefficient(1))); + + + double alpha = fabs(spline_coefficient(2)*(spline->StartPI()(0)-spline->EndPI()(0))) / + max2(fabs(spline->StartPI()(1)),fabs(spline->EndPI()(1))); + + return max2(2.*fabs(spline_coefficient(0))+sqrt(2.)*fabs(spline_coefficient(2)), + 2.*fabs(spline_coefficient(1))+spline_coefficient(2)+1.5*alpha); + } + + double RevolutionFace :: MaxCurvature() const + { + double retval = spline->MaxCurvature(); + + Array < Point<2> > checkpoints; + + const SplineSeg3<2> * ss3 = dynamic_cast *>(spline); + const LineSeg<2> * ls = dynamic_cast *>(spline); + + if(ss3) + { + checkpoints.Append(ss3->StartPI()); + checkpoints.Append(ss3->TangentPoint()); + checkpoints.Append(ss3->TangentPoint()); + checkpoints.Append(ss3->EndPI()); + } + else if(ls) + { + checkpoints.Append(ls->StartPI()); + checkpoints.Append(ls->EndPI()); + } + + for(int i=0; i v = checkpoints[i+1]-checkpoints[i]; + Vec<2> n(v(1),-v(0)); n.Normalize(); + + //if(ss3) + // (*testout) << "n " << n << endl; + + if(fabs(n(1)) < 1e-15) + continue; + + double t1 = -checkpoints[i](1)/n(1); + double t2 = -checkpoints[i+1](1)/n(1); + + double c1 = (t1 > 0) ? (1./t1) : -1; + double c2 = (t2 > 0) ? (1./t2) : -1; + + //if(ss3) + // (*testout) << "t1 " << t1 << " t2 " << t2 << " c1 " << c1 << " c2 " << c2 << endl; + + if(c1 > retval) + retval = c1; + if(c2 > retval) + retval = c2; + } + + //if(ss3) + // (*testout) << "curvature " << retval << endl; + + return retval; + + /* + + + // find smallest y value of spline: + Array testt; + + if(!isfirst) + testt.Append(0); + if(!islast) + testt.Append(1); + + const SplineSegment3 * s3 = dynamic_cast(&spline); + + if(s3) + { + double denom = (2.-sqrt(2.))*(s3->EndPI()(1) - s3->StartPI()(1)); + + if(fabs(denom) < 1e-20) + testt.Append(0.5); + else + { + double sD = sqrt(pow(s3->TangentPoint()(1) - s3->StartPI()(1),2)+ + pow(s3->TangentPoint()(1) - s3->EndPI()(1),2)); + testt.Append((s3->StartPI()(1)*(sqrt(2.)-1.) - sqrt(2.)*s3->TangentPoint()(1) + s3->EndPI()(1) + sD)/denom); + testt.Append((s3->StartPI()(1)*(sqrt(2.)-1.) - sqrt(2.)*s3->TangentPoint()(1) + s3->EndPI()(1) - sD)/denom); + } + } + + double miny = fabs(spline.GetPoint(testt[0])(1)); + for(int i=1; i & p) const + { + Point<2> p2d; + + CalcProj(p,p2d); + + const Vec<3> y = (p-p0)-p2d(0)*v_axis; + const double yl = y.Length(); + + double dummy; + + spline->Project(p2d,p2d,dummy); + + p = p0 + p2d(0)*v_axis; + + if(yl > 1e-20*Dist(spline->StartPI(),spline->EndPI())) + p+= (p2d(1)/yl)*y; + } + + + + + Point<3> RevolutionFace :: GetSurfacePoint () const + { + Vec<3> random_vec(0.760320,-0.241175,0.60311534); + + Vec<3> n = Cross(v_axis,random_vec); n.Normalize(); + + Point<2> sp = spline->GetPoint(0.5); + + Point<3> retval = p0 + sp(0)*v_axis + sp(1)*n; + + return retval; + } + + + void RevolutionFace :: Print (ostream & str) const + { + if(spline_coefficient.Size() == 0) + spline->GetCoeff(spline_coefficient); + + str << p0(0) << " " << p0(1) << " " << p0(2) << " " + << v_axis(0) << " " << v_axis(1) << " " << v_axis(2) << " "; + for(int i=0; i<6; i++) str << spline_coefficient(i) << " "; + str << endl; + } + + + void RevolutionFace :: GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const + { + Vec<3> random_vec(0.760320,-0.241175,0.60311534); + + Vec<3> v1 = Cross(v_axis,random_vec); v1.Normalize(); + Vec<3> v2 = Cross(v1,v_axis); v2.Normalize(); + + int n = int(2.*facets) + 1; + + for(int i=0; i<=n; i++) + { + Point<2> sp = spline->GetPoint(double(i)/double(n)); + for(int j=0; j<=n; j++) + { + double phi = 2.*M_PI*double(j)/double(n); + + Point<3> p = p0 + sp(0)*v_axis + sp(1)*cos(phi)*v1 + sp(1)*sin(phi)*v2; + tas.AddPoint(p); + } + } + + for(int i=0; i & box) const + { + Point<3> center = box.Center(); + + Project(center); + + return (Dist(box.Center(),center) < 0.5*box.Diam()); + } + + + /* + bool RevolutionFace :: BoxIntersectsFace (const BoxSphere<3> & box, bool & uncertain) const + { + Point<2> c,pmin,pmax; + CalcProj(box.Center(),c); + double aux = box.Diam()/sqrt(8.); + pmin(0) = c(0)-aux; pmin(1) = c(1)-aux; + pmax(0) = c(0)+aux; pmax(1) = c(1)+aux; + + BoxSphere<2> box2d(pmin,pmax); + return BoxIntersectsFace(box2d, uncertain); + } + + bool RevolutionFace :: BoxIntersectsFace (const BoxSphere<2> & box, bool & uncertain) const + { + const LineSegment * line = dynamic_cast(&spline); + const SplineSegment3 * spline3 = dynamic_cast(&spline); + + bool always_right = true, always_left = true; + + bool retval = false; + bool thisint; + bool intdirect = false; + bool inttangent = false; + uncertain = false; + + if(line) inttangent = true; + + for(int i=0; i b = box.Center()- (*checklines_start[i]); + + double d; + + double checkdist = b * (*checklines_vec[i]); + double ncomp = b * (*checklines_normal[i]); + + if(checkdist < 0) + d = b.Length(); + else if (checkdist > 1) + { + if(spline3) + d = Dist(box.Center(),*checklines_start[(i+1)%3]); + else + d = Dist(box.Center(),(*checklines_start[i]) + + pow(checklines_vec[i]->Length(),2)*(*checklines_vec[i])); + } + else + d = fabs(ncomp); + + thisint = (box.Diam() >= 2.*d); + retval = retval || thisint; + if(thisint) + { + if(i==0) + intdirect = true; + else + inttangent = true; + } + + if(ncomp > 0) always_right = false; + else if(ncomp < 0) always_left = false; + } + + if(retval && !(intdirect && inttangent)) + uncertain = true; + + if(!retval && spline3 && (always_right || always_left)) + { + retval = true; + uncertain = true; + } + + return retval; + } + */ + + + INSOLID_TYPE RevolutionFace :: PointInFace (const Point<3> & p, const double eps) const + { + Point<2> p2d; + CalcProj(p,p2d); + + double val = spline_coefficient(0)*p2d(0)*p2d(0) + spline_coefficient(1)*p2d(1)*p2d(1) + spline_coefficient(2)*p2d(0)*p2d(1) + + spline_coefficient(3)*p2d(0) + spline_coefficient(4)*p2d(1) + spline_coefficient(5); + + if(val > eps) + return IS_OUTSIDE; + if(val < -eps) + return IS_INSIDE; + + return DOES_INTERSECT; + } + + + + void RevolutionFace :: GetRawData(Array & data) const + { + data.DeleteAll(); + spline->GetRawData(data); + for(int i=0; i<3; i++) + data.Append(p0(i)); + for(int i=0; i<3; i++) + data.Append(v_axis(i)); + data.Append((isfirst) ? 1. : 0.); + data.Append((islast) ? 1. : 0.); + } + + + + Revolution :: Revolution(const Point<3> & p0_in, + const Point<3> & p1_in, + const SplineGeometry<2> & spline_in) : + p0(p0_in), p1(p1_in), splinecurve(spline_in), + nsplines(spline_in.GetNSplines()) + { + surfaceactive.SetSize(0); + surfaceids.SetSize(0); + + v_axis = p1-p0; + + v_axis.Normalize(); + + if(splinecurve.GetSpline(0).StartPI()(1) <= 0. && + splinecurve.GetSpline(nsplines-1).EndPI()(1) <= 0.) + type = 2; + else if (Dist(splinecurve.GetSpline(0).StartPI(), + splinecurve.GetSpline(nsplines-1).EndPI()) < 1e-7) + type = 1; + else + cerr << "Surface of revolution cannot be constructed" << endl; + + for(int i=0; i & box) const + { + for(int i=0; iBoxIntersectsFace(box)) + return DOES_INTERSECT; + + + return PointInSolid(box.Center(),0); + + + /* + Point<2> c,pmin,pmax; + faces[0]->CalcProj(box.Center(),c); + double aux = box.Diam()/sqrt(8.); + pmin(0) = c(0)-aux; pmin(1) = c(1)-aux; + pmax(0) = c(0)+aux; pmax(1) = c(1)+aux; + + + BoxSphere<2> box2d(pmin,pmax); + + bool intersection = false; + bool uncertain = true; + + for(int i=0; !(intersection && !uncertain) && iBoxIntersectsFace(box2d,thisuncertain); + intersection = intersection || thisintersects; + if(thisintersects && !thisuncertain) + uncertain = false; + } + + if(intersection) + { + if(!uncertain) + return DOES_INTERSECT; + else + { + Array < Point<3> > pext(2); + Point<3> p; + + pext[0] = box.PMin(); + pext[1] = box.PMax(); + + INSOLID_TYPE position; + bool firsttime = true; + + for(int i=0; i<2; i++) + for(int j=0; j<2; j++) + for(int k=0; k<2; k++) + { + p(0) = pext[i](0); + p(1) = pext[j](1); + p(2) = pext[k](2); + INSOLID_TYPE ppos = PointInSolid(p,0); + if(ppos == DOES_INTERSECT) + return DOES_INTERSECT; + + if(firsttime) + { + firsttime = false; + position = ppos; + } + if(position != ppos) + return DOES_INTERSECT; + } + return position; + + } + } + + return PointInSolid(box.Center(),0); + */ + } + + INSOLID_TYPE Revolution :: PointInSolid (const Point<3> & p, + double eps) const + { + Point<2> p2d; + faces[0]->CalcProj(p,p2d); + + int intersections_before(0), intersections_after(0); + double randomx = 7.42357; + double randomy = 1.814756; + randomx *= 1./sqrt(randomx*randomx+randomy*randomy); + randomy *= 1./sqrt(randomx*randomx+randomy*randomy); + + + const double a = randomy; + const double b = -randomx; + const double c = -a*p2d(0)-b*p2d(1); + + Array < Point<2> > points; + + //(*testout) << "face intersections at: " << endl; + for(int i=0; iGetSpline().LineIntersections(a,b,c,points,eps); + + for(int j=0; j eps ) + intersections_after++; + else + { + intersecting_face = i; + return DOES_INTERSECT; + } + } + } + + if(intersections_before % 2 == 0) + return IS_OUTSIDE; + else + return IS_INSIDE; + } + + INSOLID_TYPE Revolution :: VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const + { + INSOLID_TYPE pInSolid = PointInSolid(p,eps); + + if(pInSolid != DOES_INTERSECT) + { + //(*testout) << "pInSolid" << endl; + return pInSolid; + } + + Array intersecting_faces; + + for(int i=0; iPointInFace(p,eps) == DOES_INTERSECT) + intersecting_faces.Append(i); + + Vec<3> hv; + + if(intersecting_faces.Size() == 1) + { + faces[intersecting_faces[0]]->CalcGradient(p,hv); + + double hv1; + hv1 = v * hv; + + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + return DOES_INTERSECT; + } + else if(intersecting_faces.Size() == 2) + { + Point<2> p2d; + Vec<2> v2d; + faces[intersecting_faces[0]]->CalcProj(p,p2d,v,v2d); + + if(Dist(faces[intersecting_faces[0]]->GetSpline().StartPI(),p2d) < + Dist(faces[intersecting_faces[0]]->GetSpline().EndPI(),p2d)) + { + int aux = intersecting_faces[0]; + intersecting_faces[0] = intersecting_faces[1]; + intersecting_faces[1] = aux; + } + + const SplineSeg3<2> * splinesegment3 = + dynamic_cast *>(&faces[intersecting_faces[0]]->GetSpline()); + const LineSeg<2> * linesegment = + dynamic_cast *>(&faces[intersecting_faces[0]]->GetSpline()); + + Vec<2> t1,t2; + + if(linesegment) + t1 = linesegment->StartPI() - linesegment->EndPI(); + else if(splinesegment3) + t1 = splinesegment3->TangentPoint() - splinesegment3->EndPI(); + + linesegment = + dynamic_cast *>(&faces[intersecting_faces[1]]->GetSpline()); + splinesegment3 = + dynamic_cast *>(&faces[intersecting_faces[1]]->GetSpline()); + + if(linesegment) + t2 = linesegment->EndPI() - linesegment->StartPI(); + else if(splinesegment3) + t2 = splinesegment3->TangentPoint() - splinesegment3->StartPI(); + + t1.Normalize(); + t2.Normalize(); + + double d1 = v2d*t1; + double d2 = v2d*t2; + + Vec<2> n; + + if(d1 > d2) + { + n(0) = t1(1); + n(1) = -t1(0); + } + else + { + n(0) = -t2(1); + n(1) = t2(0); + } + + double d = v2d*n; + + if(d > eps) + return IS_OUTSIDE; + else if (d < -eps) + return IS_INSIDE; + else + return DOES_INTERSECT; + + + } + else + { + cerr << "Jo gibt's denn des?" << endl; + } + + return DOES_INTERSECT; + } + + INSOLID_TYPE Revolution :: VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const + { + INSOLID_TYPE ret1 = VecInSolid(p,v1,eps); + if(ret1 != DOES_INTERSECT) + return ret1; + + return VecInSolid(p,v1+0.01*v2,eps); + } + + int Revolution :: GetNSurfaces() const + { + return faces.Size(); + } + + Surface & Revolution :: GetSurface (int i) + { + return *faces[i]; + } + + const Surface & Revolution :: GetSurface (int i) const + { + return *faces[i]; + } + + + void Revolution :: Reduce (const BoxSphere<3> & box) + { + //bool dummy; + for(int i=0; iBoxIntersectsFace(box)); + //surfaceactive[i] = (faces[i]->BoxIntersectsFace(box,dummy)); + } + + void Revolution :: UnReduce () + { + for(int i=0; i * spline; + bool deletable; + + Point<3> p0; + Vec<3> v_axis; + + int id; + + mutable Vector spline_coefficient; + + + Array < Vec<2>* > checklines_vec; + Array < Point<2>* > checklines_start; + Array < Vec<2>* > checklines_normal; + + private: + void Init (void); + + public: + void CalcProj(const Point<3> & point3d, Point<2> & point2d) const; + void CalcProj(const Point<3> & point3d, Point<2> & point2d, + const Vec<3> & vector3d, Vec<2> & vector2d) const; + void CalcProj0(const Vec<3> & point3d_minus_p0, Point<2> & point2d) const; + + public: + RevolutionFace(const SplineSeg<2> & spline_in, + const Point<3> & p, + const Vec<3> & vec, + bool first = false, + bool last = false, + const int id_in = 0); + + RevolutionFace(const Array & raw_data); + + ~RevolutionFace(); + + virtual int IsIdentic (const Surface & s2, int & inv, double eps) const; + + virtual double CalcFunctionValue (const Point<3> & point) const; + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + virtual double HesseNorm () const; + + virtual double MaxCurvature () const; + //virtual double MaxCurvatureLoc (const Point<3> & /* c */ , + // double /* rad */) const; + + virtual void Project (Point<3> & p) const; + + virtual Point<3> GetSurfacePoint () const; + virtual void Print (ostream & str) const; + + virtual void GetTriangleApproximation (TriangleApproximation & tas, + const Box<3> & boundingbox, + double facets) const; + + bool BoxIntersectsFace (const Box<3> & box) const; + /* + bool BoxIntersectsFace (const BoxSphere<2> & box, bool & uncertain) const; + bool BoxIntersectsFace (const BoxSphere<3> & box, bool & uncertain) const; + */ + + const SplineSeg<2> & GetSpline(void) const {return *spline;} + + INSOLID_TYPE PointInFace (const Point<3> & p, const double eps) const; + + void GetRawData(Array & data) const; + + }; + + + + /* + + Primitive of revolution + + */ + + + class Revolution : public Primitive + { + private: + Point<3> p0,p1; + Vec<3> v_axis; + const SplineGeometry<2> & splinecurve; + const int nsplines; + + // 1 ... torus-like + // 2 ... sphere-like + int type; + + + Array faces; + + mutable int intersecting_face; + + public: + Revolution(const Point<3> & p0_in, + const Point<3> & p1_in, + const SplineGeometry<2> & spline_in); + + ~Revolution(); + + + /* + Check, whether box intersects solid defined by surface. + + return values: + 0 .. box outside solid \\ + 1 .. box in solid \\ + 2 .. can't decide (allowed, iff box is close to solid) + */ + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const; + virtual INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const; + virtual INSOLID_TYPE VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const; + + // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid + virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + + virtual int GetNSurfaces() const; + virtual Surface & GetSurface (int i = 0); + virtual const Surface & GetSurface (int i = 0) const; + + + virtual void Reduce (const BoxSphere<3> & box); + virtual void UnReduce (); + + + }; + +} + + +#endif diff --git a/libsrc/csg/singularref.cpp b/libsrc/csg/singularref.cpp new file mode 100644 index 00000000..0ad13db9 --- /dev/null +++ b/libsrc/csg/singularref.cpp @@ -0,0 +1,217 @@ +#include +#include + +#include +#include +#include + +namespace netgen +{ + + SingularEdge :: SingularEdge (double abeta, int adomnr, + const CSGeometry & ageom, + const Solid * asol1, + const Solid * asol2, double sf, + const double maxh_at_initialization) + : domnr(adomnr), geom(ageom) + { + beta = abeta; + maxhinit = maxh_at_initialization; + + if (beta > 1) + { + beta = 1; + cout << "Warning: beta set to 1" << endl; + } + if (beta <= 1e-3) + { + beta = 1e-3; + cout << "Warning: beta set to minimal value 0.001" << endl; + } + + sol1 = asol1; + sol2 = asol2; + factor = sf; +} + +void SingularEdge :: FindPointsOnEdge (class Mesh & mesh) +{ + (*testout) << "find points on edge" << endl; + points.SetSize(0); + segms.SetSize(0); + + + Array si1, si2; + sol1->GetSurfaceIndices (si1); + sol2->GetSurfaceIndices (si2); + + for (int i = 0; i < si1.Size(); i++) + si1[i] = geom.GetSurfaceClassRepresentant(si1[i]); + for (int i = 0; i < si2.Size(); i++) + si2[i] = geom.GetSurfaceClassRepresentant(si2[i]); + + + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + INDEX_2 i2 (mesh[si][0], mesh[si][1]); + /* + + bool onedge = 1; + for (j = 1; j <= 2; j++) + { + const Point<3> p = mesh[ PointIndex (i2.I(j)) ]; + if (sol1->IsIn (p, 1e-3) && sol2->IsIn(p, 1e-3) && + !sol1->IsStrictIn (p, 1e-3) && !sol2->IsStrictIn(p, 1e-3)) + { + ; + } + else + onedge = 0; + } + */ + + if (domnr != -1 && domnr != mesh[si].domin && domnr != mesh[si].domout) + continue; + + /* + bool onedge = 1; + for (int j = 0; j < 2; j++) + { + int surfi = (j == 0) ? mesh[si].surfnr1 : mesh[si].surfnr2; + surfi = geom.GetSurfaceClassRepresentant(surfi); + if (!si1.Contains(surfi) && !si2.Contains(surfi)) + onedge = 0; + } + */ + int surfi1 = geom.GetSurfaceClassRepresentant(mesh[si].surfnr1); + int surfi2 = geom.GetSurfaceClassRepresentant(mesh[si].surfnr2); + + if ( (si1.Contains(surfi1) && si2.Contains(surfi2)) || + (si1.Contains(surfi2) && si2.Contains(surfi1)) ) + + // if (onedge) + { + segms.Append (i2); + // PrintMessage (5, "sing segment ", i2.I1(), " - ", i2.I2()); + points.Append (mesh[ PointIndex (i2.I1())]); + points.Append (mesh[ PointIndex (i2.I2())]); + mesh[si].singedge_left = factor; + mesh[si].singedge_right = factor; + } + } + + /* + (*testout) << "Singular edge points:" << endl; + for (int i = 0; i < points.Size(); i++) + (*testout) << points[i] << endl; + */ + +} + +void SingularEdge :: SetMeshSize (class Mesh & mesh, double globalh) +{ + double hloc = pow (globalh, 1/beta); + if(maxhinit > 0 && maxhinit < hloc) + { + hloc = maxhinit; + if(points.Size() > 1) + { + for (int i = 0; i < points.Size()-1; i++) + mesh.RestrictLocalHLine(points[i],points[i+1],hloc); + } + else + { + for (int i = 0; i < points.Size(); i++) + mesh.RestrictLocalH (points[i], hloc); + } + } + else + { + for (int i = 0; i < points.Size(); i++) + mesh.RestrictLocalH (points[i], hloc); + } +} + + + +SingularPoint :: SingularPoint (double abeta, + const Solid * asol1, + const Solid * asol2, + const Solid * asol3, double sf) +{ + beta = abeta; + sol1 = asol1; + sol2 = asol2; + sol3 = asol3; + factor = sf; +} + + +void SingularPoint :: FindPoints (class Mesh & mesh) +{ + points.SetSize(0); + Array surfk, surf; + + + for (PointIndex pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + { + if (mesh[pi].Type() != FIXEDPOINT) continue; + const Point<3> p = mesh[pi]; + + (*testout) << "check singular point" << p << endl; + + if (sol1->IsIn (p) && sol2->IsIn(p) && sol3->IsIn(p) && + !sol1->IsStrictIn (p) && !sol2->IsStrictIn(p) && !sol3->IsStrictIn(p)) + { + surf.SetSize (0); + for (int k = 1; k <= 3; k++) + { + const Solid * solk(NULL); + Solid *tansol; + switch (k) + { + case 1: solk = sol1; break; + case 2: solk = sol2; break; + case 3: solk = sol3; break; + } + + solk -> TangentialSolid (p, tansol, surfk, 1e-3); + (*testout) << "Tansol = " << *tansol << endl; + + if (!tansol) continue; + + ReducePrimitiveIterator rpi(Box<3> (p-Vec<3> (1e-3,1e-3,1e-3), + p+Vec<3> (1e-3,1e-3,1e-3))); + UnReducePrimitiveIterator urpi; + + tansol -> IterateSolid (rpi); + tansol->GetSurfaceIndices (surfk); + tansol -> IterateSolid (urpi); + + (*testout) << "surfinds = " << surfk << endl; + + for (int i = 0; i < surfk.Size(); i++) + if (!surf.Contains (surfk[i])) + surf.Append (surfk[i]); + + delete tansol; + } + + if (surf.Size() < 3) continue; + + points.Append (p); + PrintMessage (5, "Point (", p(0), ", ", p(1), ", ", p(2), ") is singular"); + mesh[pi].Singularity(factor); + } + } +} + + +void SingularPoint :: SetMeshSize (class Mesh & mesh, double globalh) +{ + double hloc = pow (globalh, 1/beta); + for (int i = 1; i <= points.Size(); i++) + mesh.RestrictLocalH (points.Get(i), hloc); +} +} diff --git a/libsrc/csg/singularref.hpp b/libsrc/csg/singularref.hpp new file mode 100644 index 00000000..c029fbef --- /dev/null +++ b/libsrc/csg/singularref.hpp @@ -0,0 +1,84 @@ +#ifndef FILE_SINGULARREF +#define FILE_SINGULARREF + +/**************************************************************************/ +/* File: singularref.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 25. Sep. 99 */ +/**************************************************************************/ + +namespace netgen +{ + + + /** + Control for local refinement + */ + + + + /** + Singular Face. + Causes a bounday layer mesh refinement. + All elements in subdomain domnr will get a boundary layer + on faces sharing the solid sol + */ + class SingularFace + { + public: + int domnr; + const Solid *sol; + double factor; + // Array > points; + // Array segms; + public: + SingularFace (int adomnr, const Solid * asol, double sf) + : domnr(adomnr), sol(asol), factor(sf) { ; } + const Solid * GetSolid() const { return sol; } + int GetDomainNr () const { return domnr; } + }; + + + /// + class SingularEdge + { + public: + double beta; + int domnr; + const CSGeometry& geom; + const Solid *sol1, *sol2; + Array > points; + Array segms; + double factor; + + double maxhinit; + public: + SingularEdge (double abeta, int adomnr, + const CSGeometry & ageom, + const Solid * asol1, const Solid * asol2, double sf, + const double maxh_at_initialization = -1); + void FindPointsOnEdge (class Mesh & mesh); + void SetMeshSize (class Mesh & mesh, double globalh); + }; + + + /// + class SingularPoint + { + public: + double beta; + const Solid *sol1, *sol2, *sol3; + Array > points; + double factor; + + public: + SingularPoint (double abeta, const Solid * asol1, const Solid * asol2, + const Solid * asol3, double sf); + void FindPoints (class Mesh & mesh); + void SetMeshSize (class Mesh & mesh, double globalh); + }; + +} + + +#endif diff --git a/libsrc/csg/solid.cpp b/libsrc/csg/solid.cpp new file mode 100644 index 00000000..aba39d8a --- /dev/null +++ b/libsrc/csg/solid.cpp @@ -0,0 +1,1732 @@ +#include + +#include +#include + + +namespace netgen +{ + //using namespace netgen; + + + /* + SolidIterator :: SolidIterator () + { + ; + } + + SolidIterator :: ~SolidIterator () + { + ; + } + */ + + + + // int Solid :: cntnames = 0; + + Solid :: Solid (Primitive * aprim) + { + op = TERM; + prim = aprim; + s1 = s2 = NULL; + maxh = 1e10; + name = NULL; + } + + Solid :: Solid (optyp aop, Solid * as1, Solid * as2) + { + op = aop; + s1 = as1; + s2 = as2; + prim = NULL; + name = NULL; + maxh = 1e10; + } + + Solid :: ~Solid () + { + // cout << "delete solid, op = " << int(op) << endl; + delete [] name; + + switch (op) + { + case UNION: + case SECTION: + { + if (s1->op != ROOT) delete s1; + if (s2->op != ROOT) delete s2; + break; + } + case SUB: + // case ROOT: + { + if (s1->op != ROOT) delete s1; + break; + } + case TERM: + { + // cout << "has term" << endl; + delete prim; + break; + } + default: + break; + } + } + + void Solid :: SetName (const char * aname) + { + delete [] name; + name = new char[strlen (aname)+1]; + strcpy (name, aname); + } + + + Solid * Solid :: Copy (CSGeometry & geom) const + { + Solid * nsol(NULL); + switch (op) + { + case TERM: case TERM_REF: + { + Primitive * nprim = prim->Copy(); + geom.AddSurfaces (nprim); + nsol = new Solid (nprim); + break; + } + + case SECTION: + case UNION: + { + nsol = new Solid (op, s1->Copy(geom), s2->Copy(geom)); + break; + } + + case SUB: + { + nsol = new Solid (SUB, s1 -> Copy (geom)); + break; + } + + case ROOT: + { + nsol = s1->Copy(geom); + break; + } + } + + return nsol; + } + + + void Solid :: Transform (Transformation<3> & trans) + { + switch (op) + { + case TERM: case TERM_REF: + { + prim -> Transform (trans); + break; + } + case SECTION: + case UNION: + { + s1 -> Transform (trans); + s2 -> Transform (trans); + break; + } + + case SUB: + case ROOT: + { + s1 -> Transform (trans); + break; + } + } + } + + + + void Solid :: IterateSolid (SolidIterator & it, + bool only_once) + { + if (only_once) + { + if (visited) + return; + + visited = 1; + } + + it.Do (this); + + switch (op) + { + case SECTION: + { + s1->IterateSolid (it, only_once); + s2->IterateSolid (it, only_once); + break; + } + case UNION: + { + s1->IterateSolid (it, only_once); + s2->IterateSolid (it, only_once); + break; + } + case SUB: + case ROOT: + { + s1->IterateSolid (it, only_once); + break; + } + case TERM: + case TERM_REF: + break; // do nothing + } + } + + + + + bool Solid :: IsIn (const Point<3> & p, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid (p, eps); + return ( (ist == IS_INSIDE) || (ist == DOES_INTERSECT) ) ? 1 : 0; + } + case SECTION: + return s1->IsIn (p, eps) && s2->IsIn (p, eps); + case UNION: + return s1->IsIn (p, eps) || s2->IsIn (p, eps); + case SUB: + return !s1->IsStrictIn (p, eps); + case ROOT: + return s1->IsIn (p, eps); + } + return 0; + } + + bool Solid :: IsStrictIn (const Point<3> & p, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid (p, eps); + return (ist == IS_INSIDE) ? 1 : 0; + } + case SECTION: + return s1->IsStrictIn(p, eps) && s2->IsStrictIn(p, eps); + case UNION: + return s1->IsStrictIn(p, eps) || s2->IsStrictIn(p, eps); + case SUB: + return !s1->IsIn (p, eps); + case ROOT: + return s1->IsStrictIn (p, eps); + } + return 0; + } + + bool Solid :: VectorIn (const Point<3> & p, const Vec<3> & v, + double eps) const + { + Vec<3> hv; + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->VecInSolid (p, v, eps); + return (ist == IS_INSIDE || ist == DOES_INTERSECT) ? 1 : 0; + } + case SECTION: + return s1 -> VectorIn (p, v, eps) && s2 -> VectorIn (p, v, eps); + case UNION: + return s1 -> VectorIn (p, v, eps) || s2 -> VectorIn (p, v, eps); + case SUB: + return !s1->VectorStrictIn(p, v, eps); + case ROOT: + return s1->VectorIn(p, v, eps); + } + return 0; + } + + bool Solid :: VectorStrictIn (const Point<3> & p, const Vec<3> & v, + double eps) const + { + Vec<3> hv; + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->VecInSolid (p, v, eps); + return (ist == IS_INSIDE) ? true : false; + } + case SECTION: + return s1 -> VectorStrictIn (p, v, eps) && + s2 -> VectorStrictIn (p, v, eps); + case UNION: + return s1 -> VectorStrictIn (p, v, eps) || + s2 -> VectorStrictIn (p, v, eps); + case SUB: + return !s1->VectorIn(p, v, eps); + case ROOT: + return s1->VectorStrictIn(p, v, eps); + } + return 0; + } + + + bool Solid::VectorIn2 (const Point<3> & p, const Vec<3> & v1, + const Vec<3> & v2, double eps) const + { + if (VectorStrictIn (p, v1, eps)) + return 1; + if (!VectorIn (p, v1, eps)) + return 0; + + bool res = VectorIn2Rec (p, v1, v2, eps); + return res; + } + + bool Solid::VectorIn2Rec (const Point<3> & p, const Vec<3> & v1, + const Vec<3> & v2, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + return (prim->VecInSolid2 (p, v1, v2, eps) != IS_OUTSIDE); // Is this correct???? + case SECTION: + return s1->VectorIn2Rec (p, v1, v2, eps) && + s2->VectorIn2Rec (p, v1, v2, eps); + case UNION: + return s1->VectorIn2Rec (p, v1, v2, eps) || + s2->VectorIn2Rec (p, v1, v2, eps); + case SUB: + return !s1->VectorIn2Rec (p, v1, v2, eps); + case ROOT: + return s1->VectorIn2Rec (p, v1, v2, eps); + } + return 0; + } + + + + + + + void Solid :: Print (ostream & str) const + { + switch (op) + { + case TERM: case TERM_REF: + { + str << prim->GetSurfaceId(0); + for (int i = 1; i < prim->GetNSurfaces(); i++) + str << "," << prim->GetSurfaceId(i); + break; + } + case SECTION: + { + str << "("; + s1 -> Print (str); + str << " AND "; + s2 -> Print (str); + str << ")"; + break; + } + case UNION: + { + str << "("; + s1 -> Print (str); + str << " OR "; + s2 -> Print (str); + str << ")"; + break; + } + case SUB: + { + str << " NOT "; + s1 -> Print (str); + break; + } + case ROOT: + { + str << " [" << name << "="; + s1 -> Print (str); + str << "] "; + break; + } + } + } + + + + void Solid :: GetSolidData (ostream & ost, int first) const + { + switch (op) + { + case SECTION: + { + ost << "("; + s1 -> GetSolidData (ost, 0); + ost << " AND "; + s2 -> GetSolidData (ost, 0); + ost << ")"; + break; + } + case UNION: + { + ost << "("; + s1 -> GetSolidData (ost, 0); + ost << " OR "; + s2 -> GetSolidData (ost, 0); + ost << ")"; + break; + } + case SUB: + { + ost << "NOT "; + s1 -> GetSolidData (ost, 0); + break; + } + case TERM: case TERM_REF: + { + if (name) + ost << name; + else + ost << "(noname)"; + break; + } + case ROOT: + { + if (first) + s1 -> GetSolidData (ost, 0); + else + ost << name; + break; + } + } + } + + + + static Solid * CreateSolidExpr (istream & ist, const SYMBOLTABLE & solids); + static Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE & solids); + static Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE & solids); + + static void ReadString (istream & ist, char * str) + { + //char * hstr = str; + char ch; + + while (1) + { + ist.get(ch); + if (!ist.good()) break; + + if (!isspace (ch)) + { + ist.putback (ch); + break; + } + } + + while (1) + { + ist.get(ch); + if (!ist.good()) break; + if (isalpha(ch) || isdigit(ch)) + { + *str = ch; + str++; + } + else + { + ist.putback (ch); + break; + } + } + *str = 0; + // cout << "Read string (" << hstr << ")" + // << "put back: " << ch << endl; + } + + + Solid * CreateSolidExpr (istream & ist, const SYMBOLTABLE & solids) + { + // cout << "create expr" << endl; + + Solid *s1, *s2; + char str[100]; + + s1 = CreateSolidTerm (ist, solids); + ReadString (ist, str); + if (strcmp (str, "OR") == 0) + { + // cout << " OR "; + s2 = CreateSolidExpr (ist, solids); + return new Solid (Solid::UNION, s1, s2); + } + + // cout << "no OR found, put back string: " << str << endl; + for (int i = int(strlen(str))-1; i >= 0; i--) + ist.putback (str[i]); + + return s1; + } + + Solid * CreateSolidTerm (istream & ist, const SYMBOLTABLE & solids) + { + // cout << "create term" << endl; + + Solid *s1, *s2; + char str[100]; + + s1 = CreateSolidPrim (ist, solids); + ReadString (ist, str); + if (strcmp (str, "AND") == 0) + { + // cout << " AND "; + s2 = CreateSolidTerm (ist, solids); + return new Solid (Solid::SECTION, s1, s2); + } + + + // cout << "no AND found, put back string: " << str << endl; + for (int i = int(strlen(str))-1; i >= 0; i--) + ist.putback (str[i]); + + return s1; + } + + Solid * CreateSolidPrim (istream & ist, const SYMBOLTABLE & solids) + { + Solid * s1; + char ch; + char str[100]; + + ist >> ch; + if (ch == '(') + { + s1 = CreateSolidExpr (ist, solids); + ist >> ch; // ')' + // cout << "close back " << ch << endl; + return s1; + } + ist.putback (ch); + + ReadString (ist, str); + if (strcmp (str, "NOT") == 0) + { + // cout << " NOT "; + s1 = CreateSolidPrim (ist, solids); + return new Solid (Solid::SUB, s1); + } + + (*testout) << "get terminal " << str << endl; + s1 = solids.Get(str); + if (s1) + { + // cout << "primitive: " << str << endl; + return s1; + } + cerr << "syntax error" << endl; + + return NULL; + } + + + Solid * Solid :: CreateSolid (istream & ist, const SYMBOLTABLE & solids) + { + Solid * nsol = CreateSolidExpr (ist, solids); + nsol = new Solid (ROOT, nsol); + (*testout) << "Print new sol: "; + nsol -> Print (*testout); + (*testout) << endl; + return nsol; + } + + + + void Solid :: Boundaries (const Point<3> & p, Array & bounds) const + { + int in, strin; + bounds.SetSize (0); + RecBoundaries (p, bounds, in, strin); + } + + void Solid :: RecBoundaries (const Point<3> & p, Array & bounds, + int & in, int & strin) const + { + switch (op) + { + case TERM: case TERM_REF: + { + /* + double val; + val = surf->CalcFunctionValue (p); + in = (val < 1e-6); + strin = (val < -1e-6); + if (in && !strin) bounds.Append (id); + */ + if (prim->PointInSolid (p, 1e-6) == DOES_INTERSECT) + bounds.Append (prim->GetSurfaceId (1)); + break; + } + case SECTION: + { + int i, in1, in2, strin1, strin2; + Array bounds1, bounds2; + + s1 -> RecBoundaries (p, bounds1, in1, strin1); + s2 -> RecBoundaries (p, bounds2, in2, strin2); + + if (in1 && in2) + { + for (i = 1; i <= bounds1.Size(); i++) + bounds.Append (bounds1.Get(i)); + for (i = 1; i <= bounds2.Size(); i++) + bounds.Append (bounds2.Get(i)); + } + in = (in1 && in2); + strin = (strin1 && strin2); + break; + } + case UNION: + { + int i, in1, in2, strin1, strin2; + Array bounds1, bounds2; + + s1 -> RecBoundaries (p, bounds1, in1, strin1); + s2 -> RecBoundaries (p, bounds2, in2, strin2); + + if (!strin1 && !strin2) + { + for (i = 1; i <= bounds1.Size(); i++) + bounds.Append (bounds1.Get(i)); + for (i = 1; i <= bounds2.Size(); i++) + bounds.Append (bounds2.Get(i)); + } + in = (in1 || in2); + strin = (strin1 || strin2); + break; + } + case SUB: + { + int hin, hstrin; + s1 -> RecBoundaries (p, bounds, hin, hstrin); + in = !hstrin; + strin = !hin; + break; + } + + case ROOT: + { + s1 -> RecBoundaries (p, bounds, in, strin); + break; + } + } + } + + + void Solid :: TangentialSolid (const Point<3> & p, Solid *& tansol, Array & surfids, double eps) const + { + int in, strin; + RecTangentialSolid (p, tansol, surfids, in, strin, eps); + surfids.SetSize (0); + if (tansol) + tansol -> GetTangentialSurfaceIndices (p, surfids, eps); + } + + + void Solid :: RecTangentialSolid (const Point<3> & p, Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const + { + tansol = NULL; + + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid(p, eps); + + in = (ist == IS_INSIDE || ist == DOES_INTERSECT); + strin = (ist == IS_INSIDE); + + if (ist == DOES_INTERSECT) + { + tansol = new Solid (prim); + tansol -> op = TERM_REF; + } + break; + } + case SECTION: + { + int in1, in2, strin1, strin2; + Solid * tansol1, * tansol2; + + s1 -> RecTangentialSolid (p, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid (p, tansol2, surfids, in2, strin2, eps); + + if (in1 && in2) + { + if (tansol1 && tansol2) + tansol = new Solid (SECTION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + in = (in1 && in2); + strin = (strin1 && strin2); + break; + } + case UNION: + { + int in1, in2, strin1, strin2; + Solid * tansol1 = 0, * tansol2 = 0; + + s1 -> RecTangentialSolid (p, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid (p, tansol2, surfids, in2, strin2, eps); + + if (!strin1 && !strin2) + { + if (tansol1 && tansol2) + tansol = new Solid (UNION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + else + { + delete tansol1; + delete tansol2; + } + in = (in1 || in2); + strin = (strin1 || strin2); + break; + } + case SUB: + { + int hin, hstrin; + Solid * tansol1; + + s1 -> RecTangentialSolid (p, tansol1, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialSolid (p, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + void Solid :: TangentialSolid2 (const Point<3> & p, + const Vec<3> & t, + Solid *& tansol, Array & surfids, double eps) const + { + int in, strin; + surfids.SetSize (0); + RecTangentialSolid2 (p, t, tansol, surfids, in, strin, eps); + if (tansol) + tansol -> GetTangentialSurfaceIndices2 (p, t, surfids, eps); + } + + void Solid :: RecTangentialSolid2 (const Point<3> & p, const Vec<3> & t, + Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const + { + tansol = NULL; + + switch (op) + { + case TERM: case TERM_REF: + { + /* + double val; + val = surf->CalcFunctionValue (p); + in = (val < 1e-6); + strin = (val < -1e-6); + if (in && !strin) + tansol = new Solid (surf, id); + */ + + INSOLID_TYPE ist = prim->PointInSolid(p, eps); + if (ist == DOES_INTERSECT) + ist = prim->VecInSolid (p, t, eps); + + in = (ist == IS_INSIDE || ist == DOES_INTERSECT); + strin = (ist == IS_INSIDE); + + if (ist == DOES_INTERSECT) + { + tansol = new Solid (prim); + tansol -> op = TERM_REF; + } + break; + } + case SECTION: + { + int in1, in2, strin1, strin2; + Solid * tansol1, * tansol2; + + s1 -> RecTangentialSolid2 (p, t, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid2 (p, t, tansol2, surfids, in2, strin2, eps); + + if (in1 && in2) + { + if (tansol1 && tansol2) + tansol = new Solid (SECTION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + in = (in1 && in2); + strin = (strin1 && strin2); + break; + } + case UNION: + { + int in1, in2, strin1, strin2; + Solid * tansol1, * tansol2; + + s1 -> RecTangentialSolid2 (p, t, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid2 (p, t, tansol2, surfids, in2, strin2, eps); + + if (!strin1 && !strin2) + { + if (tansol1 && tansol2) + tansol = new Solid (UNION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + in = (in1 || in2); + strin = (strin1 || strin2); + break; + } + case SUB: + { + int hin, hstrin; + Solid * tansol1; + + s1 -> RecTangentialSolid2 (p, t, tansol1, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialSolid2 (p, t, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + + + + + void Solid :: TangentialSolid3 (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, + Solid *& tansol, Array & surfids, + double eps) const + { + int in, strin; + surfids.SetSize (0); + RecTangentialSolid3 (p, t, t2, tansol, surfids, in, strin, eps); + + if (tansol) + tansol -> GetTangentialSurfaceIndices3 (p, t, t2, surfids, eps); + } + + void Solid :: RecTangentialSolid3 (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, + Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const + { + tansol = NULL; + + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid(p, eps); + + if (ist == DOES_INTERSECT) + ist = prim->VecInSolid3 (p, t, t2, eps); + in = (ist == IS_INSIDE || ist == DOES_INTERSECT); + strin = (ist == IS_INSIDE); + + if (ist == DOES_INTERSECT) + { + tansol = new Solid (prim); + tansol -> op = TERM_REF; + } + break; + } + case SECTION: + { + int in1, in2, strin1, strin2; + Solid * tansol1, * tansol2; + + s1 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid3 (p, t, t2, tansol2, surfids, in2, strin2, eps); + + if (in1 && in2) + { + if (tansol1 && tansol2) + tansol = new Solid (SECTION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + in = (in1 && in2); + strin = (strin1 && strin2); + break; + } + case UNION: + { + int in1, in2, strin1, strin2; + Solid * tansol1, * tansol2; + + s1 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialSolid3 (p, t, t2, tansol2, surfids, in2, strin2, eps); + + if (!strin1 && !strin2) + { + if (tansol1 && tansol2) + tansol = new Solid (UNION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + in = (in1 || in2); + strin = (strin1 || strin2); + break; + } + case SUB: + { + int hin, hstrin; + Solid * tansol1; + + s1 -> RecTangentialSolid3 (p, t, t2, tansol1, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialSolid3 (p, t, t2, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + + + + + + + + void Solid :: TangentialEdgeSolid (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, const Vec<3> & m, + Solid *& tansol, Array & surfids, + double eps) const + { + int in, strin; + surfids.SetSize (0); + + // *testout << "tangentialedgesolid,sol = " << (*this) << endl; + RecTangentialEdgeSolid (p, t, t2, m, tansol, surfids, in, strin, eps); + + if (tansol) + tansol -> RecGetTangentialEdgeSurfaceIndices (p, t, t2, m, surfids, eps); + } + + void Solid :: RecTangentialEdgeSolid (const Point<3> & p, + const Vec<3> & t, const Vec<3> & t2, const Vec<3> & m, + Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const + { + tansol = NULL; + + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->PointInSolid(p, eps); + + /* + (*testout) << "tangedgesolid, p = " << p << ", t = " << t + << " for prim " << typeid (*prim).name() + << " with surf " << prim->GetSurface() << endl; + (*testout) << "ist = " << ist << endl; + */ + + if (ist == DOES_INTERSECT) + ist = prim->VecInSolid4 (p, t, t2, m, eps); + + // (*testout) << "ist2 = " << ist << endl; + + in = (ist == IS_INSIDE || ist == DOES_INTERSECT); + strin = (ist == IS_INSIDE); + + if (ist == DOES_INTERSECT) + { + tansol = new Solid (prim); + tansol -> op = TERM_REF; + } + break; + } + case SECTION: + { + int in1, in2, strin1, strin2; + Solid * tansol1, * tansol2; + + s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialEdgeSolid (p, t, t2, m, tansol2, surfids, in2, strin2, eps); + + if (in1 && in2) + { + if (tansol1 && tansol2) + tansol = new Solid (SECTION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + in = (in1 && in2); + strin = (strin1 && strin2); + break; + } + case UNION: + { + int in1, in2, strin1, strin2; + Solid * tansol1, * tansol2; + + s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, in1, strin1, eps); + s2 -> RecTangentialEdgeSolid (p, t, t2, m, tansol2, surfids, in2, strin2, eps); + + if (!strin1 && !strin2) + { + if (tansol1 && tansol2) + tansol = new Solid (UNION, tansol1, tansol2); + else if (tansol1) + tansol = tansol1; + else if (tansol2) + tansol = tansol2; + } + in = (in1 || in2); + strin = (strin1 || strin2); + break; + } + case SUB: + { + int hin, hstrin; + Solid * tansol1; + + s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol1, surfids, hin, hstrin, eps); + + if (tansol1) + tansol = new Solid (SUB, tansol1); + in = !hstrin; + strin = !hin; + break; + } + case ROOT: + { + s1 -> RecTangentialEdgeSolid (p, t, t2, m, tansol, surfids, in, strin, eps); + break; + } + } + } + + + + + + + + + + + + + + + + + int Solid :: Edge (const Point<3> & p, const Vec<3> & v, double eps) const + { + int in, strin, faces; + RecEdge (p, v, in, strin, faces, eps); + return faces >= 2; + } + + int Solid :: OnFace (const Point<3> & p, const Vec<3> & v, double eps) const + { + int in, strin, faces; + RecEdge (p, v, in, strin, faces, eps); + return faces >= 1; + } + + + void Solid :: RecEdge (const Point<3> & p, const Vec<3> & v, + int & in, int & strin, int & faces, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + INSOLID_TYPE ist = prim->VecInSolid (p, v, eps); + in = (ist == IS_INSIDE || ist == DOES_INTERSECT); + strin = (ist == IS_INSIDE); + /* + in = VectorIn (p, v); + strin = VectorStrictIn (p, v); + */ + faces = 0; + + if (in && ! strin) + { + // faces = 1; + int i; + Vec<3> grad; + for (i = 0; i < prim->GetNSurfaces(); i++) + { + double val = prim->GetSurface(i).CalcFunctionValue(p); + prim->GetSurface(i).CalcGradient (p, grad); + if (fabs (val) < eps && fabs (v * grad) < 1e-6) + faces++; + } + } + // else + // faces = 0; + break; + } + case SECTION: + { + int in1, in2, strin1, strin2, faces1, faces2; + + s1 -> RecEdge (p, v, in1, strin1, faces1, eps); + s2 -> RecEdge (p, v, in2, strin2, faces2, eps); + + faces = 0; + if (in1 && in2) + faces = faces1 + faces2; + in = in1 && in2; + strin = strin1 && strin2; + break; + } + case UNION: + { + int in1, in2, strin1, strin2, faces1, faces2; + + s1 -> RecEdge (p, v, in1, strin1, faces1, eps); + s2 -> RecEdge (p, v, in2, strin2, faces2, eps); + + faces = 0; + if (!strin1 && !strin2) + faces = faces1 + faces2; + in = in1 || in2; + strin = strin1 || strin2; + break; + } + case SUB: + { + int in1, strin1; + s1 -> RecEdge (p, v, in1, strin1, faces, eps); + in = !strin1; + strin = !in1; + break; + } + case ROOT: + { + s1 -> RecEdge (p, v, in, strin, faces, eps); + break; + } + } + } + + + void Solid :: CalcSurfaceInverse () + { + CalcSurfaceInverseRec (0); + } + + void Solid :: CalcSurfaceInverseRec (int inv) + { + switch (op) + { + case TERM: case TERM_REF: + { + bool priminv; + for (int i = 0; i < prim->GetNSurfaces(); i++) + { + priminv = (prim->SurfaceInverted(i) != 0); + if (inv) priminv = !priminv; + prim->GetSurface(i).SetInverse (priminv); + } + break; + } + case UNION: + case SECTION: + { + s1 -> CalcSurfaceInverseRec (inv); + s2 -> CalcSurfaceInverseRec (inv); + break; + } + case SUB: + { + s1 -> CalcSurfaceInverseRec (1 - inv); + break; + } + case ROOT: + { + s1 -> CalcSurfaceInverseRec (inv); + break; + } + } + } + + + Solid * Solid :: GetReducedSolid (const BoxSphere<3> & box) const + { + INSOLID_TYPE in; + return RecGetReducedSolid (box, in); + } + + Solid * Solid :: RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const + { + Solid * redsol = NULL; + + switch (op) + { + case TERM: + case TERM_REF: + { + in = prim -> BoxInSolid (box); + if (in == DOES_INTERSECT) + { + redsol = new Solid (prim); + redsol -> op = TERM_REF; + } + break; + } + case SECTION: + { + INSOLID_TYPE in1, in2; + Solid * redsol1, * redsol2; + + redsol1 = s1 -> RecGetReducedSolid (box, in1); + redsol2 = s2 -> RecGetReducedSolid (box, in2); + + if (in1 == IS_OUTSIDE || in2 == IS_OUTSIDE) + { + if (in1 == DOES_INTERSECT) delete redsol1; + if (in2 == DOES_INTERSECT) delete redsol2; + in = IS_OUTSIDE; + } + else + { + if (in1 == DOES_INTERSECT || in2 == DOES_INTERSECT) + in = DOES_INTERSECT; + else + in = IS_INSIDE; + + if (in1 == DOES_INTERSECT && in2 == DOES_INTERSECT) + redsol = new Solid (SECTION, redsol1, redsol2); + else if (in1 == DOES_INTERSECT) + redsol = redsol1; + else if (in2 == DOES_INTERSECT) + redsol = redsol2; + } + break; + } + + case UNION: + { + INSOLID_TYPE in1, in2; + Solid * redsol1, * redsol2; + + redsol1 = s1 -> RecGetReducedSolid (box, in1); + redsol2 = s2 -> RecGetReducedSolid (box, in2); + + if (in1 == IS_INSIDE || in2 == IS_INSIDE) + { + if (in1 == DOES_INTERSECT) delete redsol1; + if (in2 == DOES_INTERSECT) delete redsol2; + in = IS_INSIDE; + } + else + { + if (in1 == DOES_INTERSECT || in2 == DOES_INTERSECT) in = DOES_INTERSECT; + else in = IS_OUTSIDE; + + if (in1 == DOES_INTERSECT && in2 == DOES_INTERSECT) + redsol = new Solid (UNION, redsol1, redsol2); + else if (in1 == DOES_INTERSECT) + redsol = redsol1; + else if (in2 == DOES_INTERSECT) + redsol = redsol2; + } + break; + } + + case SUB: + { + INSOLID_TYPE in1; + Solid * redsol1 = s1 -> RecGetReducedSolid (box, in1); + + switch (in1) + { + case IS_OUTSIDE: in = IS_INSIDE; break; + case IS_INSIDE: in = IS_OUTSIDE; break; + case DOES_INTERSECT: in = DOES_INTERSECT; break; + } + + if (redsol1) + redsol = new Solid (SUB, redsol1); + break; + } + + case ROOT: + { + INSOLID_TYPE in1; + redsol = s1 -> RecGetReducedSolid (box, in1); + in = in1; + break; + } + } + + /* + if (redsol) + (*testout) << "getrecsolid, redsol = " << endl << (*redsol) << endl; + else + (*testout) << "redsol is null" << endl; + */ + + return redsol; + } + + + int Solid :: NumPrimitives () const + { + switch (op) + { + case TERM: case TERM_REF: + { + return 1; + } + case UNION: + case SECTION: + { + return s1->NumPrimitives () + s2 -> NumPrimitives(); + } + case SUB: + case ROOT: + { + return s1->NumPrimitives (); + } + } + return 0; + } + + void Solid :: GetSurfaceIndices (Array & surfind) const + { + surfind.SetSize (0); + RecGetSurfaceIndices (surfind); + } + + void Solid :: RecGetSurfaceIndices (Array & surfind) const + { + switch (op) + { + case TERM: case TERM_REF: + { + /* + int i; + for (i = 1; i <= surfind.Size(); i++) + if (surfind.Get(i) == prim->GetSurfaceId()) + return; + surfind.Append (prim->GetSurfaceId()); + break; + */ + for (int j = 0; j < prim->GetNSurfaces(); j++) + if (prim->SurfaceActive (j)) + { + bool found = 0; + int siprim = prim->GetSurfaceId(j); + + for (int i = 0; i < surfind.Size(); i++) + if (surfind[i] == siprim) + { + found = 1; + break; + } + if (!found) surfind.Append (siprim); + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetSurfaceIndices (surfind); + s2 -> RecGetSurfaceIndices (surfind); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetSurfaceIndices (surfind); + break; + } + } + } + + + + void Solid :: GetTangentialSurfaceIndices (const Point<3> & p, Array & surfind, double eps) const + { + surfind.SetSize (0); + RecGetTangentialSurfaceIndices (p, surfind, eps); + } + + void Solid :: RecGetTangentialSurfaceIndices (const Point<3> & p, Array & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + /* + for (int j = 0; j < prim->GetNSurfaces(); j++) + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + */ + prim->GetTangentialSurfaceIndices (p, surfind, eps); + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialSurfaceIndices (p, surfind, eps); + s2 -> RecGetTangentialSurfaceIndices (p, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialSurfaceIndices (p, surfind, eps); + break; + } + } + } + + + + + + + void Solid :: GetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, + Array & surfind, double eps) const + { + surfind.SetSize (0); + RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + } + + void Solid :: RecGetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, + Array & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + for (int j = 0; j < prim->GetNSurfaces(); j++) + { + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + prim->GetSurface(j).CalcGradient (p, grad); + if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2()) + { + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + } + } + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + s2 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialSurfaceIndices2 (p, v, surfind, eps); + break; + } + } + } + + + + + + + + + void Solid :: GetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + Array & surfind, double eps) const + { + surfind.SetSize (0); + RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + } + + void Solid :: RecGetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + Array & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + for (int j = 0; j < prim->GetNSurfaces(); j++) + { + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + prim->GetSurface(j).CalcGradient (p, grad); + if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2()) + { + Mat<3> hesse; + prim->GetSurface(j).CalcHesse (p, hesse); + double hv2 = v2 * grad + v * (hesse * v); + + if (fabs (hv2) < 1e-6) + { + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + } + /* + else + { + *testout << "QUAD NOT OK" << endl; + *testout << "v = " << v << ", v2 = " << v2 << endl; + *testout << "v * grad = " << v*grad << endl; + *testout << "v2 * grad = " << v2*grad << endl; + *testout << "v H v = " << v*(hesse*v) << endl; + *testout << "grad = " << grad << endl; + *testout << "hesse = " << hesse << endl; + *testout << "hv2 = " << v2 * grad + v * (hesse * v) << endl; + } + */ + } + } + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + s2 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialSurfaceIndices3 (p, v, v2, surfind, eps); + break; + } + } + } + + + + + + void Solid :: RecGetTangentialEdgeSurfaceIndices (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, const Vec<3> & m, + Array & surfind, double eps) const + { + switch (op) + { + case TERM: case TERM_REF: + { + // *testout << "check vecinsolid4, p = " << p << ", v = " << v << "; m = " << m << endl; + if (prim->VecInSolid4 (p, v, v2, m, eps) == DOES_INTERSECT) + { + prim->GetTangentialVecSurfaceIndices2 (p, v, m, surfind, eps); + /* + for (int j = 0; j < prim->GetNSurfaces(); j++) + { + if (fabs (prim->GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + prim->GetSurface(j).CalcGradient (p, grad); + *testout << "grad = " << grad << endl; + if (sqr (grad * v) < 1e-6 * v.Length2() * grad.Length2() && + sqr (grad * m) < 1e-6 * m.Length2() * grad.Length2() ) // new, 18032006 JS + + { + *testout << "add surf " << prim->GetSurfaceId(j) << endl; + if (!surfind.Contains (prim->GetSurfaceId(j))) + surfind.Append (prim->GetSurfaceId(j)); + } + } + } + */ + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps); + s2 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetTangentialEdgeSurfaceIndices (p, v, v2, m, surfind, eps); + break; + } + } + } + + + + + + + + + + + + + void Solid :: GetSurfaceIndices (IndexSet & iset) const + { + iset.Clear(); + RecGetSurfaceIndices (iset); + } + + void Solid :: RecGetSurfaceIndices (IndexSet & iset) const + { + switch (op) + { + case TERM: case TERM_REF: + { + /* + int i; + for (i = 1; i <= surfind.Size(); i++) + if (surfind.Get(i) == prim->GetSurfaceId()) + return; + surfind.Append (prim->GetSurfaceId()); + break; + */ + for (int j = 0; j < prim->GetNSurfaces(); j++) + if (prim->SurfaceActive (j)) + { + int siprim = prim->GetSurfaceId(j); + iset.Add (siprim); + } + break; + } + case UNION: + case SECTION: + { + s1 -> RecGetSurfaceIndices (iset); + s2 -> RecGetSurfaceIndices (iset); + break; + } + case SUB: + case ROOT: + { + s1 -> RecGetSurfaceIndices (iset); + break; + } + } + } + + + void Solid :: CalcOnePrimitiveSpecialPoints (const Box<3> & box, Array > & pts) const + { + double eps = 1e-8 * box.Diam (); + + pts.SetSize (0); + this -> RecCalcOnePrimitiveSpecialPoints (pts); + for (int i = pts.Size()-1; i >= 0; i--) + { + if (!IsIn (pts[i],eps) || IsStrictIn (pts[i],eps)) + pts.Delete (i); + } + } + + void Solid :: RecCalcOnePrimitiveSpecialPoints (Array > & pts) const + { + switch (op) + { + case TERM: case TERM_REF: + { + prim -> CalcSpecialPoints (pts); + break; + } + case UNION: + case SECTION: + { + s1 -> RecCalcOnePrimitiveSpecialPoints (pts); + s2 -> RecCalcOnePrimitiveSpecialPoints (pts); + break; + } + case SUB: + case ROOT: + { + s1 -> RecCalcOnePrimitiveSpecialPoints (pts); + break; + } + } + } + + + + + BlockAllocator Solid :: ball(sizeof (Solid)); +} diff --git a/libsrc/csg/solid.hpp b/libsrc/csg/solid.hpp new file mode 100644 index 00000000..ebd7c88c --- /dev/null +++ b/libsrc/csg/solid.hpp @@ -0,0 +1,246 @@ +#ifndef FILE_SOLID +#define FILE_SOLID + +/**************************************************************************/ +/* File: solid.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 1. Dez. 95 */ +/**************************************************************************/ + +namespace netgen +{ + + + /* + + Constructive Solid Model (csg) + + */ + + + + + class Solid; + + class SolidIterator + { + public: + SolidIterator () { ; } + virtual ~SolidIterator () { ; } + virtual void Do (Solid * sol) = 0; + }; + + + + class Solid + { + public: + + typedef enum optyp1 { TERM, TERM_REF, SECTION, UNION, SUB, ROOT /*, DUMMY */ } optyp; + + private: + char * name; + Primitive * prim; + Solid * s1, * s2; + + optyp op; + bool visited; + double maxh; + + // static int cntnames; + + public: + Solid (Primitive * aprim); + Solid (optyp aop, Solid * as1, Solid * as2 = NULL); + ~Solid (); + + const char * Name () const { return name; } + void SetName (const char * aname); + + Solid * Copy (class CSGeometry & geom) const; + void Transform (Transformation<3> & trans); + + + void IterateSolid (SolidIterator & it, bool only_once = 0); + + + void Boundaries (const Point<3> & p, Array & bounds) const; + int NumPrimitives () const; + void GetSurfaceIndices (Array & surfind) const; + void GetSurfaceIndices (IndexSet & iset) const; + + void GetTangentialSurfaceIndices (const Point<3> & p, Array & surfids, double eps) const; + void GetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, Array & surfids, double eps) const; + void GetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, Array & surfids, double eps) const; + + + Primitive * GetPrimitive () + { return (op == TERM || op == TERM_REF) ? prim : NULL; } + const Primitive * GetPrimitive () const + { return (op == TERM || op == TERM_REF) ? prim : NULL; } + + Solid * S1() { return s1; } + Solid * S2() { return s2; } + + // geometric tests + + bool IsIn (const Point<3> & p, double eps = 1e-6) const; + bool IsStrictIn (const Point<3> & p, double eps = 1e-6) const; + bool VectorIn (const Point<3> & p, const Vec<3> & v, double eps = 1e-6) const; + bool VectorStrictIn (const Point<3> & p, const Vec<3> & v, double eps = 1e-6) const; + + bool VectorIn2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + double eps) const; + bool VectorIn2Rec (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + double eps) const; + + + /// compute localization in point p + void TangentialSolid (const Point<3> & p, Solid *& tansol, Array & surfids, double eps) const; + + /// compute localization in point p tangential to vector t + void TangentialSolid2 (const Point<3> & p, const Vec<3> & t, + Solid *& tansol, Array & surfids, double eps) const; + + /** compute localization in point p, with second order approximation to edge + p + s t + s*s/2 t2 **/ + void TangentialSolid3 (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2, + Solid *& tansol, Array & surfids, double eps) const; + + + + /** tangential solid, which follows the edge + p + s t + s*s/2 t2 + with second order, and the neighbouring face + p + s t + s*s/2 t2 + r m + with first order + **/ + void TangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2, + const Vec<3> & m, + Solid *& tansol, Array & surfids, double eps) const; + + + void CalcOnePrimitiveSpecialPoints (const Box<3> & box, Array > & pts) const; + + /// + int Edge (const Point<3> & p, const Vec<3> & v, double eps) const; + /// + int OnFace (const Point<3> & p, const Vec<3> & v, double eps) const; + /// + void Print (ostream & str) const; + /// + void CalcSurfaceInverse (); + /// + Solid * GetReducedSolid (const BoxSphere<3> & box) const; + + + void SetMaxH (double amaxh) + { maxh = amaxh; } + double GetMaxH () const + { return maxh; } + + void GetSolidData (ostream & ost, int first = 1) const; + static Solid * CreateSolid (istream & ist, const SYMBOLTABLE & solids); + + + static BlockAllocator ball; + void * operator new(size_t /* s */) + { + return ball.Alloc(); + } + + void operator delete (void * p) + { + ball.Free (p); + } + + + protected: + /// + + void RecBoundaries (const Point<3> & p, Array & bounds, + int & in, int & strin) const; + /// + void RecTangentialSolid (const Point<3> & p, Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const; + + void RecTangentialSolid2 (const Point<3> & p, const Vec<3> & vec, + Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const; + /// + void RecTangentialSolid3 (const Point<3> & p, const Vec<3> & vec,const Vec<3> & vec2, + Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const; + /// + void RecTangentialEdgeSolid (const Point<3> & p, const Vec<3> & t, const Vec<3> & t2, + const Vec<3> & m, + Solid *& tansol, Array & surfids, + int & in, int & strin, double eps) const; + + /// + void RecEdge (const Point<3> & p, const Vec<3> & v, + int & in, int & strin, int & faces, double eps) const; + /// + void CalcSurfaceInverseRec (int inv); + /// + Solid * RecGetReducedSolid (const BoxSphere<3> & box, INSOLID_TYPE & in) const; + /// + void RecGetSurfaceIndices (Array & surfind) const; + void RecGetTangentialSurfaceIndices (const Point<3> & p, Array & surfids, double eps) const; + void RecGetTangentialSurfaceIndices2 (const Point<3> & p, const Vec<3> & v, Array & surfids, double eps) const; + void RecGetTangentialSurfaceIndices3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + Array & surfids, double eps) const; + void RecGetTangentialEdgeSurfaceIndices (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, const Vec<3> & m, + Array & surfids, double eps) const; + void RecGetSurfaceIndices (IndexSet & iset) const; + + void RecCalcOnePrimitiveSpecialPoints (Array > & pts) const; + + friend class SolidIterator; + friend class ClearVisitedIt; + friend class RemoveDummyIterator; + friend class CSGeometry; + }; + + + inline ostream & operator<< (ostream & ost, const Solid & sol) + { + sol.Print (ost); + return ost; + } + + + + + + + class ReducePrimitiveIterator : public SolidIterator + { + const BoxSphere<3> & box; + public: + ReducePrimitiveIterator (const BoxSphere<3> & abox) + : SolidIterator(), box(abox) { ; } + virtual ~ReducePrimitiveIterator () { ; } + virtual void Do (Solid * sol) + { + if (sol -> GetPrimitive()) + sol -> GetPrimitive() -> Reduce (box); + } + }; + + + class UnReducePrimitiveIterator : public SolidIterator + { + public: + UnReducePrimitiveIterator () { ; } + virtual ~UnReducePrimitiveIterator () { ; } + virtual void Do (Solid * sol) + { + if (sol -> GetPrimitive()) + sol -> GetPrimitive() -> UnReduce (); + } + }; + +} + +#endif diff --git a/libsrc/csg/specpoin.cpp b/libsrc/csg/specpoin.cpp new file mode 100644 index 00000000..f4c5f946 --- /dev/null +++ b/libsrc/csg/specpoin.cpp @@ -0,0 +1,2099 @@ +#include +#include +#include + + +/* + Special Point calculation uses the global Flags: + + relydegtest when to rely on degeneration ? + calccp calculate points of intersection ? + cpeps1 eps for degenerated poi + calcep calculate points of extreme coordinates ? + epeps1 eps for degenerated edge + epeps2 eps for axis parallel pec + epspointdist eps for distance of special points +*/ + + +// #define DEVELOP + + +namespace netgen +{ + Array > boxes; + + + void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp); + + enum { check_crosspoint = 5 }; + + SpecialPoint :: SpecialPoint (const SpecialPoint & sp) + { + p = sp.p; + v = sp.v; + s1 = sp.s1; + s2 = sp.s2; + s1_orig = sp.s1_orig; + s2_orig = sp.s2_orig; + layer = sp.layer; + unconditional = sp.unconditional; + } + + SpecialPoint & SpecialPoint :: operator= (const SpecialPoint & sp) + { + p = sp.p; + v = sp.v; + s1 = sp.s1; + s2 = sp.s2; + s1_orig = sp.s1_orig; + s2_orig = sp.s2_orig; + layer = sp.layer; + unconditional = sp.unconditional; + return *this; + } + + + void SpecialPoint :: Print (ostream & str) const + { + str << "p = " << p << " v = " << v + << " s1/s2 = " << s1 << "/" << s2; + str << " layer = " << layer + << " unconditional = " << unconditional + << endl; + } + + + static Array numprim_hist; + + SpecialPointCalculation :: SpecialPointCalculation () + { + ideps = 1e-9; + } + + void SpecialPointCalculation :: + CalcSpecialPoints (const CSGeometry & ageometry, + Array & apoints) + { + static int timer = NgProfiler::CreateTimer ("CSG: find special points"); + NgProfiler::RegionTimer reg (timer); + + + geometry = &ageometry; + points = &apoints; + + size = geometry->MaxSize(); + (*testout) << "Find Special Points" << endl; + (*testout) << "maxsize = " << size << endl; + + cpeps1 = 1e-6; + epeps1 = 1e-3; + epeps2 = 1e-6; + + epspointdist2 = sqr (size * 1e-8); + relydegtest = size * 1e-4; + + + BoxSphere<3> box (Point<3> (-size, -size, -size), + Point<3> ( size, size, size)); + + box.CalcDiamCenter(); + PrintMessage (3, "main-solids: ", geometry->GetNTopLevelObjects()); + + numprim_hist.SetSize (geometry->GetNSurf()+1); + numprim_hist = 0; + + for (int i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + const TopLevelObject * tlo = geometry->GetTopLevelObject(i); + + (*testout) << "tlo " << i << ":" << endl + << *tlo->GetSolid() << endl; + + if (tlo->GetSolid()) + { + Array > hpts; + tlo->GetSolid()->CalcOnePrimitiveSpecialPoints (box, hpts); + // if (hpts.Size()) + // cout << "oneprimitivespecialpoints = " << hpts << endl; + for (int j = 0; j < hpts.Size(); j++) + AddPoint (hpts[j], tlo->GetLayer()); + } + + CalcSpecialPointsRec (tlo->GetSolid(), tlo->GetLayer(), + box, 1, 1, 1); + } + + + geometry->DeleteIdentPoints(); + for (int i = 0; i < geometry->GetNIdentifications(); i++) + { + CloseSurfaceIdentification * ident = + dynamic_cast(geometry->identifications[i]); + + if(!ident || !ident->IsSkewIdentification()) + continue; + + for(int j=0; jSize(); j++) + { + if(fabs(ident->GetSurface1().CalcFunctionValue((*points)[j])) < 1e-15) + { + Point<3> auxpoint = (*points)[j]; + ident->GetSurface2().SkewProject(auxpoint,ident->GetDirection()); + geometry->AddIdentPoint(auxpoint); + geometry->AddIdentPoint((*points)[j]); + AddPoint (auxpoint,1); + +#ifdef DEVELOP + (*testout) << "added identpoint " << auxpoint << "; proj. of " + << (*points)[j] << endl; +#endif + break; + } + } + } + + + // add user point: + for (int i = 0; i < geometry->GetNUserPoints(); i++) + AddPoint (geometry->GetUserPoint(i), 1); + + + PrintMessage (3, "Found points ", apoints.Size()); + + for (int i = 0; i < boxesinlevel.Size(); i++) + (*testout) << "level " << i << " has " + << boxesinlevel[i] << " boxes" << endl; + (*testout) << "numprim_histogramm = " << endl << numprim_hist << endl; + } + + + + void SpecialPointCalculation :: + CalcSpecialPointsRec (const Solid * sol, int layer, + const BoxSphere<3> & box, + int level, bool calccp, bool calcep) + { + // boxes.Append (box); + +#ifdef DEVELOP + *testout << "lev " << level << ", box = " << box << endl; + *testout << "calccp = " << calccp << ", calcep = " << calcep << endl; + *testout << "locsol = " << *sol << endl; +#endif + + if (multithread.terminate) + { + *testout << "boxes = " << boxes << endl; + *testout << "boxesinlevel = " << boxesinlevel << endl; + throw NgException ("Meshing stopped"); + } + + + if (!sol) return; + + if (level >= 100) + { + MyStr err = + MyStr("Problems in CalcSpecialPoints\nPoint: ") + MyStr (box.Center()); + throw NgException (err.c_str()); + } + + + bool decision; + bool possiblecrossp, possibleexp; // possible cross or extremalpoint + bool surecrossp = 0, sureexp = 0; // sure ... + + static Array locsurf; // attention: array is static + + static int cntbox = 0; + cntbox++; + + if (level <= boxesinlevel.Size()) + boxesinlevel.Elem(level)++; + else + boxesinlevel.Append (1); + + /* + numprim = sol -> NumPrimitives(); + sol -> GetSurfaceIndices (locsurf); + */ + + geometry -> GetIndependentSurfaceIndices (sol, box, locsurf); + int numprim = locsurf.Size(); + +#ifdef DEVELOP + (*testout) << "numprim = " << numprim << endl; +#endif + + numprim_hist[numprim]++; + + Point<3> p = box.Center(); + + + // explicit solution for planes only and at most one quadratic + if (numprim <= check_crosspoint) + { + int nplane = 0, nquad = 0, quadi = -1, nsphere = 0; + const QuadraticSurface *qsurf = 0, *qsurfi; + + for (int i = 0; i < numprim; i++) + { + qsurfi = dynamic_cast + (geometry->GetSurface(locsurf[i])); + + if (qsurfi) nquad++; + if (dynamic_cast (qsurfi)) + nplane++; + else + { + quadi = i; + qsurf = qsurfi; + } + + if (dynamic_cast (qsurfi)) + nsphere++; + } + + /* + if (nquad == numprim && nplane == numprim-2) + return; + */ + +#ifdef DEVELOP + (*testout) << "nquad " << nquad << " nplane " << nplane << endl; +#endif + + if (nquad == numprim && nplane >= numprim-1) + { + Array > pts; + Array surfids; + + for (int k1 = 0; k1 < numprim - 2; k1++) + for (int k2 = k1 + 1; k2 < numprim - 1; k2++) + for (int k3 = k2 + 1; k3 < numprim; k3++) + if (k1 != quadi && k2 != quadi && k3 != quadi) + { + ComputeCrossPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + dynamic_cast (geometry->GetSurface(locsurf[k2])), + dynamic_cast (geometry->GetSurface(locsurf[k3])), + pts); + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + + if(!tansol) + continue; + + bool ok1 = false, ok2 = false, ok3 = false; + int rep1 = geometry->GetSurfaceClassRepresentant(locsurf[k1]); + int rep2 = geometry->GetSurfaceClassRepresentant(locsurf[k2]); + int rep3 = geometry->GetSurfaceClassRepresentant(locsurf[k3]); + for(int jj=0; jjGetSurfaceClassRepresentant(surfids[jj]); + if(actrep == rep1) ok1 = true; + if(actrep == rep2) ok2 = true; + if(actrep == rep3) ok3 = true; + } + + + if (tansol && ok1 && ok2 && ok3) + // if (sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size)) + { + if (AddPoint (pts[j], layer)) + (*testout) << "cross point found, 1: " << pts[j] << endl; + } + delete tansol; + } + } + + + if (qsurf) + { + for (int k1 = 0; k1 < numprim - 1; k1++) + for (int k2 = k1 + 1; k2 < numprim; k2++) + if (k1 != quadi && k2 != quadi) + { + ComputeCrossPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + dynamic_cast (geometry->GetSurface(locsurf[k2])), + qsurf, pts); + //(*testout) << "checking pot. crosspoints: " << pts << endl; + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + + if(!tansol) + continue; + + bool ok1 = false, ok2 = false, ok3 = true;//false; + int rep1 = geometry->GetSurfaceClassRepresentant(locsurf[k1]); + int rep2 = geometry->GetSurfaceClassRepresentant(locsurf[k2]); + //int rep3 = geometry->GetSurfaceClassRepresentant(quadi); + for(int jj=0; jjGetSurfaceClassRepresentant(surfids[jj]); + if(actrep == rep1) ok1 = true; + if(actrep == rep2) ok2 = true; + //if(actrep == rep3) ok3 = true; + } + + + if (tansol && ok1 && ok2 && ok3) + //if (sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size) ) + { + if (AddPoint (pts[j], layer)) + (*testout) << "cross point found, 2: " << pts[j] << endl; + } + delete tansol; + } + } + + + for (int k1 = 0; k1 < numprim; k1++) + if (k1 != quadi) + { + ComputeExtremalPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + qsurf, pts); + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + if (tansol) + // sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size) ) + { + if (AddPoint (pts[j], layer)) + (*testout) << "extremal point found, 1: " << pts[j] << endl; + } + delete tansol; + } + } + } + + return; + } + + + + if (nsphere == numprim) // && calccp == false) + { + Array > pts; + Array surfids; + + + + for (int k1 = 0; k1 < numprim; k1++) + for (int k2 = 0; k2 < k1; k2++) + for (int k3 = 0; k3 < k2; k3++) + { + ComputeCrossPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + dynamic_cast (geometry->GetSurface(locsurf[k2])), + dynamic_cast (geometry->GetSurface(locsurf[k3])), + pts); + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + + if(!tansol) + continue; + + bool ok1 = false, ok2 = false, ok3 = false; + int rep1 = geometry->GetSurfaceClassRepresentant(locsurf[k1]); + int rep2 = geometry->GetSurfaceClassRepresentant(locsurf[k2]); + int rep3 = geometry->GetSurfaceClassRepresentant(locsurf[k3]); + for(int jj=0; jjGetSurfaceClassRepresentant(surfids[jj]); + if(actrep == rep1) ok1 = true; + if(actrep == rep2) ok2 = true; + if(actrep == rep3) ok3 = true; + } + + + if (tansol && ok1 && ok2 && ok3) + // if (sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size)) + { + if (AddPoint (pts[j], layer)) + (*testout) << "cross point found, 1: " << pts[j] << endl; + } + delete tansol; + } + } + + + for (int k1 = 0; k1 < numprim; k1++) + for (int k2 = 0; k2 < k1; k2++) + { + ComputeExtremalPoints (dynamic_cast (geometry->GetSurface(locsurf[k1])), + dynamic_cast (geometry->GetSurface(locsurf[k2])), + pts); + + for (int j = 0; j < pts.Size(); j++) + if (Dist (pts[j], box.Center()) < box.Diam()/2) + { + Solid * tansol; + sol -> TangentialSolid (pts[j], tansol, surfids, 1e-9*size); + if (tansol) + // sol -> IsIn (pts[j], 1e-6*size) && !sol->IsStrictIn (pts[j], 1e-6*size) ) + { + if (AddPoint (pts[j], layer)) + (*testout) << "extremal point found, spheres: " << pts[j] << endl; + } + delete tansol; + } + } + + return; + } + } + + + + possiblecrossp = (numprim >= 3) && calccp; + surecrossp = 0; + + if (possiblecrossp && (locsurf.Size() <= check_crosspoint || level > 50)) + { + decision = 1; + surecrossp = 0; + + for (int k1 = 1; k1 <= locsurf.Size() - 2; k1++) + for (int k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) + for (int k3 = k2 + 1; k3 <= locsurf.Size(); k3++) + { + int nc, deg; + nc = CrossPointNewtonConvergence + (geometry->GetSurface(locsurf.Get(k1)), + geometry->GetSurface(locsurf.Get(k2)), + geometry->GetSurface(locsurf.Get(k3)), box ); + + deg = CrossPointDegenerated + (geometry->GetSurface(locsurf.Get(k1)), + geometry->GetSurface(locsurf.Get(k2)), + geometry->GetSurface(locsurf.Get(k3)), box ); + +#ifdef DEVELOP + (*testout) << "k1,2,3 = " << k1 << "," << k2 << "," << k3 << ", nc = " << nc << ", deg = " << deg << endl; +#endif + + + if (!nc && !deg) decision = 0; + if (nc) surecrossp = 1; + } + +#ifdef DEVELOP + (*testout) << "dec = " << decision << ", surcp = " << surecrossp << endl; +#endif + + if (decision && surecrossp) + { + for (int k1 = 1; k1 <= locsurf.Size() - 2; k1++) + for (int k2 = k1 + 1; k2 <= locsurf.Size() - 1; k2++) + for (int k3 = k2 + 1; k3 <= locsurf.Size(); k3++) + { + if (CrossPointNewtonConvergence + (geometry->GetSurface(locsurf.Get(k1)), + geometry->GetSurface(locsurf.Get(k2)), + geometry->GetSurface(locsurf.Get(k3)), box ) ) + { + + Point<3> pp = p; + CrossPointNewton + (geometry->GetSurface(locsurf.Get(k1)), + geometry->GetSurface(locsurf.Get(k2)), + geometry->GetSurface(locsurf.Get(k3)), pp); + + BoxSphere<3> hbox (pp, pp); + hbox.Increase (1e-8*size); + + if (pp(0) > box.PMin()(0) - 1e-5*size && + pp(0) < box.PMax()(0) + 1e-5*size && + pp(1) > box.PMin()(1) - 1e-5*size && + pp(1) < box.PMax()(1) + 1e-5*size && + pp(2) > box.PMin()(2) - 1e-5*size && + pp(2) < box.PMax()(2) + 1e-5*size && + sol -> IsIn (pp, 1e-6*size) && !sol->IsStrictIn (pp, 1e-6*size) && + !CrossPointDegenerated + (geometry->GetSurface(locsurf.Get(k1)), + geometry->GetSurface(locsurf.Get(k2)), + geometry->GetSurface(locsurf.Get(k3)), hbox )) + + { + // AddCrossPoint (locsurf, sol, p); + BoxSphere<3> boxp (pp, pp); + boxp.Increase (1e-3*size); + boxp.CalcDiamCenter(); + Array locsurf2; + + geometry -> GetIndependentSurfaceIndices (sol, boxp, locsurf2); + + bool found1 = false, found2 = false, found3 = false; + for (int i = 0; i < locsurf2.Size(); i++) + { + if (locsurf2[i] == locsurf.Get(k1)) found1 = true; + if (locsurf2[i] == locsurf.Get(k2)) found2 = true; + if (locsurf2[i] == locsurf.Get(k3)) found3 = true; + } + + if (found1 && found2 && found3) + if (AddPoint (pp, layer)) + { + (*testout) << "Crosspoint found: " << pp + << " diam = " << box.Diam() + << ", surfs: " + << locsurf.Get(k1) << "," + << locsurf.Get(k2) << "," + << locsurf.Get(k3) << endl; + } + } + } + } + } + + if (decision) + possiblecrossp = 0; + } + + + possibleexp = (numprim >= 2) && calcep; + + // (*testout) << "l = " << level << "locsize = " << locsurf.Size() << " possexp = " << possibleexp << "\n"; + if (possibleexp && (numprim <= check_crosspoint || level >= 50)) + { + decision = 1; + sureexp = 0; + + /* + (*testout) << "extremal surfs = "; + for (int k5 = 0; k5 < locsurf.Size(); k5++) + (*testout) << typeid(*geometry->GetSurface(locsurf[k5])).name() << " "; + (*testout) << "\n"; + */ + + for (int k1 = 0; k1 < locsurf.Size() - 1; k1++) + for (int k2 = k1+1; k2 < locsurf.Size(); k2++) + { + const Surface * surf1 = geometry->GetSurface(locsurf[k1]); + const Surface * surf2 = geometry->GetSurface(locsurf[k2]); + /* + (*testout) << "edgecheck, types = " << typeid(*surf1).name() << ", " << typeid(*surf2).name() + << "edge-newton-conv = " << EdgeNewtonConvergence (surf1, surf2, p) + << "edge-deg = " << EdgeDegenerated (surf1, surf2, box) + << "\n"; + */ + + if (EdgeNewtonConvergence (surf1, surf2, p) ) + sureexp = 1; + else + { + if (!EdgeDegenerated (surf1, surf2, box)) + decision = 0; + } + } + + // (*testout) << "l = " << level << " dec/sureexp = " << decision << sureexp << endl; + + if (decision && sureexp) + { + for (int k1 = 0; k1 < locsurf.Size() - 1; k1++) + for (int k2 = k1+1; k2 < locsurf.Size(); k2++) + { + const Surface * surf1 = geometry->GetSurface(locsurf[k1]); + const Surface * surf2 = geometry->GetSurface(locsurf[k2]); + + if (EdgeNewtonConvergence (surf1, surf2, p)) + { + EdgeNewton (surf1, surf2, p); + + Point<3> pp; + if (IsEdgeExtremalPoint (surf1, surf2, p, pp, box.Diam()/2)) + { + (*testout) << "extremalpoint (nearly) found:" << pp << endl; + + if (Dist (pp, box.Center()) < box.Diam()/2 && + sol -> IsIn (pp, 1e-6*size) && !sol->IsStrictIn (pp, 1e-6*size) ) + { + if (AddPoint (pp, layer)) + (*testout) << "Extremal point found: " << pp << endl;//"(eps="<<1e-9*size<<")"<< endl; + } + } + } + } + } + if (decision) + possibleexp = 0; + } + + + // (*testout) << "l = " << level << " poss cp/ep sure exp = " << possiblecrossp << " " << possibleexp << " " << sureexp << "\n"; + if (possiblecrossp || possibleexp) + { + BoxSphere<3> sbox; + for (int i = 0; i < 8; i++) + { + box.GetSubBox (i, sbox); + sbox.Increase (1e-4 * sbox.Diam()); + sbox.CalcDiamCenter(); + Solid * redsol = sol -> GetReducedSolid (sbox); + + if (redsol) + { + CalcSpecialPointsRec (redsol, layer, sbox, level+1, calccp, calcep); + delete redsol; + } + } + } + } + + + + + + /******* Tests for Point of intersection **********************/ + + + + bool SpecialPointCalculation :: + CrossPointNewtonConvergence (const Surface * f1, + const Surface * f2, + const Surface * f3, + const BoxSphere<3> & box) + { + Vec<3> grad, rs, x; + Mat<3> jacobi, inv; + Point<3> p = box.Center(); + + f1->CalcGradient (p, grad); + jacobi(0,0) = grad(0); + jacobi(0,1) = grad(1); + jacobi(0,2) = grad(2); + + f2->CalcGradient (p, grad); + jacobi(1,0) = grad(0); + jacobi(1,1) = grad(1); + jacobi(1,2) = grad(2); + + f3->CalcGradient (p, grad); + jacobi(2,0) = grad(0); + jacobi(2,1) = grad(1); + jacobi(2,2) = grad(2); + + if (fabs (Det (jacobi)) > 1e-8) + { + double gamma = f1 -> HesseNorm() + f2 -> HesseNorm() + f3 -> HesseNorm(); + if (gamma == 0.0) return 1; + + CalcInverse (jacobi, inv); + + rs(0) = f1->CalcFunctionValue (p); + rs(1) = f2->CalcFunctionValue (p); + rs(2) = f3->CalcFunctionValue (p); + + x = inv * rs; + + double beta = 0; + for (int i = 0; i < 3; i++) + { + double sum = 0; + for (int j = 0; j < 3; j++) + sum += fabs (inv(i,j)); + if (sum > beta) beta = sum; + } + double eta = Abs (x); + + +#ifdef DEVELOP + *testout << "check Newton: " << "beta = " << beta << ", gamma = " << gamma << ", eta = " << eta << endl; + double rad = 1.0 / (beta * gamma); + *testout << "rad = " << rad << endl; + *testout << "rs = " << rs << endl; +#endif + + return (beta * gamma * eta < 0.1) && (2 > box.Diam()*beta*gamma); + } + return 0; + + } + + + + + bool SpecialPointCalculation :: + CrossPointDegenerated (const Surface * f1, + const Surface * f2, + const Surface * f3, + const BoxSphere<3> & box) const + { + Mat<3> mat; + Vec<3> g1, g2, g3; + double normprod; + + if (box.Diam() > relydegtest) return 0; + + f1->CalcGradient (box.Center(), g1); + normprod = Abs2 (g1); + + f2->CalcGradient (box.Center(), g2); + normprod *= Abs2 (g2); + + f3->CalcGradient (box.Center(), g3); + normprod *= Abs2 (g3); + + for (int i = 0; i < 3; i++) + { + mat(i,0) = g1(i); + mat(i,1) = g2(i); + mat(i,2) = g3(i); + } + + return sqr (Det (mat)) < sqr(cpeps1) * normprod; + } + + + + + + void SpecialPointCalculation :: CrossPointNewton (const Surface * f1, + const Surface * f2, + const Surface * f3, Point<3> & p) + { + Vec<3> g1, g2, g3; + Vec<3> rs, sol; + Mat<3> mat; + + int i = 10; + while (i > 0) + { + i--; + rs(0) = f1->CalcFunctionValue (p); + rs(1) = f2->CalcFunctionValue (p); + rs(2) = f3->CalcFunctionValue (p); + + f1->CalcGradient (p, g1); + f2->CalcGradient (p, g2); + f3->CalcGradient (p, g3); + + for (int j = 0; j < 3; j++) + { + mat(0, j) = g1(j); + mat(1, j) = g2(j); + mat(2, j) = g3(j); + } + mat.Solve (rs, sol); + if (sol.Length2() < 1e-24 && i > 1) i = 1; + +#ifdef DEVELOP + *testout << "CrossPointNewton, err = " << sol.Length2() << endl; +#endif + p -= sol; + } + } + + + + + /******* Tests for Point on edges **********************/ + + + + + bool SpecialPointCalculation :: + EdgeNewtonConvergence (const Surface * f1, const Surface * f2, + const Point<3> & p) + { + Vec<3> g1, g2, sol; + Vec<2> vrs; + Mat<2,3> mat; + Mat<3,2> inv; + + f1->CalcGradient (p, g1); + f2->CalcGradient (p, g2); + + if ( sqr(g1 * g2) < (1 - 1e-8) * Abs2 (g1) * Abs2 (g2)) + { + double gamma = f1 -> HesseNorm() + f2 -> HesseNorm(); + if (gamma < 1e-32) return 1; + gamma = sqr (gamma); + + for (int i = 0; i < 3; i++) + { + mat(0,i) = g1(i); + mat(1,i) = g2(i); + } + + CalcInverse (mat, inv); + + vrs(0) = f1->CalcFunctionValue (p); + vrs(1) = f2->CalcFunctionValue (p); + sol = inv * vrs; + + double beta = 0; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 2; j++) + beta += inv(i,j) * inv(i,j); + // beta = sqrt (beta); + + double eta = Abs2 (sol); + + // alpha = beta * gamma * eta; + return (beta * gamma * eta < 0.01); + } + return 0; + } + + + + + bool SpecialPointCalculation :: + EdgeDegenerated (const Surface * f1, + const Surface * f2, + const BoxSphere<3> & box) const + { + // perform newton steps. normals parallel ? + // if not decideable: return 0 + + Point<3> p = box.Center(); + Vec<3> g1, g2, sol; + Vec<2> vrs; + Mat<2,3> mat; + + int i = 20; + while (i > 0) + { + if (Dist2 (p, box.Center()) > sqr(box.Diam())) + return 0; + + i--; + vrs(0) = f1->CalcFunctionValue (p); + vrs(1) = f2->CalcFunctionValue (p); + + f1->CalcGradient (p, g1); + f2->CalcGradient (p, g2); + + if ( sqr (g1 * g2) > (1 - 1e-10) * Abs2 (g1) * Abs2 (g2)) + return 1; + + for (int j = 0; j < 3; j++) + { + mat(0,j) = g1(j); + mat(1,j) = g2(j); + } + mat.Solve (vrs, sol); + + if (Abs2 (sol) < 1e-24 && i > 1) i = 1; + p -= sol; + } + + return 0; + } + + + + + + + void SpecialPointCalculation :: EdgeNewton (const Surface * f1, + const Surface * f2, Point<3> & p) + { + Vec<3> g1, g2, sol; + Vec<2> vrs; + Mat<2,3> mat; + + int i = 10; + while (i > 0) + { + i--; + vrs(0) = f1->CalcFunctionValue (p); + vrs(1) = f2->CalcFunctionValue (p); + + f1->CalcGradient (p, g1); + f2->CalcGradient (p, g2); + + //(*testout) << "p " << p << " f1 " << vrs(0) << " f2 " << vrs(1) << " g1 " << g1 << " g2 " << g2 << endl; + + for (int j = 0; j < 3; j++) + { + mat(0,j) = g1(j); + mat(1,j) = g2(j); + } + mat.Solve (vrs, sol); + + if (Abs2 (sol) < 1e-24 && i > 1) i = 1; + p -= sol; + } + } + + + + bool SpecialPointCalculation :: + IsEdgeExtremalPoint (const Surface * f1, const Surface * f2, + const Point<3> & p, Point<3> & pp, double rad) + { + Vec<3> g1, g2, t, t1, t2; + + f1->CalcGradient (p, g1); + f2->CalcGradient (p, g2); + + t = Cross (g1, g2); + t.Normalize(); + + Point<3> p1 = p + rad * t; + Point<3> p2 = p - rad * t; + + EdgeNewton (f1, f2, p1); + EdgeNewton (f1, f2, p2); + + f1->CalcGradient (p1, g1); + f2->CalcGradient (p1, g2); + t1 = Cross (g1, g2); + t1.Normalize(); + + f1->CalcGradient (p2, g1); + f2->CalcGradient (p2, g2); + t2 = Cross (g1, g2); + t2.Normalize(); + + double val = 1e-8 * rad * rad; + for (int j = 0; j < 3; j++) + if ( (t1(j) * t2(j) < -val) ) + { + pp = p; + ExtremalPointNewton (f1, f2, j+1, pp); + return 1; + } + + return 0; + } + + + + + + + + + + /********** Tests of Points of extremal coordinates ****************/ + + + void SpecialPointCalculation :: ExtremalPointNewton (const Surface * f1, + const Surface * f2, + int dir, Point<3> & p) + { + Vec<3> g1, g2, v, curv; + Vec<3> rs, x, y1, y2, y; + Mat<3> h1, h2; + Mat<3> jacobi; + + int i = 50; + while (i > 0) + { + i--; + rs(0) = f1->CalcFunctionValue (p); + rs(1) = f2->CalcFunctionValue (p); + + f1 -> CalcGradient (p, g1); + f2 -> CalcGradient (p, g2); + + f1 -> CalcHesse (p, h1); + f2 -> CalcHesse (p, h2); + + v = Cross (g1, g2); + + rs(2) = v(dir-1); + + jacobi(0,0) = g1(0); + jacobi(0,1) = g1(1); + jacobi(0,2) = g1(2); + + jacobi(1,0) = g2(0); + jacobi(1,1) = g2(1); + jacobi(1,2) = g2(2); + + + switch (dir) + { + case 1: + { + y1(0) = 0; + y1(1) = g2(2); + y1(2) = -g2(1); + y2(0) = 0; + y2(1) = -g1(2); + y2(2) = g1(1); + break; + } + case 2: + { + y1(0) = -g2(2); + y1(1) = 0; + y1(2) = g2(0); + y2(0) = g1(2); + y2(1) = 0; + y2(2) = -g1(0); + break; + } + case 3: + { + y1(0) = g2(1); + y1(1) = -g2(0); + y1(2) = 0; + y2(0) = -g1(1); + y2(1) = g1(0); + y2(2) = 0; + break; + } + } + + y = h1 * y1 + h2 * y2; + + jacobi(2,0) = y(0); + jacobi(2,1) = y(1); + jacobi(2,2) = y(2); + + /* + (*testout) << "p " << p << " f1 " << rs(0) << " f2 " << rs(1) << endl + << " jacobi " << jacobi << endl + << " rhs " << rs << endl; + */ + + jacobi.Solve (rs, x); + + if (Abs2 (x) < 1e-24 && i > 1) + { + i = 1; + } + + + double minval(Abs2(rs)),minfac(1); + double startval(minval); + for(double fac = 1; fac > 1e-7; fac *= 0.6) + { + Point<3> testpoint = p-fac*x; + + rs(0) = f1->CalcFunctionValue (testpoint); + rs(1) = f2->CalcFunctionValue (testpoint); + + f1 -> CalcGradient (testpoint, g1); + f2 -> CalcGradient (testpoint, g2); + + v = Cross (g1, g2); + + rs(2) = v(dir-1); + + double val = Abs2(rs); + + if(val < minval) + { + minfac = fac; + if(val < 0.5 * startval) + break; + minval = val; + } + + } + p -= minfac*x; + + + //p -= x; + } + + + if (Abs2 (x) > 1e-20) + { + (*testout) << "Error: extremum Newton not convergent" << endl; + (*testout) << "dir = " << dir << endl; + (*testout) << "p = " << p << endl; + (*testout) << "x = " << x << endl; + } + } + + void SpecialPointCalculation :: + ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const Plane * plane3, + Array > & pts) + { + Mat<3> mat; + Vec<3> rhs, sol; + Point<3> p0(0,0,0); + + pts.SetSize (0); + for (int i = 0; i < 3; i++) + { + const Plane * pi(NULL); + switch (i) + { + case 0: pi = plane1; break; + case 1: pi = plane2; break; + case 2: pi = plane3; break; + } + + double val; + Vec<3> hvec; + val = pi -> CalcFunctionValue(p0); + pi -> CalcGradient (p0, hvec); + + for (int j = 0; j < 3; j++) + mat(i,j) = hvec(j); + rhs(i) = -val; + } + + if (fabs (Det (mat)) > 1e-8) + { + mat.Solve (rhs, sol); + pts.Append (Point<3> (sol)); + } + } + + + + + + void SpecialPointCalculation :: + ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const QuadraticSurface * quadric, + Array > & pts) + { + Mat<2,3> mat; + Mat<3,2> inv; + Vec<2> rhs; + Vec<3> sol, t; + Point<3> p0(0,0,0); + + pts.SetSize (0); + for (int i = 0; i < 2; i++) + { + const Plane * pi(NULL); + switch (i) + { + case 0: pi = plane1; break; + case 1: pi = plane2; break; + } + + double val; + Vec<3> hvec; + val = pi -> CalcFunctionValue(p0); + pi -> CalcGradient (p0, hvec); + + for (int j = 0; j < 3; j++) + mat(i,j) = hvec(j); + rhs(i) = -val; + } + CalcInverse (mat, inv); + sol = inv * rhs; + t = Cross (mat.Row(0), mat.Row(1)); + + if (t.Length() > 1e-8) + { + Point<3> p (sol); + // quadratic on p + s t = 0 + double quad_a; + Vec<3> quad_b; + Mat<3> quad_c; + + quad_a = quadric -> CalcFunctionValue(p); + quadric -> CalcGradient (p, quad_b); + quadric -> CalcHesse (p, quad_c); + + double a, b, c; + a = quad_a; + b = quad_b * t; + c = 0.5 * t * (quad_c * t); + + // a + s b + s^2 c = 0; + double disc = b*b-4*a*c; + if (disc > 1e-10 * fabs (b)) + { + disc = sqrt (disc); + double s1 = (-b-disc) / (2*c); + double s2 = (-b+disc) / (2*c); + + pts.Append (p + s1 * t); + pts.Append (p + s2 * t); + } + } + } + + + + + + void SpecialPointCalculation :: + ComputeCrossPoints (const Sphere * sphere1, + const Sphere * sphere2, + const Sphere * sphere3, + Array > & pts) + { + Mat<2,3> mat; + Mat<3,2> inv; + Vec<2> rhs; + Vec<3> sol, t; + Point<3> p0(0,0,0); + + pts.SetSize (0); + + + Point<3> c1 = sphere1 -> Center(); + Point<3> c2 = sphere2 -> Center(); + Point<3> c3 = sphere3 -> Center(); + double r1 = sphere1 -> Radius(); + double r2 = sphere2 -> Radius(); + double r3 = sphere3 -> Radius(); + + + Vec<3> a1 = c2-c1; + double b1 = 0.5 * (sqr(r1) - sqr(r2) - Abs2(Vec<3> (c1)) + Abs2(Vec<3> (c2)) ); + + Vec<3> a2 = c3-c1; + double b2 = 0.5 * (sqr(r1) - sqr(r3) - Abs2(Vec<3> (c1)) + Abs2(Vec<3> (c3)) ); + + + for (int j = 0; j < 3; j++) + { + mat(0,j) = a1(j); + mat(1,j) = a2(j); + } + + rhs(0) = b1; + rhs(1) = b2; + + + CalcInverse (mat, inv); + sol = inv * rhs; + t = Cross (mat.Row(0), mat.Row(1)); + + if (t.Length() > 1e-8) + { + Point<3> p (sol); + // quadratic on p + s t = 0 + double quad_a; + Vec<3> quad_b; + Mat<3> quad_c; + + quad_a = sphere1 -> CalcFunctionValue(p); + sphere1 -> CalcGradient (p, quad_b); + sphere1 -> CalcHesse (p, quad_c); + + double a, b, c; + a = quad_a; + b = quad_b * t; + c = 0.5 * t * (quad_c * t); + + // a + s b + s^2 c = 0; + double disc = b*b-4*a*c; + if (disc > 1e-10 * fabs (b)) + { + disc = sqrt (disc); + double s1 = (-b-disc) / (2*c); + double s2 = (-b+disc) / (2*c); + + pts.Append (p + s1 * t); + pts.Append (p + s2 * t); + } + } + } + + + + + + + + + + + void SpecialPointCalculation :: + ComputeExtremalPoints (const Plane * plane, + const QuadraticSurface * quadric, + Array > & pts) + { + // 3 equations: + // surf1 = 0 <===> plane_a + plane_b x = 0; + // surf2 = 0 <===> quad_a + quad_b x + x^T quad_c x = 0 + // (grad 1 x grad 2)(i) = 0 <====> (grad 1 x e_i) . grad_2 = 0 + + pts.SetSize (0); + + Point<3> p0(0,0,0); + double plane_a, quad_a; + Vec<3> plane_b, quad_b, ei; + Mat<3> quad_c; + + plane_a = plane -> CalcFunctionValue(p0); + plane -> CalcGradient (p0, plane_b); + + quad_a = quadric -> CalcFunctionValue(p0); + quadric -> CalcGradient (p0, quad_b); + quadric -> CalcHesse (p0, quad_c); + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + quad_c(i,j) *= 0.5; + + for (int dir = 0; dir <= 2; dir++) + { + ei = 0.0; ei(dir) = 1; + Vec<3> v1 = Cross (plane_b, ei); + + // grad_2 . v1 ... linear: + double g2v1_c = v1 * quad_b; + Vec<3> g2v1_l = 2.0 * (quad_c * v1); + + // find line of two linear equations: + + Vec<2> rhs; + Vec<3> sol; + Mat<2,3> mat; + + for (int j = 0; j < 3; j++) + { + mat(0,j) = plane_b(j); + mat(1,j) = g2v1_l(j); + } + rhs(0) = -plane_a; + rhs(1) = -g2v1_c; + + Vec<3> t = Cross (plane_b, g2v1_l); + if (Abs2(t) > 0) + { + mat.Solve (rhs, sol); + + // solve quadratic equation along line sol + alpha t .... + double a = quad_a + quad_b * sol + sol * (quad_c * sol); + double b = quad_b * t + 2 * (sol * (quad_c * t)); + double c = t * (quad_c * t); + + // solve a + b alpha + c alpha^2: + + if (fabs (c) > 1e-32) + { + double disc = sqr (0.5*b/c) - a/c; + if (disc > 0) + { + disc = sqrt (disc); + double alpha1 = -0.5*b/c + disc; + double alpha2 = -0.5*b/c - disc; + + pts.Append (Point<3> (sol+alpha1*t)); + pts.Append (Point<3> (sol+alpha2*t)); + /* + cout << "sol1 = " << sol + alpha1 * t + << ", sol2 = " << sol + alpha2 * t << endl; + */ + } + } + } + } + } + + + + + + + + void SpecialPointCalculation :: + ComputeExtremalPoints (const Sphere * sphere1, + const Sphere * sphere2, + Array > & pts) + { + // 3 equations: + // surf1 = 0 <===> |x-c1|^2 - r1^2 = 0; + // surf2 = 0 <===> |x-c2|^2 - r2^2 = 0; + // (grad 1 x grad 2)(i) = 0 <====> (x-p1) x (p1-p2) . e_i = 0; + + pts.SetSize (0); + + Point<3> c1 = sphere1 -> Center(); + Point<3> c2 = sphere2 -> Center(); + double r1 = sphere1 -> Radius(); + double r2 = sphere2 -> Radius(); + + /* + *testout << "\n\ncompute extremalpoint, sphere-sphere" << endl; + *testout << "c1 = " << c1 << ", r1 = " << r1 << endl; + *testout << "c2 = " << c2 << ", r2 = " << r2 << endl; + *testout << "dist = " << Abs (c2-c1) << ", r1+r2 = " << r1+r2 << endl; + */ + + Vec<3> v12 = c2 - c1; + + Vec<3> a1, a2; + double b1, b2; + + // eqn: ai . x = bi + + a1 = v12; + b1 = 0.5 * (sqr(r1) - sqr(r2) - Abs2(Vec<3> (c1)) + Abs2(Vec<3> (c2)) ); + + int dir = 0; + for (int j = 1; j < 3; j++) + if (fabs (v12(j)) > v12(dir)) + dir = j; + + // *testout << "dir = " << dir << endl; + + Vec<3> ei = 0.0; + ei(dir) = 1; + a2 = Cross (v12, ei); + b2 = Vec<3>(c1) * a2; + + + Point<3> p0 (0,0,0); + double quad_a; + Vec<3> quad_b; + Mat<3> quad_c; + + quad_a = sphere1 -> CalcFunctionValue(p0); + sphere1 -> CalcGradient (p0, quad_b); + sphere1 -> CalcHesse (p0, quad_c); + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + quad_c(i,j) *= 0.5; + + + // find line of two linear equations: + + Vec<2> rhs; + Vec<3> sol; + Mat<2,3> mat; + + for (int j = 0; j < 3; j++) + { + mat(0,j) = a1(j); + mat(1,j) = a2(j); + } + rhs(0) = b1; + rhs(1) = b2; + + + // *testout << "mat = " << endl << mat << endl; + // *testout << "rhs = " << endl << rhs << endl; + + Vec<3> t = Cross (a1, a2); + if (Abs2(t) > 0) + { + mat.Solve (rhs, sol); + + /* + *testout << "sol = " << endl << sol << endl; + + *testout << "a * sol = " << mat * sol << endl; + + *testout << "c1-sol = " << Abs (Vec<3>(c1)-sol) << endl; + *testout << "c2-sol = " << Abs (Vec<3>(c2)-sol) << endl; + */ + + // solve quadratic equation along line sol + alpha t .... + double a = quad_a + quad_b * sol + sol * (quad_c * sol); + double b = quad_b * t + 2 * (sol * (quad_c * t)); + double c = t * (quad_c * t); + + // solve a + b alpha + c alpha^2: + + if (fabs (c) > 1e-32) + { + double disc = sqr (0.5*b/c) - a/c; + if (disc > 0) + { + disc = sqrt (disc); + double alpha1 = -0.5*b/c + disc; + double alpha2 = -0.5*b/c - disc; + + pts.Append (Point<3> (sol+alpha1*t)); + pts.Append (Point<3> (sol+alpha2*t)); + + // *testout << "pts = " << endl << pts << endl; + + /* + cout << "sol1 = " << sol + alpha1 * t + << ", sol2 = " << sol + alpha2 * t << endl; + */ + } + } + } + } + + + + + + + + + + + /* + bool SpecialPointCalculation :: ExtremalPointPossible (const Surface * f1, + const Surface * f2, + int dir, + const BoxSphere<3> & box) + { + double hn1, hn2, gn1, gn2; + Point<3> p; + Vec<3> g1, g2, v; + double f3; + double r = box.Diam()/2; + + p = box.Center(); + + f1 -> CalcGradient (p, g1); + f2 -> CalcGradient (p, g2); + + gn1 = g1.Length(); + gn2 = g2.Length(); + + hn1 = f1 -> HesseNorm (); + hn2 = f2 -> HesseNorm (); + + v = Cross (g1, g2); + f3 = fabs (v(dir-1)); + + // (*testout) << "f3 = " << f3 << " r = " << r + // << "normbound = " + // << (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1)) << endl; + + return (f3 <= 3 * r * (hn1 * (gn2 + r * hn2) + hn2 * (gn1 + r * hn1))); + } + + + + bool SpecialPointCalculation :: + ExtremalPointNewtonConvergence (const Surface * f1, const Surface * f2, + int dir, + const BoxSphere<3> & box) + { + return box.Diam() < 1e-8; + } + + + bool SpecialPointCalculation :: + ExtremalPointDegenerated (const Surface * f1, const Surface * f2, + int dir, const BoxSphere<3> & box) + { + double gn1, gn2; + Point<3> p; + Vec<3> g1, g2, v; + double maxderiv; + double minv; + Vec<3> curv, t; + Vec<2> rs, x; + Mat<3> h1, h2; + Mat<2> a, inv; + double leftside; + + if (box.Diam() > relydegtest) return 0; + + p = box.Center(); + + f1 -> CalcGradient (p, g1); + f2 -> CalcGradient (p, g2); + gn1 = g1.Length(); + gn2 = g2.Length(); + + v = Cross (g1, g2); + if (Abs (v) < epeps1 * gn1 * gn2) return 1; // irregular edge + + f1 -> CalcHesse (p, h1); + f2 -> CalcHesse (p, h2); + + // hn1 = f1 -> HesseNorm (); + // hn2 = f2 -> HesseNorm (); + + t = v; + a(0, 0) = g1 * g1; + a(0, 1) = + a(1, 0) = g1 * g2; + a(1, 1) = g2 * g2; + + rs(0) = g1(dir-1); + rs(1) = g2(dir-1); + + a.Solve (rs, x); + + // (*testout) << "g1 = " << g1 << " g2 = " << g2 << endl; + // (*testout) << "lam = " << x << endl; + // (*testout) << "h2 = " << h2 << endl; + + leftside = fabs (x(0) * ( t * (h1 * t)) + + x(1) * ( t * (h2 * t))); + + // (*testout) << "leftside = " << leftside << endl; + + if (leftside < epeps2 * Abs2 (v)) return 1; + + return 0; + } + */ + + + bool SpecialPointCalculation :: AddPoint (const Point<3> & p, int layer) + { + for (int i = 0; i < points->Size(); i++) + if (Dist2 ( (*points)[i], p) < epspointdist2 && + (*points)[i].GetLayer() == layer) + return false; + + points->Append (MeshPoint(p, layer)); + PrintMessageCR (3, "Found points ", points->Size()); + return true; + } + + + + + + + + void SpecialPointCalculation :: + AnalyzeSpecialPoints (const CSGeometry & ageometry, + Array & apoints, + Array & specpoints) + { + static int timer = NgProfiler::CreateTimer ("CSG: analyze special points"); + NgProfiler::RegionTimer reg (timer); + + + Array surfind, rep_surfind, surfind2, rep_surfind2, surfind3; + + Array > normalvecs; + Vec<3> nsurf = 0.0; + + Array specpoint2point; + specpoints.SetSize (0); + + geometry = &ageometry; + + double geomsize = ageometry.MaxSize(); + + (*testout) << "AnalyzeSpecialPoints\n"; + + if (!apoints.Size()) return; + + + { + /* + sort points in the (arbitrary) direction dir + important for periodic boundaries: + corner points on the left and the right boundary come in the same ordering + */ + Vec<3> dir(1.2, 1.7, 0.9); + + Array coord(apoints.Size()); + for (int i = 0; i < apoints.Size(); i++) + coord[i] = dir * Vec<3> (apoints[i]); + + QuickSort (coord, apoints); + } + + + + + + Box<3> bbox (apoints[0], apoints[0]); + for (int i = 1; i < apoints.Size(); i++) + bbox.Add (apoints[i]); + bbox.Increase (0.1 * bbox.Diam()); + + (*testout) << "points = " << apoints << endl; + + Point3dTree searchtree (bbox.PMin(), bbox.PMax()); + Array locsearch; + + for (int si = 0; si < ageometry.GetNTopLevelObjects(); si++) + { + const TopLevelObject * tlo = ageometry.GetTopLevelObject(si); + + const Solid * sol = tlo->GetSolid(); + const Surface * surf = tlo->GetSurface(); + + + for (int i = 0; i < apoints.Size(); i++) + { + Point<3> p = apoints[i]; + +#ifdef DEVELOP + *testout << " test point " << p << endl; +#endif + + if (tlo->GetLayer() != apoints[i].GetLayer()) + continue; + + + Solid * locsol; + sol -> TangentialSolid (p, locsol, surfind, ideps*geomsize); + + + rep_surfind.SetSize (surfind.Size()); + int num_indep_surfs = 0; + + for (int j = 0; j < surfind.Size(); j++) + { + rep_surfind[j] = ageometry.GetSurfaceClassRepresentant (surfind[j]); + bool found = false; + for (int k = 0; !found && k < j; k++) + found = (rep_surfind[k] == rep_surfind[j]); + if(!found) + num_indep_surfs++; + } + + +#ifdef DEVELOP + *testout << "surfs = " << surfind << endl; + *testout << "rep_surfs = " << rep_surfind << endl; +#endif + + if (!locsol) continue; + + + // get all surface indices, + if (surf) + { + // locsol -> GetSurfaceIndices (surfind); + bool hassurf = 0; + for (int m = 0; m < surfind.Size(); m++) + if (ageometry.GetSurface(surfind[m]) == surf) + hassurf = 1; + + if (!hassurf) + continue; + + nsurf = surf->GetNormalVector (p); + } + + /* + // get independent surfaces of tangential solid + BoxSphere<3> box(p,p); + box.Increase (1e-6*geomsize); + box.CalcDiamCenter(); + ageometry.GetIndependentSurfaceIndices (locsol, box, surfind); + */ + + // ageometry.GetIndependentSurfaceIndices (surfind); + + + normalvecs.SetSize(surfind.Size()); + for (int j = 0; j < surfind.Size(); j++) + normalvecs[j] = + ageometry.GetSurface(surfind[j]) -> GetNormalVector(apoints[i]); + + + for (int j = 0; j < normalvecs.Size(); j++) + for (int k = 0; k < normalvecs.Size(); k++) + { + if (rep_surfind[j] == rep_surfind[k]) continue; + //if (j == k) continue; + + Vec<3> t; + + if (dynamic_cast (ageometry.surf2prim[surfind[j]]) && + ageometry.surf2prim[surfind[j]] == + ageometry.surf2prim[surfind[k]]) + { + t = ageometry.surf2prim[surfind[j]] -> + SpecialPointTangentialVector (p, surfind[j], surfind[k]); + } + else + { + t = Cross (normalvecs[j], normalvecs[k]); + } + + + if (Abs2 (t) < 1e-8) + continue; + +#ifdef DEVELOP + *testout << " tangential vector " << t << endl; +#endif + + t.Normalize(); + + + // try tangential direction t + if (surf && fabs (nsurf * t) > 1e-6) + continue; + + +#ifdef DEVELOP + *testout << " j " << j << " k " << k << endl; +#endif + + if (!surf) + { + // compute second order approximation + // c(s) = p + s t + s*s/2 t2 + Vec<3> gradj, gradk; + Mat<3> hessej, hessek; + ageometry.GetSurface (surfind[j]) -> CalcGradient (p, gradj); + ageometry.GetSurface (surfind[k]) -> CalcGradient (p, gradk); + ageometry.GetSurface (surfind[j]) -> CalcHesse (p, hessej); + ageometry.GetSurface (surfind[k]) -> CalcHesse (p, hessek); + + Vec<2> rhs; + Vec<3> t2; + Mat<2,3> mat; + Mat<3,2> inv; + for (int l = 0; l < 3; l++) + { + mat(0,l) = gradj(l); + mat(1,l) = gradk(l); + } + rhs(0) = -t * (hessej * t); + rhs(1) = -t * (hessek * t); + + CalcInverse (mat, inv); + t2 = inv * rhs; + + + /* + ageometry.GetIndependentSurfaceIndices + (locsol, p, t, surfind2); + */ + + Solid * locsol2; + locsol -> TangentialSolid3 (p, t, t2, locsol2, surfind2, ideps*geomsize); + if (!locsol2) continue; + + // locsol2 -> GetTangentialSurfaceIndices3 (p, t, t2, surfind2, 1e-9*geomsize); + + rep_surfind2.SetSize (surfind2.Size()); + for (int j2 = 0; j2 < surfind2.Size(); j2++) + rep_surfind2[j2] = ageometry.GetSurfaceClassRepresentant (surfind2[j2]); + +#ifdef DEVELOP + (*testout) << "surfind2 = " << endl << surfind2 << endl; +#endif + Array surfind2_aux(surfind2); + ageometry.GetIndependentSurfaceIndices (surfind2_aux); +#ifdef DEVELOP + (*testout) << "surfind2,rep = " << endl << surfind2_aux << endl; +#endif + + bool ok = true; + + // intersecting surfaces must be in second order tangential solid + /* + if (!surfind2.Contains(surfind[j]) || + !surfind2.Contains(surfind[k])) + ok = false; + */ + if (!surfind2_aux.Contains(rep_surfind[j]) || + !surfind2_aux.Contains(rep_surfind[k])) + ok = false; + +#ifdef DEVELOP + (*testout) << "ok,1 = " << ok << endl; +#endif + + // there must be 2 different tangential faces to the edge + int cnt_tang_faces = 0; + for (int l = 0; l < surfind2.Size(); l++) + { + Vec<3> nv = + ageometry.GetSurface(surfind2[l]) -> GetNormalVector(p); + + + Vec<3> m1 = Cross (t, nv); + Vec<3> m2 = -m1; + bool isface1 = 0, isface2 = 0; + + Solid * locsol3; + + // locsol2 -> TangentialSolid2 (p, m1, locsol3, surfind3, 1e-9*geomsize); + locsol -> TangentialEdgeSolid (p, t, t2, m1, locsol3, surfind3, ideps*geomsize); + + //ageometry.GetIndependentSurfaceIndices (surfind3); + + if (surfind3.Contains(surfind2[l])) + isface1 = 1; + delete locsol3; + + // locsol2 -> TangentialSolid2 (p, m2, locsol3, surfind3, 1e-9*geomsize); + locsol -> TangentialEdgeSolid (p, t, t2, m2, locsol3, surfind3, ideps*geomsize); + + // ageometry.GetIndependentSurfaceIndices (surfind3); + + + if (surfind3.Contains(surfind2[l])) + isface2 = 1; + delete locsol3; + + if (isface1 != isface2) + cnt_tang_faces++; + } + +#ifdef DEVELOP + (*testout) << "cnt_tang = " << cnt_tang_faces << endl; +#endif + + if (cnt_tang_faces < 1) + ok = false; + + delete locsol2; + if (!ok) continue; + } + + + // edge must be on tangential surface + bool isedge = + locsol->VectorIn (p, t) && + !locsol->VectorStrictIn (p, t); + +#ifdef DEVELOP + (*testout) << "isedge,1 = " << isedge << "\n"; +#endif + + // there must exist at least two different faces on edge + if (isedge) + { + // *testout << "succ 1" << endl; + int cnts = 0; + for (int m = 0; m < surfind.Size(); m++) + { + if (fabs (normalvecs[m] * t) > 1e-6) + continue; + + Vec<3> s = Cross (normalvecs[m], t); + Vec<3> t2a = t + 0.01 *s; + Vec<3> t2b = t - 0.01 *s; + + bool isface = + (locsol->VectorIn (p, t2a, 1e-6*geomsize) && + !locsol->VectorStrictIn (p, t2a, 1e-6*geomsize)) + || + (locsol->VectorIn (p, t2b, 1e-6*geomsize) && + !locsol->VectorStrictIn (p, t2b, 1e-6*geomsize)); + + /* + bool isface = + (locsol->VectorIn (p, t2a) && + !locsol->VectorStrictIn (p, t2a)) + || + (locsol->VectorIn (p, t2b) && + !locsol->VectorStrictIn (p, t2b)); + */ + + if (isface) + { + cnts++; + } + } + if (cnts < 2) isedge = 0; + } + + if (isedge) + { +#ifdef DEVELOP + *testout << "success" << endl; +#endif + int spi = -1; + + const double searchradius = 1e-4*geomsize;//1e-5*geomsize; + searchtree.GetIntersecting (apoints[i]-Vec3d(searchradius,searchradius,searchradius), + apoints[i]+Vec3d(searchradius,searchradius,searchradius), + locsearch); + + for (int m = 0; m < locsearch.Size(); m++) + { + if (Dist2 (specpoints[locsearch[m]].p, apoints[i]) < 1e-10*geomsize + && Abs2(specpoints[locsearch[m]].v - t) < 1e-8) + { + spi = locsearch[m]; + break; + } + } + + + if (spi == -1) + { + spi = specpoints.Append (SpecialPoint()) - 1; + specpoint2point.Append (i); + specpoints.Last().unconditional = 0; + searchtree.Insert (apoints[i], spi); + } + + if(!specpoints[spi].unconditional) + { + specpoints[spi].p = apoints[i]; + specpoints[spi].v = t; + //if (surfind.Size() >= 3) + if (num_indep_surfs >= 3) + specpoints[spi].unconditional = 1; + specpoints[spi].s1 = rep_surfind[j]; + specpoints[spi].s2 = rep_surfind[k]; + specpoints[spi].s1_orig = surfind[j]; + specpoints[spi].s2_orig = surfind[k]; + specpoints[spi].layer = apoints[i].GetLayer(); + for (int up = 0; up < geometry->GetNUserPoints(); up++) + if (Dist (geometry->GetUserPoint(up), apoints[i]) < 1e-8*geomsize) + specpoints[spi].unconditional = 1; + for (int ip = 0; ip < geometry->GetNIdentPoints(); ip++) + if (Dist (geometry->GetIdentPoint(ip), apoints[i]) < 1e-8*geomsize) + specpoints[spi].unconditional = 1; + } + } + + } + + delete locsol; + } + } + + /* + BitArray testuncond (specpoints.Size()); + testuncond.Clear(); + for(int i = 0; i same; + same.Append(i); + + for(int j = i+1; j p; + /// tangential to edge + Vec<3> v; + /// + int layer; + /// point must be used in mesh + bool unconditional; + + /// surfaces defining edge + int s1, s2; + /// if s1 and s2 are only representatives, then these are the original indices + int s1_orig, s2_orig; + int nr; + /// + SpecialPoint () : p(0,0,0), v(0,0,0), layer(0), unconditional(0), s1(0), s2(0), s1_orig(0), s2_orig(0) + { ; } + + /// + SpecialPoint (const SpecialPoint & sp2); + + /// + SpecialPoint & operator= (const SpecialPoint & sp2); + + /// + void Print (ostream & str) const; + + + int GetLayer() const { return layer; } + + /// + bool HasSurfaces (int as1, int as2) const + { + return ( (s1 == as1 && s2 == as2) || (s1 == as2 && s2 == as1) ); + } + }; + + inline ostream & operator<< (ostream & ost, const SpecialPoint & sp) + { + sp.Print (ost); + return ost; + } + + + + + /// + class SpecialPointCalculation + { + private: + /// + const CSGeometry * geometry; + /// + Array * points; + /// + Array boxesinlevel; + + /// + double size; + /// + double relydegtest; // maximal dimension of bisection intervall for + /// test of degeneration parameters + double cpeps1, epeps1, epeps2, epspointdist2; + + double ideps; + + public: + + /// + SpecialPointCalculation (); + + /// + void SetIdEps(const double epsin) {ideps = epsin;} + + /// + void CalcSpecialPoints (const CSGeometry & ageometry, + Array & points); + /// + void AnalyzeSpecialPoints (const CSGeometry & geometry, + Array & points, + Array & specpoints); + + protected: + /// + void CalcSpecialPointsRec (const Solid * sol, int layer, + const BoxSphere<3> & box, + int level, + bool calccp, bool calcep); + + + /// + bool CrossPointNewtonConvergence (const Surface * f1, const Surface * f2, + const Surface * f3, const BoxSphere<3> & box); + /// + bool CrossPointDegenerated (const Surface * f1, const Surface * f2, + const Surface * f3, const BoxSphere<3> & box) const; + /// + void CrossPointNewton (const Surface * f1, const Surface * f2, + const Surface * f3, Point<3> & p); + + bool EdgeNewtonConvergence (const Surface * f1, const Surface * f2, + const Point<3> & p); + /// + bool EdgeDegenerated (const Surface * f1, const Surface * f2, + const BoxSphere<3> & box) const; + /// + void EdgeNewton (const Surface * f1, const Surface * f2, + Point<3> & p); + /// + bool IsEdgeExtremalPoint (const Surface * f1, const Surface * f2, + const Point<3> & p, Point<3> & pp, double rad); + + + + /* + /// + bool ExtremalPointPossible (const Surface * f1, const Surface * f2, + int dir, const BoxSphere<3> & box); + /// + bool ExtremalPointDegenerated (const Surface * f1, const Surface * f2, + int dir, const BoxSphere<3> & box); + /// + bool ExtremalPointNewtonConvergence (const Surface * f1, const Surface * f2, + int dir, const BoxSphere<3> & box); + */ + /// + void ExtremalPointNewton (const Surface * f1, const Surface * f2, + int dir, Point<3> & p); + + + /// + bool AddPoint (const Point<3> & p, int layer); + + void ComputeExtremalPoints (const Plane * plane, + const QuadraticSurface * quadric, + Array > & pts); + + void ComputeExtremalPoints (const Sphere * sphere1, + const Sphere * sphere2, + Array > & pts); + + + void ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const Plane * plane3, + Array > & pts); + + void ComputeCrossPoints (const Plane * plane1, + const Plane * plane2, + const QuadraticSurface * quadratic, + Array > & pts); + + void ComputeCrossPoints (const Sphere * sphere1, + const Sphere * sphere2, + const Sphere * sphere3, + Array > & pts); + }; + +} + +#endif + + diff --git a/libsrc/csg/spline3d.cpp b/libsrc/csg/spline3d.cpp new file mode 100644 index 00000000..b89e7f70 --- /dev/null +++ b/libsrc/csg/spline3d.cpp @@ -0,0 +1,355 @@ +#include + +#include + +#include +#include + + +namespace netgen +{ +splinesegment3d :: splinesegment3d (const Point<3> & ap1, const Point<3> & ap2, + const Point<3> & ap3) +{ + p1 = ap1; + p2 = ap2; + p3 = ap3; +} + + +/* + todo + Tip von Joerg Stiller: + setzt Du in + void splinesegment3d :: Evaluate + Zeilen 54 und 56 + b2 = 2 * t * (1-t); + b2 /= sqrt(2); + Das heisst, Du wichtest das zweite Bersteinpolynom mit + w2 = 1 / sqrt(2); + Das ist aber nur fuer 45-Grad-Segmente korrekt. Fuer den + allgemeinen Fall funktioniert + w2 = ( e(p3 - p1), e(p2 - p1) ); // also cos(winkel(p3-p1, p2-p1)) + bzw. schoen symmetrisch + w2 = ( e(p3 - p1), e(p2 - p1) )/2 + ( e(p1 - p3), e(p2 - p3) )/2; + Das ist natuerlich kein C++ Code sondern symbolisch, wobei + e(p3 - p1) ist der von p1 zu p3 zeigende Einheitsvektor und + (a, b) steht fuer das Skalarprodukt zweier Vektoren etc. + + Eine vergleichbare Information steht auch irgendwo im Hoscheck & Lasser. + Ich habe das Buch aber eben nicht zur Hand. +*/ + +void splinesegment3d :: Evaluate (double t, Point<3> & p) const +{ + double x, y, z, w; + double b1, b2, b3; + + b1 = (1-t)*(1-t); + b2 = 2 * t * (1-t); + b3 = t * t; + + b2 /= sqrt(double(2)); + + x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3; + y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3; + z = p1(2) * b1 + p2(2) * b2 + p3(2) * b3; + w = b1 + b2 + b3; + + p(0) = x / w; + p(1) = y / w; + p(2) = z / w; +} + +void splinesegment3d :: EvaluateTangent (double t, Vec<3> & tang) const +{ + double x, y, z, w, xprime, yprime, zprime, wprime; + double b1, b2, b3, b1prime, b2prime, b3prime; + + b1 = (1-t)*(1-t); + b2 = 2 * t * (1-t); + b3 = t * t; + b2 /= sqrt(double(2)); + + b1prime = 2 * t - 2; + b2prime = - 4 * t + 2; + b3prime = 2 * t; + b2prime /= sqrt(double(2)); + + + x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3; + y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3; + z = p1(2) * b1 + p2(2) * b2 + p3(2) * b3; + w = b1 + b2 + b3; + + xprime = p1(0) * b1prime + p2(0) * b2prime + p3(0) * b3prime; + yprime = p1(1) * b1prime + p2(1) * b2prime + p3(1) * b3prime; + zprime = p1(2) * b1prime + p2(2) * b2prime + p3(2) * b3prime; + wprime = b1prime + b2prime + b3prime; + + tang(0) = (w * xprime - x * wprime) / (w * w); + tang(1) = (w * yprime - y * wprime) / (w * w); + tang(2) = (w * zprime - z * wprime) / (w * w); +} + + +void spline3d :: AddSegment (const Point<3> & ap1, const Point<3> & ap2, + const Point<3> & ap3) +{ + segments.Append (new splinesegment3d (ap1, ap2, ap3)); +} + +void spline3d :: Evaluate (double t, Point<3> & p) const +{ + int nr; + double loct; + static int cnt = 0; + + cnt++; + if (cnt % 10000 == 0) (*mycout) << "Evaluate calls: " << cnt << endl; + + while (t < 0) t += GetNumSegments(); + while (t >= GetNumSegments()) t -= GetNumSegments(); + nr = 1 + int (t); + loct = t - nr + 1; + segments.Get(nr)->Evaluate (loct, p); +} + +void spline3d :: EvaluateTangent (double t, Vec<3> & tang) const +{ + int nr; + double loct; + + while (t < 0) t += GetNumSegments(); + while (t >= GetNumSegments()) t -= GetNumSegments(); + nr = 1 + int (t); + loct = t - nr + 1; + segments.Get(nr)->EvaluateTangent (loct, tang); +} + + +double spline3d :: ProjectToSpline (Point<3> & p) const +{ + double t, tl, tu, dt, dist, mindist, optt(0); + Point<3> hp; + Vec<3> tanx, px; + + dt = 0.01; + mindist = 0; + for (t = 0; t <= GetNumSegments() + dt/2; t += dt) + { + Evaluate (t, hp); + dist = Dist (hp, p); + if (t == 0 || dist < mindist) + { + optt = t; + mindist = dist; + } + } + + + tu = optt + dt; + tl = optt - dt; + while (tu - tl > 1e-2) + { + optt = 0.5 * (tu + tl); + Evaluate (optt, hp); + EvaluateTangent (optt, tanx); + if (tanx * (hp - p) > 0) + tu = optt; + else + tl = optt; + } + + optt = 0.5 * (tu + tl); + + optt = ProjectToSpline (p, optt); + return optt; +} + + +double spline3d :: ProjectToSpline (Point<3> & p, double optt) const +{ + double tl, tu, dt, val, dval, valu, vall; + Point<3> hp; + Vec<3> tanx, px; + int its = 0; + int cnt = 1000; + do + { + dt = 1e-8; + tl = optt - dt; + tu = optt + dt; + + EvaluateTangent (optt, tanx); + Evaluate (optt, hp); + px = hp - p; + val = px * tanx; + + EvaluateTangent (tl, tanx); + Evaluate (tl, hp); + px = hp - p; + vall = px * tanx; + + EvaluateTangent (tu, tanx); + Evaluate (tu, hp); + px = hp - p; + valu = px * tanx; + + dval = (valu - vall) / (2 * dt); + + if (its % 100 == 99) + (*testout) << "optt = " << optt + << " val = " << val + << " dval = " << dval << endl; + optt -= val / dval; + its++; + if (fabs(val) < 1e-8 && cnt > 5) cnt = 5; + cnt--; + } + while (cnt > 0); + + Evaluate (optt, p); + return optt; +} + + +splinetube :: splinetube (const spline3d & amiddlecurve, double ar) + : Surface(), middlecurve (amiddlecurve), r(ar) +{ + (*mycout) << "Splinetube Allocated, r = " << r << endl; + +} + +void splinetube :: DefineTangentialPlane (const Point<3> & ap1, + const Point<3> & ap2) +{ + double t; + double phi, z; + + p1 = ap1; + p2 = ap2; + cp = p1; + t = middlecurve.ProjectToSpline (cp); + ex = p1 - cp; + middlecurve.EvaluateTangent (t, ez); + ex.Normalize(); + ez.Normalize(); + ey = Cross (ez, ex); + + phi = r * atan2 (ey * (p2-cp), ex * (p2-cp)); + z = ez * (p2 - cp); + e2x(0) = phi; + e2x(1) = z; + e2x.Normalize(); + e2y(1) = e2x(0); + e2y(0) = -e2x(1); + + // (*testout) << "Defineplane: " << endl + // << "p1 = " << p1 << " p2 = " << p2 << endl + // << "pc = " << cp << endl + // << "ex = " << ex << " ey = " << ey << " ez = " << ez << endl + // << "phi = " << phi << " z = " << z << endl + // << "e2x = " << e2x << " e2y = " << e2y << endl; +} + +void splinetube :: ToPlane (const Point<3> & p3d, Point<2> & pplain, double h, + int & zone) const +{ + Vec<2> v; + v(0) = r * atan2 (ey * (p3d-cp), ex * (p3d-cp)); + v(1) = ez * (p3d - cp); + zone = 0; + if (v(0) > r * 2) zone = 1; + if (v(0) < r * 2) zone = 2; + + pplain(0) = (v * e2x) / h; + pplain(1) = (v * e2y) / h; +} + +void splinetube :: FromPlane (const Point<2> & pplain, Point<3> & p3d, double h) const +{ + Vec<2> v; + + v(0) = pplain(0) * h * e2x(0) + pplain(1) * h * e2y(0); + v(1) = pplain(0) * h * e2x(1) + pplain(1) * h * e2y(1); + + p3d = p1 + v(0) * ey + v(1) * ez; + + Project (p3d); +} + +void splinetube :: Project (Point<3> & p3d) const +{ + Point<3> hp; + + hp = p3d; + middlecurve.ProjectToSpline (hp); + + p3d = hp + (r / Dist(p3d, hp)) * (p3d - hp); +} + + + +double splinetube :: CalcFunctionValue (const Point<3> & point) const +{ + Point<3> hcp; + double rad; + + hcp = point; + middlecurve.ProjectToSpline (hcp); + rad = Dist (hcp, point); + return 0.5 * (rad * rad / r - r); +} + +void splinetube :: CalcGradient (const Point<3> & point, Vec<3> & grad) const +{ + Point<3> hcp; + + hcp = point; + middlecurve.ProjectToSpline (hcp); + + grad = point - hcp; + grad /= r; +} + + + + +Point<3> splinetube :: GetSurfacePoint () const +{ + Point<3> p; + Vec<3> t, n; + + middlecurve.Evaluate (0, p); + middlecurve.EvaluateTangent (0, t); + n = t.GetNormal (); + n *= r; + (*mycout) << "p = " << p << " t = " << t << " n = " << n << endl; + return p + n; +} + +void splinetube :: Print (ostream & str) const +{ + int i; + str << "SplineTube, " + << middlecurve.GetNumSegments () << " segments, r = " << r << endl; + for (i = 1; i <= middlecurve.GetNumSegments(); i++) + str << middlecurve.P1(i) << " - " + << middlecurve.P2(i) << " - " + << middlecurve.P3(i) << endl; +} + + +int splinetube :: BoxInSolid (const BoxSphere<3> & box) const + // 0 .. no, 1 .. yes, 2 .. maybe +{ + Point<3> pc = box.Center(); + middlecurve.ProjectToSpline (pc); + double d = Dist (pc, box.Center()); + + if (d < r - box.Diam()/2) return 1; + if (d > r + box.Diam()/2) return 0; + return 2; +} +} diff --git a/libsrc/csg/spline3d.hpp b/libsrc/csg/spline3d.hpp new file mode 100644 index 00000000..db3a40c5 --- /dev/null +++ b/libsrc/csg/spline3d.hpp @@ -0,0 +1,99 @@ +namespace netgen +{ + + /// + class splinesegment3d + { + /// + Point<3> p1, p2, p3; + + public: + /// + splinesegment3d (const Point<3> & ap1, const Point<3> & ap2, + const Point<3> & ap3); + /// + void Evaluate (double t, Point<3> & p) const; + /// + void EvaluateTangent (double t, Vec<3> & tang) const; + /// + const Point<3> & P1() const { return p1; } + /// + const Point<3> & P2() const { return p2; } + /// + const Point<3> & P3() const { return p3; } + }; + + /// + class spline3d + { + /// + Array segments; + + public: + /// + spline3d () { }; + /// + void AddSegment (const Point<3> & ap1, const Point<3> & ap2, const Point<3> & ap3); + /// + int GetNumSegments () const { return segments.Size(); } + /// + double ProjectToSpline (Point<3> & p) const; + /// + double ProjectToSpline (Point<3> & p, double t) const; + /// + void Evaluate (double t, Point<3> & p) const; + /// + void EvaluateTangent (double t, Vec<3> & tang) const; + /// + const Point<3> & P1(int i) const { return segments.Get(i)->P1(); } + /// + const Point<3> & P2(int i) const { return segments.Get(i)->P2(); } + /// + const Point<3> & P3(int i) const { return segments.Get(i)->P3(); } + }; + + /// + class splinetube : public Surface + { + /// + const spline3d & middlecurve; + /// + double r; + /// Vec<3> ex, ey, ez; + Vec<2> e2x, e2y; + /// + Point<3> cp; + + public: + /// + splinetube (const spline3d & amiddlecurve, double ar); + + /// + virtual void DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2); + /// + virtual void ToPlane (const Point<3> & p, Point<2> & pplain, double h, int & zone) const; + /// + virtual void FromPlane (const Point<2> & pplain, Point<3> & p, double h) const; + /// + virtual void Project (Point<3> & p) const; + + // virtual int RootInBox (const box3d & box) const { return 0; } + /// 0 .. no, 1 .. yes, 2 .. maybe + + virtual int BoxInSolid (const BoxSphere<3> & box) const; + /// 0 .. no, 1 .. yes, 2 .. maybe + + virtual double CalcFunctionValue (const Point<3> & point) const; + /// + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const; + /// + virtual double HesseNorm () const { return 0.5 / r; } + /// + virtual Point<3> GetSurfacePoint () const; + /// + virtual void Print (ostream & str) const; + }; + + +} + diff --git a/libsrc/csg/surface.cpp b/libsrc/csg/surface.cpp new file mode 100644 index 00000000..fe0415ec --- /dev/null +++ b/libsrc/csg/surface.cpp @@ -0,0 +1,568 @@ +#include + +#include +#include + +#include +#include + + +namespace netgen +{ +Surface :: Surface () +{ + maxh = 1e10; + name = new char[7]; + strcpy (name, "noname"); + bcprop = -1; + bcname = "default"; +} + +Surface :: ~Surface() +{ + delete [] name; +} + + +void Surface :: SetName (const char * aname) +{ + delete [] name; + name = new char[strlen (aname)+1]; + strcpy (name, aname); +} + + +int Surface :: PointOnSurface (const Point<3> & p, + double eps) const +{ + double val = CalcFunctionValue (p); + return fabs (val) < eps; +} + + +void Surface :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const +{ + double dx = 1e-5; + Point<3> hp1, hp2; + Vec<3> g1, g2; + + for (int i = 0; i < 3; i++) + { + hp1 = point; + hp2 = point; + + hp1(i) += dx; + hp2(i) -= dx; + + CalcGradient (hp1, g1); + CalcGradient (hp2, g2); + + for (int j = 0; j < 3; j++) + hesse(i, j) = (g1(j) - g2(j)) / (2 * dx); + } +} + +/* +void Surface :: GetNormalVector (const Point<3> & p, Vec<3> & n) const +{ + CalcGradient (p, n); + n.Normalize(); +} +*/ +Vec<3> Surface :: GetNormalVector (const Point<3> & p) const +{ + Vec<3> n; + CalcGradient (p, n); + n.Normalize(); + return n; +} + +void Surface :: DefineTangentialPlane (const Point<3> & ap1, + const Point<3> & ap2) +{ + p1 = ap1; + p2 = ap2; + + ez = GetNormalVector (p1); + ex = p2 - p1; + ex -= (ex * ez) * ez; + ex.Normalize(); + ey = Cross (ez, ex); +} + +void Surface :: ToPlane (const Point<3> & p3d, Point<2> & pplane, + double h, int & zone) const +{ + Vec<3> p1p, n; + + n = GetNormalVector (p3d); + if (n * ez < 0) + { + zone = -1; + pplane(0) = 1e8; + pplane(1) = 1e9; + return; + } + + p1p = p3d - p1; + pplane(0) = (p1p * ex) / h; + pplane(1) = (p1p * ey) / h; + zone = 0; +} + +void Surface :: FromPlane (const Point<2> & pplane, + Point<3> & p3d, double h) const +{ + p3d = p1 + + (h * pplane(0)) * ex + + (h * pplane(1)) * ey; + + Project (p3d); +} + +void Surface :: Project (Point<3> & p) const +{ + Vec<3> n; + double val; + + for (int i = 1; i <= 10; i++) + { + val = CalcFunctionValue (p); + if (fabs (val) < 1e-12) return; + + CalcGradient (p, n); + p -= (val / Abs2 (n)) * n; + } +} + +void Surface :: SkewProject (Point<3> & p, const Vec<3> & direction) const +{ + Point<3> startp(p); + double t_old(0),t_new(1); + Vec<3> grad; + for(int i=0; fabs(t_old-t_new) > 1e-20 && i<15; i++) + { + t_old = t_new; + CalcGradient(p,grad); + t_new = t_old - CalcFunctionValue(p)/(grad*direction); + p = startp + t_new*direction; + } +} + + +double Surface :: MaxCurvature () const +{ + return 0.5 * HesseNorm (); +} + +double Surface :: +MaxCurvatureLoc (const Point<3> & /* c */ , double /* rad */) const +{ + return MaxCurvature (); +} + + + +double Surface :: LocH (const Point<3> & p, double x, + double c, double hmax) const + // finds h <= hmax, s.t. h * \kappa_x*h < c +{ + /* + double h, hmin, kappa; + hmin = 0; + + while (hmin < 0.9 * hmax) + { + h = 0.5 * (hmin + hmax); + kappa = 2 * MaxCurvatureLoc (p, x * h); + + if (kappa * h >= c) + hmax = h; + else + hmin = h; + } + return h; + */ + + double hret; + double kappa = MaxCurvatureLoc (p, x*hmax); + + kappa *= c * mparam.curvaturesafety; + + if (hmax * kappa < 1) + hret = hmax; + else + hret = 1 / kappa; + + if (maxh < hret) + hret = maxh; + + return hret; +} + + + + +Primitive :: Primitive () +{ + surfaceids.SetSize (1); + surfaceactive.SetSize (1); + surfaceactive[0] = 1; +} + +Primitive :: ~Primitive() +{ + ; +} + +int Primitive :: GetSurfaceId (int i) const +{ + return surfaceids[i]; +} + +void Primitive :: SetSurfaceId (int i, int id) +{ + surfaceids[i] = id; +} + + + + +void Primitive :: GetPrimitiveData (const char *& classname, + Array & coeffs) const +{ + classname = "undef"; + coeffs.SetSize (0); +} + +void Primitive :: SetPrimitiveData (Array & coeffs) +{ + ; +} + +Primitive * Primitive :: CreatePrimitive (const char * classname) +{ + if (strcmp (classname, "sphere") == 0) + return Sphere::CreateDefault(); + if (strcmp (classname, "plane") == 0) + return Plane::CreateDefault(); + if (strcmp (classname, "cylinder") == 0) + return Cylinder::CreateDefault(); + if (strcmp (classname, "cone") == 0) + return Cone::CreateDefault(); + if (strcmp (classname, "brick") == 0) + return Brick::CreateDefault(); + + + stringstream ost; + ost << "Primitve::CreatePrimitive not implemented for " << classname << endl; + throw NgException (ost.str()); +} + + +Primitive * Primitive :: Copy () const +{ + stringstream ost; + ost << "Primitve::Copy not implemented for " << typeid(*this).name() << endl; + throw NgException (ost.str()); +} + + +void Primitive :: Transform (Transformation<3> & trans) +{ + stringstream ost; + ost << "Primitve::Transform not implemented for " << typeid(*this).name() << endl; + throw NgException (ost.str()); +} + +void Primitive :: GetTangentialSurfaceIndices (const Point<3> & p, + Array & surfind, double eps) const +{ + for (int j = 0; j < GetNSurfaces(); j++) + if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps) + if (!surfind.Contains (GetSurfaceId(j))) + surfind.Append (GetSurfaceId(j)); +} + + +void Primitive :: +GetTangentialVecSurfaceIndices (const Point<3> & p, const Vec<3> & v, + Array & surfind, double eps) const +{ + cout << "get tangvecsurfind not implemented" << endl; + surfind.SetSize (0); +} + +void Primitive :: +GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + Array & surfind, double eps) const +{ + for (int j = 0; j < GetNSurfaces(); j++) + { + if (fabs (GetSurface(j).CalcFunctionValue (p)) < eps) + { + Vec<3> grad; + GetSurface(j).CalcGradient (p, grad); + if (sqr (grad * v1) < 1e-6 * v1.Length2() * grad.Length2() && + sqr (grad * v2) < 1e-6 * v2.Length2() * grad.Length2() ) // new, 18032006 JS + { + if (!surfind.Contains (GetSurfaceId(j))) + surfind.Append (GetSurfaceId(j)); + } + } + } +} + + + + +INSOLID_TYPE Primitive :: +VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + //(*testout) << "Primitive::VecInSolid2" << endl; + Point<3> hp = p + 1e-3 * v1 + 1e-5 * v2; + + INSOLID_TYPE res = PointInSolid (hp, eps); + // (*testout) << "vectorin2, type = " << typeid(*this).name() << ", res = " << res << endl; + + return res; +} + +INSOLID_TYPE Primitive :: +VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + //(*testout) << "Primitive::VecInSolid3" << endl; + return VecInSolid (p, v1, eps); +} + +INSOLID_TYPE Primitive :: +VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const +{ + return VecInSolid2 (p, v, m, eps); +} + + + + + +OneSurfacePrimitive :: OneSurfacePrimitive() +{ + ; +} + +OneSurfacePrimitive :: ~OneSurfacePrimitive() +{ + ; +} + + +INSOLID_TYPE OneSurfacePrimitive :: +PointInSolid (const Point<3> & p, + double eps) const +{ + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + return DOES_INTERSECT; +} + + +INSOLID_TYPE OneSurfacePrimitive :: +VecInSolid (const Point<3> & p, const Vec<3> & v, + double eps) const +{ + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + + Vec<3> hv; + GetSurface(0).CalcGradient (p, hv); + + hv1 = v * hv; + + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + return DOES_INTERSECT; +} + + +INSOLID_TYPE OneSurfacePrimitive :: +VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const +{ + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + Vec<3> hv; + + GetSurface(0).CalcGradient (p, hv); + + hv1 = v1 * hv; + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + double hv2 = v2 * hv; + if (hv2 <= 0) + return IS_INSIDE; + else + return IS_OUTSIDE; +} + + + +INSOLID_TYPE OneSurfacePrimitive :: +VecInSolid3 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + double eps) const +{ + //(*testout) << "OneSurfacePrimitive::VecInSolid3" << endl; + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + Vec<3> grad; + GetSurface(0).CalcGradient (p, grad); + + hv1 = v * grad; + if (hv1 <= -eps) return IS_INSIDE; + if (hv1 >= eps) return IS_OUTSIDE; + + Mat<3> hesse; + GetSurface(0).CalcHesse (p, hesse); + + double hv2 = v2 * grad + v * (hesse * v); + + if (hv2 <= -eps) return IS_INSIDE; + if (hv2 >= eps) return IS_OUTSIDE; + + return DOES_INTERSECT; +} + + + + +INSOLID_TYPE OneSurfacePrimitive :: +VecInSolid4 (const Point<3> & p, const Vec<3> & v, const Vec<3> & v2, + const Vec<3> & m, + double eps) const +{ + double hv1 = (GetSurface(0).CalcFunctionValue(p)); + if (hv1 <= -eps) + return IS_INSIDE; + if (hv1 >= eps) + return IS_OUTSIDE; + + Vec<3> grad; + GetSurface(0).CalcGradient (p, grad); + + hv1 = v * grad; + if (hv1 <= -eps) return IS_INSIDE; + if (hv1 >= eps) return IS_OUTSIDE; + + Mat<3> hesse; + GetSurface(0).CalcHesse (p, hesse); + + double hv2 = v2 * grad + v * (hesse * v); + + if (hv2 <= -eps) return IS_INSIDE; + if (hv2 >= eps) return IS_OUTSIDE; + + + double hv3 = m * grad; + if (hv3 <= -eps) return IS_INSIDE; + if (hv3 >= eps) return IS_OUTSIDE; + + return DOES_INTERSECT; +} + + + + + + + +int OneSurfacePrimitive :: GetNSurfaces() const +{ + return 1; +} + +Surface & OneSurfacePrimitive :: GetSurface (int i) +{ + return *this; +} + +const Surface & OneSurfacePrimitive :: GetSurface (int i) const +{ + return *this; +} + + + + + + +void ProjectToEdge (const Surface * f1, const Surface * f2, Point<3> & hp) +{ + Vec<2> rs, lam; + Vec<3> a1, a2; + Mat<2> a; + + int i = 10; + while (i > 0) + { + i--; + rs(0) = f1 -> CalcFunctionValue (hp); + rs(1) = f2 -> CalcFunctionValue (hp); + f1->CalcGradient (hp, a1); + f2->CalcGradient (hp, a2); + + double alpha = fabs(a1*a2)/sqrt(a1.Length2()*a2.Length2()); + if(fabs(1.-alpha) < 1e-6) + { + if(fabs(rs(0)) >= fabs(rs(1))) + f1 -> Project(hp); + else + f2 -> Project(hp); + } + else + { + + a(0,0) = a1 * a1; + a(0,1) = a(1,0) = a1 * a2; + a(1,1) = a2 * a2; + + a.Solve (rs, lam); + + hp -= lam(0) * a1 + lam(1) * a2; + } + + if (Abs2 (rs) < 1e-24 && i > 1) i = 1; + } +} +} diff --git a/libsrc/csg/surface.hpp b/libsrc/csg/surface.hpp new file mode 100644 index 00000000..21821241 --- /dev/null +++ b/libsrc/csg/surface.hpp @@ -0,0 +1,374 @@ +#ifndef FILE_SURFACE +#define FILE_SURFACE + +/**************************************************************************/ +/* File: surface.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 1. Dez. 95 */ +/**************************************************************************/ + + +namespace netgen +{ + + class TriangleApproximation; + + + /** + Basis class for implicit surface geometry. + This class is used for generation of surface meshes + in NETGEN + */ + class Surface + { + protected: + /// invert normal vector + bool inverse; + /// maximal h in surface + double maxh; + /// name of surface + char * name; + /// boundary condition nr + int bcprop; + /// boundary condition label + string bcname; + + public: + Surface (); + /** @name Tangential plane. + The tangential plane is used for surface mesh generation. + */ + + virtual ~Surface(); + + protected: + /** @name Points in the surface defining tangential plane. + Tangential plane is taken in p1, the local x-axis + is directed to p2. + */ + //@{ + /// + Point<3> p1; + /// + Point<3> p2; + //@} + /** @name Base-vectos for local coordinate system. */ + //@{ + /// in plane, directed p1->p2 + Vec<3> ex; + /// in plane + Vec<3> ey; + /// outer normal direction + Vec<3> ez; + //@} + public: + + void SetName (const char * aname); + const char * Name () const { return name; } + + //@{ + /** + Defines tangential plane in ap1. + The local x-coordinate axis points to the direction of ap2 */ + virtual void DefineTangentialPlane (const Point<3> & ap1, + const Point<3> & ap2); + + /// Transforms 3d point p3d to local coordinates pplane + virtual void ToPlane (const Point<3> & p3d, Point<2> & pplane, + double h, int & zone) const; + + /// Transforms point pplane in local coordinates to 3d point + virtual void FromPlane (const Point<2> & pplane, + Point<3> & p3d, double h) const; + //@} + + + /// Project point p onto surface (closest point) + virtual void Project (Point<3> & p) const; + + /// Project along direction + virtual void SkewProject(Point<3> & p, const Vec<3> & direction) const; + + /// Is current surface identic to surface 2 ? + virtual int IsIdentic (const Surface & /* s2 */, int & /* inv */, + double /* eps */) const + { return 0; } + + /// + virtual int PointOnSurface (const Point<3> & p, + double eps = 1e-6) const; + + + /** @name Implicit function. + Calculate function value and derivatives. + */ + //@{ + /// Calculate implicit function value in point point + virtual double CalcFunctionValue (const Point<3> & point) const = 0; + + /** + Calc gradient of implicit function. + gradient should be O(1) at surface + */ + virtual void CalcGradient (const Point<3> & point, Vec<3> & grad) const = 0; + + /** + Calculate second derivatives of implicit function. + */ + virtual void CalcHesse (const Point<3> & point, Mat<3> & hesse) const; + + /** + Returns outer normal vector. + */ + // virtual void GetNormalVector (const Point<3> & p, Vec<3> & n) const; + virtual Vec<3> GetNormalVector (const Point<3> & p) const; + + /** + Upper bound for spectral norm of Hesse-matrix + */ + virtual double HesseNorm () const = 0; + + /** + Upper bound for spectral norm of Hesse-matrix in the + rad - environment of point c. + */ + virtual double HesseNormLoc (const Point<3> & /* c */, + double /* rad */) const + { return HesseNorm (); } + //@} + + + /// + virtual double MaxCurvature () const; + /// + virtual double MaxCurvatureLoc (const Point<3> & /* c */ , + double /* rad */) const; + + /** Returns any point in the surface. + Needed to start surface mesh generation e.g. on sphere */ + virtual Point<3> GetSurfacePoint () const = 0; + + /// + bool Inverse () const { return inverse; } + /// + void SetInverse (bool ainverse) { inverse = ainverse; } + /// + virtual void Print (ostream & str) const = 0; + + /// + virtual void Reduce (const BoxSphere<3> & /* box */) { }; + /// + virtual void UnReduce () { }; + + /// set max h in surface + void SetMaxH (double amaxh) { maxh = amaxh; } + /// + double GetMaxH () const { return maxh; } + /// + int GetBCProperty () const { return bcprop; } + /// + void SetBCProperty (int abc) { bcprop = abc; } + + /** Determine local mesh-size. + Find + \[ h \leq hmax, \] + such that + \[ h \times \kappa (x) \leq c \qquad \mbox{in} B(x, h), \] + where kappa(x) is the curvature in x. */ + virtual double LocH (const Point<3> & p, double x, + double c, double hmax) const; + + /** + Gets Approximation by triangles, + where qual is about the number of triangles per radius + */ + virtual void GetTriangleApproximation (TriangleApproximation & /* tas */, + const Box<3> & /* boundingbox */, + double /* facets */ ) const { }; + + + string GetBCName() const { return bcname; } + + void SetBCName( string abc ) { bcname = abc; } + }; + + + inline ostream & operator<< (ostream & ost, const Surface & surf) + { + surf.Print(ost); + return ost; + } + + + + typedef enum { IS_OUTSIDE = 0, IS_INSIDE = 1, DOES_INTERSECT = 2} + INSOLID_TYPE; + + + + + class DummySurface : public Surface + { + virtual double CalcFunctionValue (const Point<3> & /* point */) const + { return 0; } + + virtual void CalcGradient (const Point<3> & /* point */, Vec<3> & grad) const + { grad = Vec<3> (0,0,0); } + + virtual Point<3> GetSurfacePoint () const + { return Point<3> (0,0,0); } + + virtual double HesseNorm () const + { return 0; } + + virtual void Project (Point<3> & /* p */) const + { ; } + + virtual void Print (ostream & ost) const + { ost << "dummy surface"; } + }; + + + + class Primitive + { + + public: + + Primitive (); + + virtual ~Primitive(); + + + /* + Check, whether box intersects solid defined by surface. + + return values: + 0 .. box outside solid \\ + 1 .. box in solid \\ + 2 .. can't decide (allowed, iff box is close to solid) + */ + virtual INSOLID_TYPE BoxInSolid (const BoxSphere<3> & box) const = 0; + virtual INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const = 0; + + virtual void GetTangentialSurfaceIndices (const Point<3> & p, + Array & surfind, double eps) const; + + virtual INSOLID_TYPE VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const = 0; + + // checks if lim s->0 lim t->0 p + t(v1 + s v2) in solid + virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + // checks if p + s v1 + s*s/2 v2 is inside + virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + // like VecInSolid2, but second order approximation + virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const; + + virtual void GetTangentialVecSurfaceIndices (const Point<3> & p, const Vec<3> & v, + Array & surfind, double eps) const; + + virtual void GetTangentialVecSurfaceIndices2 (const Point<3> & p, const Vec<3> & v1, const Vec<3> & v2, + Array & surfind, double eps) const; + + + virtual void CalcSpecialPoints (Array > & /* pts */) const { ; } + virtual void AnalyzeSpecialPoint (const Point<3> & /* pt */, + Array > & /* specpts */) const { ; } + virtual Vec<3> SpecialPointTangentialVector (const Point<3> & /* p */, + int /* s1 */, int /* s2 */) const + { return Vec<3> (0,0,0); } + + + virtual int GetNSurfaces() const = 0; + virtual Surface & GetSurface (int i = 0) = 0; + virtual const Surface & GetSurface (int i = 0) const = 0; + + Array surfaceids; + Array surfaceactive; + + int GetSurfaceId (int i = 0) const; + void SetSurfaceId (int i, int id); + int SurfaceActive (int i) const { return surfaceactive[i]; } + virtual int SurfaceInverted (int /* i */ = 0) const { return 0; } + + virtual void GetPrimitiveData (const char *& classname, + Array & coeffs) const; + virtual void SetPrimitiveData (Array & coeffs); + static Primitive * CreatePrimitive (const char * classname); + + + virtual void Reduce (const BoxSphere<3> & /* box */) { }; + virtual void UnReduce () { }; + + virtual Primitive * Copy () const; + virtual void Transform (Transformation<3> & trans); + }; + + + + + class OneSurfacePrimitive : public Surface, public Primitive + { + public: + OneSurfacePrimitive(); + ~OneSurfacePrimitive(); + + virtual INSOLID_TYPE PointInSolid (const Point<3> & p, + double eps) const; + virtual INSOLID_TYPE VecInSolid (const Point<3> & p, + const Vec<3> & v, + double eps) const; + virtual INSOLID_TYPE VecInSolid2 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual INSOLID_TYPE VecInSolid3 (const Point<3> & p, + const Vec<3> & v1, + const Vec<3> & v2, + double eps) const; + + virtual INSOLID_TYPE VecInSolid4 (const Point<3> & p, + const Vec<3> & v, + const Vec<3> & v2, + const Vec<3> & m, + double eps) const; + + virtual int GetNSurfaces() const; + virtual Surface & GetSurface (int i = 0); + virtual const Surface & GetSurface (int i = 0) const; + }; + + + + + + + /** + Projects point to edge. + The point hp is projected to the edge descibed by f1 and f2. + It is assumed that the edge is non-degenerated, and the + (generalized) Newton method converges. + */ + extern void ProjectToEdge (const Surface * f1, + const Surface * f2, + Point<3> & hp); + + +} + +#endif diff --git a/libsrc/csg/triapprox.cpp b/libsrc/csg/triapprox.cpp new file mode 100644 index 00000000..0c4f2b14 --- /dev/null +++ b/libsrc/csg/triapprox.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include +#include + + +namespace netgen +{ + + TriangleApproximation :: TriangleApproximation () + { + ; + } + + int TriangleApproximation :: + AddTriangle (const TATriangle & tri, bool invert) + { + trigs.Append (tri); + if (invert) + { + trigs.Last()[1] = tri[2]; + trigs.Last()[2] = tri[1]; + } + return trigs.Size()-1; + } + + + void TriangleApproximation :: RemoveUnusedPoints () + { + BitArray used(GetNP()); + Array map (GetNP()); + int i, j; + int cnt = 0; + + used.Clear(); + for (i = 0; i < GetNT(); i++) + for (j = 0; j < 3; j++) + used.Set (GetTriangle (i)[j]); + + for (i = 0; i < GetNP(); i++) + if (used.Test(i)) + map[i] = cnt++; + + for (i = 0; i < GetNT(); i++) + for (j = 0; j < 3; j++) + trigs[i][j] = map[trigs[i][j]]; + + for (i = 0; i < GetNP(); i++) + if (used.Test(i)) + { + points[map[i]] = points[i]; + normals[map[i]] = normals[i]; + } + + points.SetSize (cnt); + normals.SetSize (cnt); + } +} diff --git a/libsrc/csg/triapprox.hpp b/libsrc/csg/triapprox.hpp new file mode 100644 index 00000000..c17a3e94 --- /dev/null +++ b/libsrc/csg/triapprox.hpp @@ -0,0 +1,63 @@ +#ifndef FILE_TRIAPPROX +#define FILE_TRIAPPROX + +/**************************************************************************/ +/* File: triapprox.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 2. Mar. 98 */ +/**************************************************************************/ + + +namespace netgen +{ + + /** + Triangulated approxiamtion to true surface + */ + + + class TATriangle + { + int pi[3]; + int surfind; + public: + TATriangle () { ; } + + TATriangle (int si, int pi1, int pi2, int pi3) + { surfind = si; pi[0] = pi1; pi[1] = pi2; pi[2] = pi3; } + + int SurfaceIndex() const { return surfind; } + int & SurfaceIndex() { return surfind; } + + int & operator[] (int i) { return pi[i]; } + const int & operator[] (int i) const { return pi[i]; } + }; + + + class TriangleApproximation + { + Array > points; + Array > normals; + Array trigs; + + public: + TriangleApproximation(); + int GetNP () const { return points.Size(); } + int GetNT () const { return trigs.Size(); } + + int AddPoint (const Point<3> & p) { points.Append (p); return points.Size()-1; } + int AddNormal (const Vec<3> & n) { normals.Append (n); return normals.Size()-1; } + int AddTriangle (const TATriangle & tri, bool invert = 0); + + const Point<3> & GetPoint (int i) const { return points[i]; } + const TATriangle & GetTriangle (int i) const { return trigs[i]; } + const Vec<3> & GetNormal (int i) const { return normals[i]; } + + void RemoveUnusedPoints (); + + friend class CSGeometry; + }; + +} + +#endif diff --git a/libsrc/csg/vscsg.cpp b/libsrc/csg/vscsg.cpp new file mode 100644 index 00000000..dc72b51a --- /dev/null +++ b/libsrc/csg/vscsg.cpp @@ -0,0 +1,495 @@ +#include +#include "incvis.hpp" + +#include +#include +#include +#include + +#include + +#include "vscsg.hpp" + +namespace netgen +{ + + + + /* *********************** Draw Geometry **************** */ + + extern AutoPtr mesh; + extern Array specpoints; + extern Array > boxes; + + + extern Array > project1, project2; + + + // extern AutoPtr geometry; + + + VisualSceneGeometry :: VisualSceneGeometry () + : VisualScene() + { + selsurf = 0; + } + + VisualSceneGeometry :: ~VisualSceneGeometry () + { + ; + } + + void VisualSceneGeometry :: SelectSurface (int aselsurf) + { + selsurf = aselsurf; + DrawScene(); + } + + + void VisualSceneGeometry :: DrawScene () + { + if (changeval != geometry->GetChangeVal()) + BuildScene(); + changeval = geometry->GetChangeVal(); + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + SetLight(); + + + glPushMatrix(); + glMultMatrixf (transformationmat); + + SetClippingPlane (); + + glShadeModel (GL_SMOOTH); + glDisable (GL_COLOR_MATERIAL); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + /* + float mat_spec_col[] = { 1, 1, 1, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); + */ + + double shine = vispar.shininess; + double transp = vispar.transp; + + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); + glLogicOp (GL_COPY); + + glEnable (GL_NORMALIZE); + + for (int i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + const TopLevelObject * tlo = geometry -> GetTopLevelObject (i); + if (tlo->GetVisible() && !tlo->GetTransparent()) + { + float mat_col[] = { tlo->GetRed(), tlo->GetGreen(), tlo->GetBlue(), 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + glCallList (trilists[i]); + } + } + + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glLogicOp (GL_NOOP); + for (int i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + const TopLevelObject * tlo = geometry -> GetTopLevelObject (i); + if (tlo->GetVisible() && tlo->GetTransparent()) + { + float mat_col[] = { tlo->GetRed(), tlo->GetGreen(), tlo->GetBlue(), transp }; + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + glCallList (trilists[i]); + } + } + + glDisable (GL_POLYGON_OFFSET_FILL); + + glPopMatrix(); + glDisable(GL_CLIP_PLANE0); + + + + DrawCoordinateCross (); + DrawNetgenLogo (); + + glFinish(); + } + + + void VisualSceneGeometry :: BuildScene (int zoomall) + { + Box<3> box; + int hasp = 0; + for (int i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + const TriangleApproximation & ta = + *geometry->GetTriApprox(i); + if (!&ta) continue; + + for (int j = 0; j < ta.GetNP(); j++) + { + if (hasp) + box.Add (ta.GetPoint(j)); + else + { + hasp = 1; + box.Set (ta.GetPoint(j)); + } + } + } + if (hasp) + { + center = box.Center(); + rad = box.Diam() / 2; + } + else + { + center = Point3d(0,0,0); + rad = 1; + } + + CalcTransformationMatrices(); + + for (int i = 0; i < trilists.Size(); i++) + glDeleteLists (trilists[i], 1); + trilists.SetSize(0); + + for (int i = 0; i < geometry->GetNTopLevelObjects(); i++) + { + trilists.Append (glGenLists (1)); + glNewList (trilists.Last(), GL_COMPILE); + glEnable (GL_NORMALIZE); + const TriangleApproximation & ta = + *geometry->GetTriApprox(i); + if (&ta) + { + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_DOUBLE, 0, &ta.GetPoint(0)(0)); + + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_DOUBLE, 0, &ta.GetNormal(0)(0)); + + for (int j = 0; j < ta.GetNT(); j++) + glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, & (ta.GetTriangle(j)[0])); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + /* + for (int j = 0; j < ta.GetNT(); j++) + { + glBegin (GL_TRIANGLES); + for (int k = 0; k < 3; k++) + { + int pi = ta.GetTriangle(j)[k]; + glNormal3dv (ta.GetNormal(pi)); + glVertex3dv (ta.GetPoint(pi)); + } + glEnd (); + } + */ + } + glEndList (); + } + } + + + + + + + + + + + + + + + + + + + + + + + VisualSceneSpecPoints :: VisualSceneSpecPoints () + : VisualScene() + { + ; + } + + VisualSceneSpecPoints :: ~VisualSceneSpecPoints () + { + ; + } + + + void VisualSceneSpecPoints :: DrawScene () + { + if (!mesh) + { + VisualScene::DrawScene(); + return; + } + + if (changeval != specpoints.Size()) + BuildScene(); + changeval = specpoints.Size(); + + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable (GL_COLOR_MATERIAL); + glColor3f (1.0f, 1.0f, 1.0f); + glLineWidth (1.0f); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + // glEnable (GL_COLOR); + // glDisable (GL_COLOR_MATERIAL); + if (vispar.drawedtangents) + { + glColor3d (1, 0, 0); + glBegin (GL_LINES); + for (int i = 1; i <= specpoints.Size(); i++) + { + const Point3d p1 = specpoints.Get(i).p; + const Point3d p2 = specpoints.Get(i).p + len * specpoints.Get(i).v; + glVertex3d (p1.X(), p1.Y(), p1.Z()); + glVertex3d (p2.X(), p2.Y(), p2.Z()); + } + glEnd(); + } + + if (vispar.drawededges) + { + glColor3d (1, 0, 0); + glBegin (GL_LINES); + for (int i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh -> LineSegment (i); + glVertex3dv ( (*mesh)[seg[0]] ); + glVertex3dv ( (*mesh)[seg[1]] ); + // glVertex3dv ( &(*mesh)[seg[0]].X() ); + // glVertex3dv ( &(*mesh)[seg[1]].X() ); + } + glEnd(); + } + + glColor3d (1, 0, 0); + glBegin (GL_LINES); + int edges[12][2] = + { { 0, 1 }, + { 2, 3 }, + { 4, 5 }, + { 6, 7 }, + { 0, 2 }, + { 1, 3 }, + { 4, 6 }, + { 5, 7 }, + { 0, 4 }, + { 1, 5 }, + { 2, 6 }, + { 3, 7 } }; + for (int i = 0; i < boxes.Size(); i++) + { + for (int j = 0; j < 12; j++) + { + glVertex3dv ( boxes[i].GetPointNr(edges[j][0]) ); + glVertex3dv ( boxes[i].GetPointNr(edges[j][1]) ); + } + /* + glVertex3dv ( boxes[i].PMin() ); + glVertex3dv ( boxes[i].PMax() ); + */ + } + glEnd(); + + + + if (vispar.drawededgenrs) + { + glEnable (GL_COLOR_MATERIAL); + GLfloat textcol[3] = { 1 - backcolor, + 1 - backcolor, + 1 - backcolor }; + glColor3fv (textcol); + glNormal3d (0, 0, 1); + glPushAttrib (GL_LIST_BIT); + // glListBase (fontbase); + + char buf[20]; + for (int i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh -> LineSegment (i); + const Point3d p1 = mesh -> Point (seg[0]); + const Point3d p2 = mesh -> Point (seg[1]); + + const Point3d p = Center (p1, p2); + glRasterPos3d (p.X(), p.Y(), p.Z()); + + sprintf (buf, "%d", seg.edgenr); + // glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + } + + glPopAttrib (); + glDisable (GL_COLOR_MATERIAL); + } + + + if (vispar.drawedpoints) + { + + glColor3d (0, 0, 1); + /* + glPointSize( 3.0 ); + + float range[2]; + glGetFloatv(GL_POINT_SIZE_RANGE, &range[0]); + cout << "max ptsize = " << range[0] << "-" << range[1] << endl; + + + glBegin( GL_POINTS ); + for (int i = 1; i <= mesh -> GetNP(); i++) + { + const Point3d & p = mesh -> Point(i); + if (i % 2) + glVertex3f( p.X(), p.Y(), p.Z()); + } + glEnd(); + */ + + static GLubyte knoedel[] = + { + 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + }; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glDisable (GL_COLOR_MATERIAL); + glDisable (GL_LIGHTING); + glDisable (GL_CLIP_PLANE0); + + for (int i = 1; i <= mesh -> GetNP(); i++) + { + const Point3d & p = mesh -> Point(i); + glRasterPos3d (p.X(), p.Y(), p.Z()); + glBitmap (7, 7, 3, 3, 0, 0, &knoedel[0]); + } + } + + if (vispar.drawedpointnrs) + { + glEnable (GL_COLOR_MATERIAL); + GLfloat textcol[3] = { 1 - backcolor, + 1 - backcolor, + 1 - backcolor }; + glColor3fv (textcol); + glNormal3d (0, 0, 1); + glPushAttrib (GL_LIST_BIT); + // glListBase (fontbase); + + char buf[20]; + for (int i = 1; i <= mesh->GetNP(); i++) + { + const Point3d & p = mesh->Point(i); + glRasterPos3d (p.X(), p.Y(), p.Z()); + + sprintf (buf, "%d", i); + // glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + } + + glPopAttrib (); + glDisable (GL_COLOR_MATERIAL); + } + + + + + + + glPopMatrix(); + + if (vispar.drawcoordinatecross) + DrawCoordinateCross (); + DrawNetgenLogo (); + + glFinish(); + } + + + void VisualSceneSpecPoints :: BuildScene (int zoomall) + { + if (!mesh) + { + VisualScene::BuildScene(zoomall); + return; + } + + Box3d box; + + if (mesh->GetNSeg()) + { + box.SetPoint (mesh->Point (mesh->LineSegment(1)[0])); + for (int i = 1; i <= mesh->GetNSeg(); i++) + { + box.AddPoint (mesh->Point (mesh->LineSegment(i)[0])); + box.AddPoint (mesh->Point (mesh->LineSegment(i)[1])); + } + } + else if (specpoints.Size() >= 2) + { + box.SetPoint (specpoints.Get(1).p); + for (int i = 2; i <= specpoints.Size(); i++) + box.AddPoint (specpoints.Get(i).p); + } + else + { + box = Box3d (Point3d (0,0,0), Point3d (1,1,1)); + } + + if (zoomall == 2 && ((vispar.centerpoint >= 1 && vispar.centerpoint <= mesh->GetNP()) || + vispar.use_center_coords)) + { + if (vispar.use_center_coords) + { + center.X() = vispar.centerx; center.Y() = vispar.centery; center.Z() = vispar.centerz; + } + else + center = mesh->Point (vispar.centerpoint); + } + else + center = Center (box.PMin(), box.PMax()); + + + rad = 0.5 * Dist (box.PMin(), box.PMax()); + + + CalcTransformationMatrices(); + } + + + + + + +} + + diff --git a/libsrc/csg/vscsg.hpp b/libsrc/csg/vscsg.hpp new file mode 100644 index 00000000..c32f5da8 --- /dev/null +++ b/libsrc/csg/vscsg.hpp @@ -0,0 +1,34 @@ +#ifndef FILE_VSCSG +#define FILE_VSCSG + +/**************************************************************************/ +/* File: vscsg.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 05. Jan. 2011 */ +/**************************************************************************/ + +namespace netgen +{ + + class VisualSceneGeometry : public VisualScene + { + class CSGeometry * geometry; + Array trilists; + int selsurf; + public: + VisualSceneGeometry (); + virtual ~VisualSceneGeometry (); + + void SetGeometry (class CSGeometry * ageometry) { geometry = ageometry; } + virtual void SelectSurface (int aselsurf); + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + }; + + + +} + + + +#endif diff --git a/libsrc/general/Makefile.am b/libsrc/general/Makefile.am new file mode 100644 index 00000000..aa4031f5 --- /dev/null +++ b/libsrc/general/Makefile.am @@ -0,0 +1,15 @@ +noinst_HEADERS = array.hpp myadt.hpp optmem.hpp sort.hpp table.hpp autodiff.hpp flags.hpp mystring.hpp spbita2d.hpp template.hpp autoptr.hpp hashtabl.hpp netgenout.hpp profiler.hpp stack.hpp bitarray.hpp seti.hpp symbolta.hpp dynamicmem.hpp parthreads.hpp mpi_interface.hpp gzstream.h + +# moveablemem.hpp + +include_HEADERS = ngexception.hpp + +AM_CPPFLAGS = $(MPI_INCLUDES) -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LTLIBRARIES = libgen.la +libgen_la_SOURCES = array.cpp bitarray.cpp dynamicmem.cpp flags.cpp \ + hashtabl.cpp mystring.cpp ngexception.cpp optmem.cpp parthreads.cpp \ + profiler.cpp seti.cpp sort.cpp spbita2d.cpp symbolta.cpp table.cpp \ + mpi_interface.cpp gzstream.cpp + +# moveablemem.cpp diff --git a/libsrc/general/Makefile.in b/libsrc/general/Makefile.in new file mode 100644 index 00000000..63fd7135 --- /dev/null +++ b/libsrc/general/Makefile.in @@ -0,0 +1,614 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc/general +DIST_COMMON = $(include_HEADERS) $(noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libgen_la_LIBADD = +am_libgen_la_OBJECTS = array.lo bitarray.lo dynamicmem.lo flags.lo \ + hashtabl.lo mystring.lo ngexception.lo optmem.lo parthreads.lo \ + profiler.lo seti.lo sort.lo spbita2d.lo symbolta.lo table.lo \ + mpi_interface.lo gzstream.lo +libgen_la_OBJECTS = $(am_libgen_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgen_la_SOURCES) +DIST_SOURCES = $(libgen_la_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = array.hpp myadt.hpp optmem.hpp sort.hpp table.hpp autodiff.hpp flags.hpp mystring.hpp spbita2d.hpp template.hpp autoptr.hpp hashtabl.hpp netgenout.hpp profiler.hpp stack.hpp bitarray.hpp seti.hpp symbolta.hpp dynamicmem.hpp parthreads.hpp mpi_interface.hpp gzstream.h + +# moveablemem.hpp +include_HEADERS = ngexception.hpp +AM_CPPFLAGS = $(MPI_INCLUDES) -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LTLIBRARIES = libgen.la +libgen_la_SOURCES = array.cpp bitarray.cpp dynamicmem.cpp flags.cpp \ + hashtabl.cpp mystring.cpp ngexception.cpp optmem.cpp parthreads.cpp \ + profiler.cpp seti.cpp sort.cpp spbita2d.cpp symbolta.cpp table.cpp \ + mpi_interface.cpp gzstream.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/general/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/general/Makefile +.PRECIOUS: 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)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgen.la: $(libgen_la_OBJECTS) $(libgen_la_DEPENDENCIES) $(EXTRA_libgen_la_DEPENDENCIES) + $(CXXLINK) $(libgen_la_OBJECTS) $(libgen_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bitarray.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dynamicmem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gzstream.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtabl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi_interface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mystring.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngexception.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optmem.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parthreads.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seti.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sort.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spbita2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbolta.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/table.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-includeHEADERS + +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: uninstall-includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags 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-includeHEADERS 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 uninstall uninstall-am uninstall-includeHEADERS + + +# moveablemem.cpp + +# 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/libsrc/general/array.cpp b/libsrc/general/array.cpp new file mode 100644 index 00000000..d3f48d36 --- /dev/null +++ b/libsrc/general/array.cpp @@ -0,0 +1,75 @@ +#ifndef FILE_NGSTD_ArrayCPP +#define FILE_NGSTD_ArrayCPP +// necessary for SGI ???? + +/**************************************************************************/ +/* File: array.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Abstract data type Array +*/ + +#include +#include +#include + + +namespace netgen +{ + //using namespace netgen; + +#ifdef NONE + void BASE_Array :: ReSize (int minsize, int elementsize) + { + cout << "resize, minsize = " << minsize << endl; + + if (inc == -1) + throw Exception ("Try to resize fixed size array"); + + + void * p; + int nsize = (inc) ? allocsize + inc : 2 * allocsize; + if (nsize < minsize) nsize = minsize; + + if (data) + { + p = new char [nsize * elementsize]; + + int mins = (nsize < actsize) ? nsize : actsize; + memcpy (p, data, mins * elementsize); + + delete [] static_cast (data); + data = p; + } + else + { + data = new char[nsize * elementsize]; + } + + allocsize = nsize; + cout << "resize done" << endl; + } + + + + void BASE_Array :: RangeCheck (int i) const + { + if (i < 0 || i >= actsize) + throw ArrayRangeException (); + } + + void BASE_Array :: CheckNonEmpty () const + { + if (!actsize) + { + throw Exception ("Array should not be empty"); + // cerr << "Array souldn't be empty"; + } + } +#endif +} +#endif + diff --git a/libsrc/general/array.hpp b/libsrc/general/array.hpp new file mode 100644 index 00000000..acd889fb --- /dev/null +++ b/libsrc/general/array.hpp @@ -0,0 +1,698 @@ +#ifndef FILE_Array +#define FILE_Array + +/**************************************************************************/ +/* File: array.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + + +namespace netgen +{ + + // template class IndirectArray; + template class IndirectArray; + + + + /** + A simple array container. + Array represented by size and data-pointer. + No memory allocation and deallocation, must be provided by user. + Helper functions for printing. + Optional range check by macro RANGE_CHECK + */ + + template + class FlatArray + { + protected: + /// the size + int size; + /// the data + T * data; + public: + typedef T TELEM; + + /// provide size and memory + FlatArray (int asize, T * adata) + : size(asize), data(adata) { ; } + + /// the size + int Size() const { return size; } + + TIND Begin() const { return TIND(BASE); } + TIND End() const { return TIND(size+BASE); } + + /// Access array. BASE-based + T & operator[] (TIND i) const + { +#ifdef DEBUG + if (i-BASE < 0 || i-BASE >= size) + cout << "array<" << typeid(T).name() << "> out of range, i = " << i << ", s = " << size << endl; +#endif + + return data[i-BASE]; + } + + template + IndirectArray > operator[] (const FlatArray & ia) const + { + return IndirectArray > (*this, ia); + } + + + + /// Access array, one-based (old fashioned) + T & Elem (int i) + { +#ifdef DEBUG + if (i < 1 || i > size) + cout << "Array<" << typeid(T).name() + << ">::Elem out of range, i = " << i + << ", s = " << size << endl; +#endif + + return ((T*)data)[i-1]; + } + + /// Access array, one-based (old fashioned) + const T & Get (int i) const + { +#ifdef DEBUG + if (i < 1 || i > size) + cout << "Array<" << typeid(T).name() << ">::Get out of range, i = " << i + << ", s = " << size << endl; +#endif + + return ((const T*)data)[i-1]; + } + + /// Access array, one-based (old fashioned) + void Set (int i, const T & el) + { +#ifdef DEBUG + if (i < 1 || i > size) + cout << "Array<" << typeid(T).name() << ">::Set out of range, i = " << i + << ", s = " << size << endl; +#endif + + ((T*)data)[i-1] = el; + } + + /// access first element + T & First () const + { + return data[0]; + } + + + /// access last element. check by macro CHECK_RANGE + T & Last () const + { + return data[size-1]; + } + + /// Fill array with value val + FlatArray & operator= (const T & val) + { + for (int i = 0; i < size; i++) + data[i] = val; + return *this; + } + + /// takes range starting from position start of end-start elements + const FlatArray Range (TIND start, TIND end) + { + return FlatArray (end-start, data+start); + } + + /// first position of element elem, returns -1 if element not contained in array + TIND Pos(const T & elem) const + { + TIND pos = -1; + for(TIND i=0; pos==-1 && i < this->size; i++) + if(elem == data[i]) pos = i; + return pos; + } + + /// does the array contain element elem ? + bool Contains(const T & elem) const + { + return ( Pos(elem) >= 0 ); + } + }; + + + + // print array + template + inline ostream & operator<< (ostream & s, const FlatArray & a) + { + for (TIND i = a.Begin(); i < a.End(); i++) + s << i << ": " << a[i] << endl; + return s; + } + + + + /** + Dynamic array container. + + Array is an automatically increasing array container. + The allocated memory doubles on overflow. + Either the container takes care of memory allocation and deallocation, + or the user provides one block of data. + */ + template + class Array : public FlatArray + { + protected: + using FlatArray::size; + using FlatArray::data; + + /// physical size of array + int allocsize; + /// memory is responsibility of container + bool ownmem; + + public: + + /// Generate array of logical and physical size asize + explicit Array() + : FlatArray (0, NULL) + { + allocsize = 0; + ownmem = 1; + } + + explicit Array(int asize) + : FlatArray (asize, new T[asize]) + { + allocsize = asize; + ownmem = 1; + } + + /// Generate array in user data + Array(TIND asize, T* adata) + : FlatArray (asize, adata) + { + allocsize = asize; + ownmem = 0; + } + + /// array copy + explicit Array (const Array & a2) + : FlatArray (a2.Size(), a2.Size() ? new T[a2.Size()] : 0) + { + allocsize = size; + ownmem = 1; + for (TIND i = BASE; i < size+BASE; i++) + (*this)[i] = a2[i]; + } + + + + /// if responsible, deletes memory + ~Array() + { + if (ownmem) + delete [] data; + } + + /// Change logical size. If necessary, do reallocation. Keeps contents. + void SetSize(int nsize) + { + if (nsize > allocsize) + ReSize (nsize); + size = nsize; + } + + /// Change physical size. Keeps logical size. Keeps contents. + void SetAllocSize (int nallocsize) + { + if (nallocsize > allocsize) + ReSize (nallocsize); + } + + + /// Add element at end of array. reallocation if necessary. + int Append (const T & el) + { + if (size == allocsize) + ReSize (size+1); + data[size] = el; + size++; + return size; + } + + template + void Append (FlatArray a2) + { + if (size+a2.Size() > allocsize) + ReSize (size+a2.Size()); + for (int i = 0; i < a2.Size(); i++) + data[size+i] = a2[i+B2]; + size += a2.Size(); + } + + + /// Delete element i (0-based). Move last element to position i. + void Delete (TIND i) + { +#ifdef CHECK_Array_RANGE + RangeCheck (i+1); +#endif + + data[i] = data[size-1]; + size--; + // DeleteElement (i+1); + } + + + /// Delete element i (1-based). Move last element to position i. + void DeleteElement (TIND i) + { +#ifdef CHECK_Array_RANGE + RangeCheck (i); +#endif + + data[i-1] = data[size-1]; + size--; + } + + /// Delete last element. + void DeleteLast () + { + size--; + } + + /// Deallocate memory + void DeleteAll () + { + if (ownmem) + delete [] data; + data = 0; + size = allocsize = 0; + } + + /// Fill array with val + Array & operator= (const T & val) + { + FlatArray::operator= (val); + return *this; + } + + /// array copy + Array & operator= (const Array & a2) + { + SetSize (a2.Size()); + for (TIND i (BASE); i < size+BASE; i++) + (*this)[i] = a2[i]; + return *this; + } + + /// array copy + Array & operator= (const FlatArray & a2) + { + SetSize (a2.Size()); + for (TIND i = BASE; i < size+BASE; i++) + (*this)[i] = a2[i]; + return *this; + } + + + private: + + /// resize array, at least to size minsize. copy contents + void ReSize (int minsize) + { + int nsize = 2 * allocsize; + if (nsize < minsize) nsize = minsize; + + if (data) + { + T * p = new T[nsize]; + + int mins = (nsize < size) ? nsize : size; + memcpy (p, data, mins * sizeof(T)); + + if (ownmem) + delete [] data; + ownmem = 1; + data = p; + } + else + { + data = new T[nsize]; + ownmem = 1; + } + + allocsize = nsize; + } + }; + + + + template + class ArrayMem : public Array + { + using Array::size; + using Array::data; + using Array::ownmem; + + // T mem[S]; // Intel C++ calls dummy constructor + // char mem[S*sizeof(T)]; + double mem[(S*sizeof(T)+7) / 8]; + public: + /// Generate array of logical and physical size asize + explicit ArrayMem(int asize = 0) + : Array (S, static_cast (static_cast(&mem[0]))) + { + size = asize; + if (asize > S) + { + data = new T[asize]; + ownmem = 1; + } + // SetSize (asize); + } + + ArrayMem & operator= (const T & val) + { + Array::operator= (val); + return *this; + } + + /// array copy + ArrayMem & operator= (const FlatArray & a2) + { + this->SetSize (a2.Size()); + for (int i = 0; i < size; i++) + (*this)[i] = a2[i]; + return *this; + } + + }; + + + + + /* + template + class IndirectArray + { + const FlatArray & array; + const FlatArray & ia; + + public: + IndirectArray (const FlatArray & aa, const FlatArray & aia) + : array(aa), ia(aia) { ; } + int Size() const { return ia.Size(); } + const T & operator[] (int i) const { return array[ia[i]]; } + }; + */ + + template + class IndirectArray + { + const TA1 & array; + const TA2 & ia; + + public: + IndirectArray (const TA1 & aa, const TA2 & aia) + : array(aa), ia(aia) { ; } + int Size() const { return ia.Size(); } + int Begin() const { return ia.Begin(); } + int End() const { return ia.End(); } + + const typename TA1::TELEM & operator[] (int i) const { return array[ia[i]]; } + }; + + + template + inline ostream & operator<< (ostream & s, const IndirectArray & ia) + { + for (int i = ia.Begin(); i < ia.End(); i++) + s << i << ": " << ia[i] << endl; + return s; + } + + + + /* + + /// + template + class MoveableArray + { + int size; + int allocsize; + DynamicMem data; + + public: + + MoveableArray() + { + size = allocsize = 0; + data.SetName ("MoveableArray"); + } + + MoveableArray(int asize) + : size(asize), allocsize(asize), data(asize) + { ; } + + ~MoveableArray () { ; } + + int Size() const { return size; } + + void SetSize(int nsize) + { + if (nsize > allocsize) + { + data.ReAlloc (nsize); + allocsize = nsize; + } + size = nsize; + } + + void SetAllocSize (int nallocsize) + { + data.ReAlloc (nallocsize); + allocsize = nallocsize; + } + + /// + T & operator[] (int i) + { return ((T*)data)[i-BASE]; } + + /// + const T & operator[] (int i) const + { return ((const T*)data)[i-BASE]; } + + /// + T & Elem (int i) + { return ((T*)data)[i-1]; } + + /// + const T & Get (int i) const + { return ((const T*)data)[i-1]; } + + /// + void Set (int i, const T & el) + { ((T*)data)[i-1] = el; } + + /// + T & Last () + { return ((T*)data)[size-1]; } + + /// + const T & Last () const + { return ((const T*)data)[size-1]; } + + /// + int Append (const T & el) + { + if (size == allocsize) + { + SetAllocSize (2*allocsize+1); + } + ((T*)data)[size] = el; + size++; + return size; + } + + /// + void Delete (int i) + { + DeleteElement (i+1); + } + + /// + void DeleteElement (int i) + { + ((T*)data)[i-1] = ((T*)data)[size-1]; + size--; + } + + /// + void DeleteLast () + { size--; } + + /// + void DeleteAll () + { + size = allocsize = 0; + data.Free(); + } + + /// + void PrintMemInfo (ostream & ost) const + { + ost << Size() << " elements of size " << sizeof(T) << " = " + << Size() * sizeof(T) << endl; + } + + MoveableArray & operator= (const T & el) + { + for (int i = 0; i < size; i++) + ((T*)data)[i] = el; + return *this; + } + + + MoveableArray & Copy (const MoveableArray & a2) + { + SetSize (a2.Size()); + for (int i = 0; i < this->size; i++) + data[i] = a2.data[i]; + return *this; + } + + /// array copy + MoveableArray & operator= (const MoveableArray & a2) + { + return Copy(a2); + } + + + void SetName (const char * aname) + { + data.SetName(aname); + } + private: + /// + //MoveableArray & operator= (MoveableArray &); //??? + /// + //MoveableArray (const MoveableArray &); //??? + }; + + + template + inline ostream & operator<< (ostream & ost, MoveableArray & a) + { + for (int i = 0; i < a.Size(); i++) + ost << i << ": " << a[i] << endl; + return ost; + } + */ + + + /// bubble sort array + template + inline void BubbleSort (const FlatArray & data) + { + for (int i = 0; i < data.Size(); i++) + for (int j = i+1; j < data.Size(); j++) + if (data[i] > data[j]) + { + T hv = data[i]; + data[i] = data[j]; + data[j] = hv; + } + } + + /// bubble sort array + template + inline void BubbleSort (FlatArray & data, FlatArray & slave) + { + for (int i = 0; i < data.Size(); i++) + for (int j = i+1; j < data.Size(); j++) + if (data[i] > data[j]) + { + T hv = data[i]; + data[i] = data[j]; + data[j] = hv; + + S hvs = slave[i]; + slave[i] = slave[j]; + slave[j] = hvs; + } + } + + + template + void QuickSortRec (FlatArray & data, + FlatArray & slave, + int left, int right) + { + int i = left; + int j = right; + T midval = data[(left+right)/2]; + + do + { + while (data[i] < midval) i++; + while (midval < data[j]) j--; + + if (i <= j) + { + Swap (data[i], data[j]); + Swap (slave[i], slave[j]); + i++; j--; + } + } + while (i <= j); + if (left < j) QuickSortRec (data, slave, left, j); + if (i < right) QuickSortRec (data, slave, i, right); + } + + template + void QuickSort (FlatArray & data, FlatArray & slave) + { + QuickSortRec (data, slave, 0, data.Size()-1); + } + + + + + + + + + + template + void Intersection (const FlatArray & in1, const FlatArray & in2, + Array & out) + { + out.SetSize(0); + for(int i=0; i + void Intersection (const FlatArray & in1, const FlatArray & in2, const FlatArray & in3, + Array & out) + { + out.SetSize(0); + for(int i=0; i +class AutoDiff +{ + SCAL val; + SCAL dval[D]; +public: + + typedef AutoDiff TELEM; + typedef SCAL TSCAL; + + + /// elements are undefined + AutoDiff () throw() { }; + // { val = 0; for (int i = 0; i < D; i++) dval[i] = 0; } // ! + + /// copy constructor + AutoDiff (const AutoDiff & ad2) throw() + { + val = ad2.val; + for (int i = 0; i < D; i++) + dval[i] = ad2.dval[i]; + } + + /// initial object with constant value + AutoDiff (SCAL aval) throw() + { + val = aval; + for (int i = 0; i < D; i++) + dval[i] = 0; + } + + /// init object with (val, e_diffindex) + AutoDiff (SCAL aval, int diffindex) throw() + { + val = aval; + for (int i = 0; i < D; i++) + dval[i] = 0; + dval[diffindex] = 1; + } + + /// assign constant value + AutoDiff & operator= (SCAL aval) throw() + { + val = aval; + for (int i = 0; i < D; i++) + dval[i] = 0; + return *this; + } + + /// returns value + SCAL Value() const throw() { return val; } + + /// returns partial derivative + SCAL DValue (int i) const throw() { return dval[i]; } + + /// access value + SCAL & Value() throw() { return val; } + + /// accesses partial derivative + SCAL & DValue (int i) throw() { return dval[i]; } + + /// + AutoDiff & operator+= (const AutoDiff & y) throw() + { + val += y.val; + for (int i = 0; i < D; i++) + dval[i] += y.dval[i]; + return *this; + } + + /// + AutoDiff & operator-= (const AutoDiff & y) throw() + { + val -= y.val; + for (int i = 0; i < D; i++) + dval[i] -= y.dval[i]; + return *this; + + } + + /// + AutoDiff & operator*= (const AutoDiff & y) throw() + { + for (int i = 0; i < D; i++) + { + // dval[i] *= y.val; + // dval[i] += val * y.dval[i]; + dval[i] = dval[i] * y.val + val * y.dval[i]; + } + val *= y.val; + return *this; + } + + /// + AutoDiff & operator*= (const SCAL & y) throw() + { + val *= y; + for (int i = 0; i < D; i++) + dval[i] *= y; + return *this; + } + + /// + AutoDiff & operator/= (const SCAL & y) throw() + { + SCAL iy = 1.0 / y; + val *= iy; + for (int i = 0; i < D; i++) + dval[i] *= iy; + return *this; + } + + /// + bool operator== (SCAL val2) throw() + { + return val == val2; + } + + /// + bool operator!= (SCAL val2) throw() + { + return val != val2; + } + + /// + bool operator< (SCAL val2) throw() + { + return val < val2; + } + + /// + bool operator> (SCAL val2) throw() + { + return val > val2; + } +}; + + +//@{ AutoDiff helper functions. + +/// prints AutoDiff +template +inline ostream & operator<< (ostream & ost, const AutoDiff & x) +{ + ost << x.Value() << ", D = "; + for (int i = 0; i < D; i++) + ost << x.DValue(i) << " "; + return ost; +} + +/// AutoDiff plus AutoDiff +template +inline AutoDiff operator+ (const AutoDiff & x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value () = x.Value()+y.Value(); + // AutoDiff res(x.Value()+y.Value()); + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i) + y.DValue(i); + return res; +} + + +/// AutoDiff minus AutoDiff +template +inline AutoDiff operator- (const AutoDiff & x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x.Value()-y.Value(); + // AutoDiff res (x.Value()-y.Value()); + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i) - y.DValue(i); + return res; +} + +/// double plus AutoDiff +template +inline AutoDiff operator+ (double x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x+y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = y.DValue(i); + return res; +} + +/// AutoDiff plus double +template +inline AutoDiff operator+ (const AutoDiff & y, double x) throw() +{ + AutoDiff res; + res.Value() = x+y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = y.DValue(i); + return res; +} + + +/// minus AutoDiff +template +inline AutoDiff operator- (const AutoDiff & x) throw() +{ + AutoDiff res; + res.Value() = -x.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = -x.DValue(i); + return res; +} + +/// AutoDiff minus double +template +inline AutoDiff operator- (const AutoDiff & x, double y) throw() +{ + AutoDiff res; + res.Value() = x.Value()-y; + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i); + return res; +} + +/// +template +inline AutoDiff operator- (double x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x-y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = -y.DValue(i); + return res; +} + + +/// double times AutoDiff +template +inline AutoDiff operator* (double x, const AutoDiff & y) throw() +{ + AutoDiff res; + res.Value() = x*y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = x*y.DValue(i); + return res; +} + +/// AutoDiff times double +template +inline AutoDiff operator* (const AutoDiff & y, double x) throw() +{ + AutoDiff res; + res.Value() = x*y.Value(); + for (int i = 0; i < D; i++) + res.DValue(i) = x*y.DValue(i); + return res; +} + +/// AutoDiff times AutoDiff +template +inline AutoDiff operator* (const AutoDiff & x, const AutoDiff & y) throw() +{ + AutoDiff res; + SCAL hx = x.Value(); + SCAL hy = y.Value(); + + res.Value() = hx*hy; + for (int i = 0; i < D; i++) + res.DValue(i) = hx*y.DValue(i) + hy*x.DValue(i); + + return res; +} + +/// AutoDiff times AutoDiff +template +inline AutoDiff sqr (const AutoDiff & x) throw() +{ + AutoDiff res; + SCAL hx = x.Value(); + res.Value() = hx*hx; + hx *= 2; + for (int i = 0; i < D; i++) + res.DValue(i) = hx*x.DValue(i); + return res; +} + +/// Inverse of AutoDiff +template +inline AutoDiff Inv (const AutoDiff & x) +{ + AutoDiff res(1.0 / x.Value()); + for (int i = 0; i < D; i++) + res.DValue(i) = -x.DValue(i) / (x.Value() * x.Value()); + return res; +} + + +/// AutoDiff div AutoDiff +template +inline AutoDiff operator/ (const AutoDiff & x, const AutoDiff & y) +{ + return x * Inv (y); +} + +/// AutoDiff div double +template +inline AutoDiff operator/ (const AutoDiff & x, double y) +{ + return (1/y) * x; +} + +/// double div AutoDiff +template +inline AutoDiff operator/ (double x, const AutoDiff & y) +{ + return x * Inv(y); +} + + + + +template +inline AutoDiff fabs (const AutoDiff & x) +{ + double abs = fabs (x.Value()); + AutoDiff res( abs ); + if (abs != 0.0) + for (int i = 0; i < D; i++) + res.DValue(i) = x.DValue(i) / abs; + else + for (int i = 0; i < D; i++) + res.DValue(i) = 0.0; + return res; +} + +//@} + +#endif diff --git a/libsrc/general/autoptr.hpp b/libsrc/general/autoptr.hpp new file mode 100644 index 00000000..352a6105 --- /dev/null +++ b/libsrc/general/autoptr.hpp @@ -0,0 +1,36 @@ +#ifndef FILE_AUTOPTR +#define FILE_AUTOPTR + +/**************************************************************************/ +/* File: autoptr.hpp */ +/* Author: STL, Joachim Schoeberl */ +/* Date: 29. Dec. 02 */ +/**************************************************************************/ + +namespace netgen +{ + +template +class AutoPtr +{ +private: + T * ptr; +public: + typedef T* pT; + explicit AutoPtr (T * p = 0) { ptr = p; } + ~AutoPtr () { delete ptr; } + + T & operator*() const { return *ptr; } + T* operator->() const { return ptr; } + T *& Ptr() { return ptr; } + T * Ptr() const { return ptr; } + void Reset(T * p = 0) { if (p != ptr) { delete ptr; ptr = p; } } + operator bool () { return ptr != 0; } +private: + AutoPtr (AutoPtr &) { ; } + AutoPtr & operator= (AutoPtr &) { ; } +}; + +} + +#endif diff --git a/libsrc/general/bitarray.cpp b/libsrc/general/bitarray.cpp new file mode 100644 index 00000000..1c36e5fc --- /dev/null +++ b/libsrc/general/bitarray.cpp @@ -0,0 +1,132 @@ +/**************************************************************************/ +/* File: bitarray.cc */ +/* Autho: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + data type BitArray +*/ + +#include +#include + + +namespace netgen +{ + //using namespace netgen; + + BitArray :: BitArray () + { + size = 0; + data = NULL; + } + + BitArray :: BitArray (int asize) + { + size = 0; + data = NULL; + SetSize (asize); + } + + BitArray :: ~BitArray () + { + delete [] data; + } + + void BitArray :: SetSize (int asize) + { + if (size == asize) return; + delete [] data; + + size = asize; + data = new unsigned char [Addr (size)+1]; + } + + void BitArray :: Set () + { + if (!size) return; + for (int i = 0; i <= Addr (size); i++) + data[i] = UCHAR_MAX; + } + + void BitArray :: Clear () + { + if (!size) return; + for (int i = 0; i <= Addr (size); i++) + data[i] = 0; + } + + + + void BitArray :: Invert () + { + if (!size) return; + for (int i = 0; i <= Addr (size); i++) + data[i] ^= 255; + } + + void BitArray :: And (const BitArray & ba2) + { + if (!size) return; + for (int i = 0; i <= Addr (size); i++) + data[i] &= ba2.data[i]; + } + + + void BitArray :: Or (const BitArray & ba2) + { + if (!size) return; + for (int i = 0; i <= Addr (size); i++) + data[i] |= ba2.data[i]; + } + + + + + + + + + + + + template + void BitArrayChar :: Set () + { + data = 1; + } + + template + void BitArrayChar :: Clear () + { + data = 0; + } + + + template + void BitArrayChar :: Invert () + { + for (int i = BASE; i < data.Size()+BASE; i++) + data[i] = 1 - data[i]; + } + + template + void BitArrayChar :: And (const BitArrayChar & ba2) + { + for (int i = BASE; i < data.Size()+BASE; i++) + data[i] &= ba2.data[i]; + } + + + template + void BitArrayChar :: Or (const BitArrayChar & ba2) + { + for (int i = BASE; i < data.Size()+BASE; i++) + data[i] |= ba2.data[i]; + } + + + template class BitArrayChar<0>; + template class BitArrayChar<1>; +} diff --git a/libsrc/general/bitarray.hpp b/libsrc/general/bitarray.hpp new file mode 100644 index 00000000..64a4ee6e --- /dev/null +++ b/libsrc/general/bitarray.hpp @@ -0,0 +1,227 @@ +#ifndef FILE_BitArray +#define FILE_BitArray + +/**************************************************************************/ +/* File: bitarray.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +#include + +namespace netgen +{ + + +/** + data type BitArray + + BitArray is a compressed array of Boolean information. By Set and Clear + the whole array or one bit can be set or reset, respectively. + Test returns the state of the accoring bit. + No range checking is done. + + index ranges from 0 to size-1 +*/ +class BitArray +{ + INDEX size; + unsigned char * data; + +public: + BitArray (); + /// + BitArray (INDEX asize); + /// + ~BitArray (); + + /// + void SetSize (INDEX asize); + /// + INDEX Size () const + { + return size; + } + + /// + void Set (); + /// + void Set (INDEX i) + { + data[Addr(i)] |= Mask(i); + } + + void Clear (); + + + void Clear (INDEX i) + { + data[Addr(i)] &= ~Mask(i); + } + + bool Test (INDEX i) const + { + return (data[i / CHAR_BIT] & (char(1) << (i % CHAR_BIT) ) ) ? true : false; + } + + /// + void Invert (); + /// + void And (const BitArray & ba2); + /// + void Or (const BitArray & ba2); +private: + /// + inline unsigned char Mask (INDEX i) const + { + return char(1) << (i % CHAR_BIT); + } + /// + inline INDEX Addr (INDEX i) const + { + return (i / CHAR_BIT); + } + + /// + BitArray & operator= (BitArray &); + /// + BitArray (const BitArray &); +}; + + + +// print bitarray +inline ostream & operator<< (ostream & s, const BitArray & a) +{ + for (int i = 1; i <= a.Size(); i++) + { + s << int (a.Test(i)); + if (i % 40 == 0) s << "\n"; + } + if (a.Size() % 40 != 0) s << "\n"; + return s; +} + + +/* +inline +INDEX BitArray :: Size () const + { + return size; + } + +inline +unsigned char BitArray :: Mask (INDEX i) const + { + return char(1) << (i % CHAR_BIT); + } + +inline +INDEX BitArray :: Addr (INDEX i) const + { + return (i / CHAR_BIT); + } +inline +void BitArray :: Set (INDEX i) + { + data[Addr(i)] |= Mask(i); + } + +inline +void BitArray :: Clear (INDEX i) + { + data[Addr(i)] &= ~Mask(i); + } + + +inline +int BitArray :: Test (INDEX i) const + { + return (data[i / CHAR_BIT] & (char(1) << (i % CHAR_BIT) ) ) ? 1 : 0; + } + +*/ + + + + + + +/** + data type BitArrayChar + + BitArray is an array of Boolean information. By Set and Clear + the whole array or one bit can be set or reset, respectively. + Test returns the state of the accoring bit. + No range checking is done. +*/ +template +class BitArrayChar +{ + /// + Array data; + +public: + /// + BitArrayChar () + { ; } + /// + BitArrayChar (int asize) + : data(asize) + { ; } + /// + ~BitArrayChar () + { ; } + + /// + void SetSize (int asize) + { data.SetSize(asize); } + + /// + inline int Size () const + { return data.Size(); } + + /// + void Set (); + /// + inline void Set (int i) + { data[i] = 1; } + /// + void Clear (); + /// + inline void Clear (int i) + { data[i] = 0; } + /// + inline int Test (int i) const + { return data[i]; } + /// + void Invert (); + /// + void And (const BitArrayChar & ba2); + /// + void Or (const BitArrayChar & ba2); +private: + /// copy bitarray is not supported + BitArrayChar & operator= (BitArrayChar &) { return *this; } + /// copy bitarray is not supported + BitArrayChar (const BitArrayChar &) { ; } +}; + + + + +template +inline ostream & operator<< (ostream & s, const BitArrayChar & a) +{ + for (int i = BASE; i < a.Size()+BASE; i++) + { + s << a.Test(i); + if ( (i-BASE) % 40 == 39) s << "\n"; + } + if (a.Size() % 40 != 0) s << "\n"; + return s; +} + +} + +#endif diff --git a/libsrc/general/dynamicmem.cpp b/libsrc/general/dynamicmem.cpp new file mode 100644 index 00000000..ec58b3d4 --- /dev/null +++ b/libsrc/general/dynamicmem.cpp @@ -0,0 +1,202 @@ +#include + +using namespace std; + +namespace netgen +{ + + BaseDynamicMem * BaseDynamicMem::first = 0; + BaseDynamicMem * BaseDynamicMem::last = 0; + + + BaseDynamicMem :: BaseDynamicMem () + { + prev = last; + next = 0; + + if (last) last->next = this; + last = this; + if (!first) first = this; + + size = 0; + ptr = 0; + name = 0; + } + + BaseDynamicMem :: ~BaseDynamicMem () + { + Free(); + + if (next) next->prev = prev; + else last = prev; + if (prev) prev->next = next; + else first = next; + + delete [] name; + } + + void BaseDynamicMem :: SetName (const char * aname) + { + delete [] name; + name = NULL; + if (aname) + { + name = new char[strlen(aname)+1]; + strcpy (name, aname); + } + } + + + void BaseDynamicMem :: Alloc (size_t s) + { + size = s; + ptr = new char[s]; + + if (!ptr) + { + cerr << "BaseynamicMem, cannot allocate " << s << " bytes" << endl; + Print (); + throw ("BaseDynamicMem::Alloc: out of memory"); + } + // ptr = (char*)malloc (s); + // ptr = (char*) _mm_malloc (s,16); + } + + void BaseDynamicMem :: ReAlloc (size_t s) + { + if (size == s) return; + + char * old = ptr; + ptr = new char[s]; + + if (!ptr) + { + cerr << "BaseynamicMem, cannot Reallocate " << s << " bytes" << endl; + Print (); + throw ("BaseDynamicMem::Alloc: out of memory"); + } + + + // ptr = (char*)malloc(s); + // ptr = (char*) _mm_malloc (s,16); + memmove (ptr, old, (s < size) ? s : size); + delete [] old; + // free (old); + // _mm_free (old); + size = s; + } + + void BaseDynamicMem :: Free () + { + delete [] ptr; + // free (ptr); + // _mm_free (ptr); + ptr = 0; + } + + void BaseDynamicMem :: Swap (BaseDynamicMem & m2) + { + size_t hi; + char * cp; + hi = size; size = m2.size; m2.size = hi; + cp = ptr; ptr = m2.ptr; m2.ptr = cp; + cp = name; name = m2.name; m2.name = cp; + } + + + void BaseDynamicMem :: Print () + { + cout << "****************** Dynamic Mem Report ****************" << endl; + BaseDynamicMem * p = first; + size_t mem = 0; + int cnt = 0; + while (p) + { + mem += p->size; + cnt++; + + cout << setw(10) << p->size << " Bytes"; + cout << ", addr = " << (void*)p->ptr; + if (p->name) + cout << " in block " << p->name; + cout << endl; + + p = p->next; + } + + if (mem > 100000000) + cout << "memory in dynamic memory: " << mem/1048576 << " MB" << endl; + else if (mem > 100000) + cout << "memory in dynamic memory: " << mem/1024 << " kB" << endl; + else + cout << "memory in dynamic memory: " << mem << " Bytes" << endl; + cout << "number of blocks: " << cnt << endl; + // cout << "******************************************************" << endl; + } + + +#ifdef __INTEL_COMPILER +#pragma warning(push) +#pragma warning(disable:1684) +#endif + + void BaseDynamicMem :: GetUsed (int nr, char * ch) + { + BaseDynamicMem * p = first; + + for (int i = 0; i < nr; i++) + ch[i] = '0'; + + while (p) + { + long unsigned hptr = (long unsigned) (p->ptr); + // uintptr_t hptr = reinterpret_cast(p->ptr); //?? + + hptr /= (1024*1024); + hptr /= (4096/nr); + + size_t blocks = p->size / (1024*1024); + blocks /= (4096/nr); + + // cout << "ptr = " << (void*)(p->ptr) << ", size = " << p->size << ", hptr = " << hptr << " blocks = " << blocks << endl; + + for (size_t i = 0; i <= blocks; i++) + ch[hptr+i] = '1'; + + p = p->next; + } + + { + + /* + BaseMoveableMem * pm = BaseMoveableMem::first; + while (pm) + { + long unsigned hptr = (long unsigned) pm->ptr; + // uintptr_t hptr = reinterpret_cast(pm->ptr); + + hptr /= (1024*1024); + hptr /= (4096/nr); + + size_t blocks = pm->size / (1024*1024); + blocks /= (4096/nr); + + // cout << "moveable, ptr = " << (void*)(pm->ptr) << ", size = " << pm->size << ", hptr = " << hptr << " blocks = " << blocks << endl; + + for (size_t i = 0; i <= blocks; i++) + ch[hptr+i] = '1'; + + pm = pm->next; + } + */ + } + + + + } + +#ifdef __INTEL_COMPILER +#pragma warning(pop) +#endif + +} diff --git a/libsrc/general/dynamicmem.hpp b/libsrc/general/dynamicmem.hpp new file mode 100644 index 00000000..089a124d --- /dev/null +++ b/libsrc/general/dynamicmem.hpp @@ -0,0 +1,100 @@ +#ifndef FILE_DYNAMICMEM +#define FILE_DYNAMICMEM + +/**************************************************************************/ +/* File: dynamicmem.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 12. Feb. 2003 */ +/**************************************************************************/ + +namespace netgen +{ + + +class BaseDynamicMem +{ +private: + static BaseDynamicMem *first, *last; + + BaseDynamicMem *prev, *next; + size_t size; + char * ptr; + char * name; + +protected: + BaseDynamicMem (); + ~BaseDynamicMem (); + void Alloc (size_t s); + void ReAlloc (size_t s); + void Free (); + // char * Ptr() { return ptr; } + char * Ptr() const { return ptr; } + void Swap (BaseDynamicMem & m2); +public: + void SetName (const char * aname); + static void Print (); + static void GetUsed (int nr, char * ch); +}; + + +template +class DynamicMem : public BaseDynamicMem +{ +public: + DynamicMem () + : BaseDynamicMem () + { + ; + } + DynamicMem (size_t s) + : BaseDynamicMem () + { + Alloc (s); + } + void Alloc (size_t s) + { + BaseDynamicMem::Alloc (sizeof(T) * s); + } + void ReAlloc (size_t s) + { + BaseDynamicMem::ReAlloc (sizeof(T) * s); + } + void Free () + { + BaseDynamicMem::Free (); + } + + /* + const T * Ptr() const + { + return reinterpret_cast (BaseDynamicMem::Ptr()); + } + */ + const T * Ptr() + { + return reinterpret_cast (BaseDynamicMem::Ptr()); + } + + /* + operator const T* () const + { + return reinterpret_cast (BaseDynamicMem::Ptr()); + } + */ + operator T* () const + { + return reinterpret_cast (BaseDynamicMem::Ptr()); + } + + void Swap (DynamicMem & m2) + { + BaseDynamicMem::Swap (m2); + } +protected: + DynamicMem (const DynamicMem & m); + DynamicMem & operator= (const DynamicMem & m); +}; + +} + +#endif diff --git a/libsrc/general/flags.cpp b/libsrc/general/flags.cpp new file mode 100644 index 00000000..e5916f87 --- /dev/null +++ b/libsrc/general/flags.cpp @@ -0,0 +1,330 @@ +/**************************************************************************/ +/* File: flags.cc */ +/* Author: Joachim Schoeberl */ +/* Date: 10. Oct. 96 */ +/**************************************************************************/ + +/* + Datatype Flags +*/ + +#include +#include + +namespace netgen +{ + //using namespace netgen; + + Flags :: Flags () + { + ; + } + + Flags :: ~Flags () + { + DeleteFlags (); + } + + void Flags :: DeleteFlags () + { + for (int i = 0; i < strflags.Size(); i++) + delete [] strflags[i]; + for (int i = 0; i < numlistflags.Size(); i++) + delete numlistflags[i]; + strflags.DeleteAll(); + numflags.DeleteAll(); + defflags.DeleteAll(); + strlistflags.DeleteAll(); + numlistflags.DeleteAll(); + } + + void Flags :: SetFlag (const char * name, const char * val) + { + char * hval = new char[strlen (val) + 1]; + strcpy (hval, val); + strflags.Set (name, hval); + } + + void Flags :: SetFlag (const char * name, double val) + { + numflags.Set (name, val); + } + + void Flags :: SetFlag (const char * name) + { + defflags.Set (name, 1); + } + + + void Flags :: SetFlag (const char * name, const Array & val) + { + Array * strarray = new Array; + for (int i = 1; i <= val.Size(); i++) + { + strarray->Append (new char[strlen(val.Get(i))+1]); + strcpy (strarray->Last(), val.Get(i)); + } + strlistflags.Set (name, strarray); + } + + void Flags :: SetFlag (const char * name, const Array & val) + { + Array * numarray = new Array; + for (int i = 1; i <= val.Size(); i++) + numarray->Append (val.Get(i)); + numlistflags.Set (name, numarray); + } + + + + + + const char * + Flags :: GetStringFlag (const char * name, const char * def) const + { + if (strflags.Used (name)) + return strflags.Get(name); + else + return def; + } + + double Flags :: GetNumFlag (const char * name, double def) const + { + if (numflags.Used (name)) + return numflags.Get(name); + else + return def; + } + + const double * Flags :: GetNumFlagPtr (const char * name) const + { + if (numflags.Used (name)) + return & ((SYMBOLTABLE&)numflags).Elem(name); + else + return NULL; + } + + double * Flags :: GetNumFlagPtr (const char * name) + { + if (numflags.Used (name)) + return & ((SYMBOLTABLE&)numflags).Elem(name); + else + return NULL; + } + + bool Flags :: GetDefineFlag (const char * name) const + { + return defflags.Used (name); + } + + + const Array & + Flags :: GetStringListFlag (const char * name) const + { + if (strlistflags.Used (name)) + return *strlistflags.Get(name); + else + { + static Array dummy_array(0); + return dummy_array; + } + } + + const Array & + Flags ::GetNumListFlag (const char * name) const + { + if (numlistflags.Used (name)) + return *numlistflags.Get(name); + else + { + static Array dummy_array(0); + return dummy_array; + } + } + + + bool Flags :: StringFlagDefined (const char * name) const + { + return strflags.Used (name); + } + + bool Flags :: NumFlagDefined (const char * name) const + { + return numflags.Used (name); + } + + bool Flags :: StringListFlagDefined (const char * name) const + { + return strlistflags.Used (name); + } + + bool Flags :: NumListFlagDefined (const char * name) const + { + return numlistflags.Used (name); + } + + + void Flags :: SaveFlags (const char * filename) const + { + int i; + ofstream outfile (filename); + + for (i = 1; i <= strflags.Size(); i++) + outfile << strflags.GetName(i) << " = " << strflags.Get(i) << endl; + for (i = 1; i <= numflags.Size(); i++) + outfile << numflags.GetName(i) << " = " << numflags.Get(i) << endl; + for (i = 1; i <= defflags.Size(); i++) + outfile << defflags.GetName(i) << endl; + } + + + + void Flags :: PrintFlags (ostream & ost) const + { + int i; + + for (i = 1; i <= strflags.Size(); i++) + ost << strflags.GetName(i) << " = " << strflags.Get(i) << endl; + for (i = 1; i <= numflags.Size(); i++) + ost << numflags.GetName(i) << " = " << numflags.Get(i) << endl; + for (i = 1; i <= defflags.Size(); i++) + ost << defflags.GetName(i) << endl; + } + + + void Flags :: LoadFlags (const char * filename) + { + char name[100], str[100]; + char ch; + double val; + ifstream infile(filename); + + // (*logout) << "Load flags from " << filename << endl << endl; + while (infile.good()) + { + infile >> name; + if (strlen (name) == 0) break; + + if (name[0] == '/' && name[1] == '/') + { + // (*logout) << "comment: "; + ch = 0; + while (ch != '\n' && infile.good()) + { + ch = infile.get(); + // (*logout) << ch; + } + continue; + } + + // (*logout) << name; + ch = 0; + infile >> ch; + if (ch != '=') + { + // (*logout) << endl; + infile.putback (ch); + SetFlag (name); + } + else + { + infile >> val; + if (!infile.good()) + { + infile.clear(); + infile >> str; + SetFlag (name, str); + // (*logout) << " = " << str << endl; + } + else + { + SetFlag (name, val); + // (*logout) << " = " << val << endl; + } + } + } + // (*logout) << endl; + } + + + void Flags :: SetCommandLineFlag (const char * st) + { + // cout << "clflag = " << st << endl; + istringstream inst( (char *)st); + // istrstream defined with char * (not const char * ?????) + + char name[100]; + double val; + + + if (st[0] != '-') + { + cerr << "flag must start with '-'" << endl; + return; + } + + const char * pos = strchr (st, '='); + + if (!pos) + { + // (cout) << "Add def flag: " << st+1 << endl; + SetFlag (st+1); + } + else + { + // cout << "pos = " << pos << endl; + + strncpy (name, st+1, (pos-st)-1); + name[pos-st-1] = 0; + + // cout << "name = " << name << endl; + + pos++; + char * endptr = NULL; + + val = strtod (pos, &endptr); + + // cout << "val = " << val << endl; + + if (endptr == pos) + { + // (cout) << "Add String Flag: " << name << " = " << pos << endl; + SetFlag (name, pos); + } + else + { + // (cout) << "Add Num Flag: " << name << " = " << val << endl; + SetFlag (name, val); + } + } + + + /* + inst >> name; + (*mycout) << "name = " << name << endl; + + ch = 0; + inst >> ch; + if (ch != '=') + { + SetFlag (name); + } + else + { + inst >> val; + if (!inst.good()) + { + inst.clear(); + inst >> str; + SetFlag (name, str); + (*mycout) << "str = " << str << endl; + } + else + { + SetFlag (name, val); + (*mycout) << "val = " << val << endl; + } + } + */ + } +} diff --git a/libsrc/general/flags.hpp b/libsrc/general/flags.hpp new file mode 100644 index 00000000..810fbfbe --- /dev/null +++ b/libsrc/general/flags.hpp @@ -0,0 +1,88 @@ +#ifndef FILE_FLAGS +#define FILE_FLAGS + + +/**************************************************************************/ +/* File: flags.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 10. Oct. 96 */ +/**************************************************************************/ + +namespace netgen +{ + +/** + Flag - Table. + A flag table maintains string variables, numerical + variables and boolean flags. +*/ +class Flags +{ + /// + SYMBOLTABLE strflags; + /// + SYMBOLTABLE numflags; + /// + SYMBOLTABLE defflags; + /// + SYMBOLTABLE*> strlistflags; + /// + SYMBOLTABLE*> numlistflags; +public: + /// + DLL_HEADER Flags (); + /// + DLL_HEADER ~Flags (); + + /// Deletes all flags + DLL_HEADER void DeleteFlags (); + /// Sets string flag, overwrite if exists + DLL_HEADER void SetFlag (const char * name, const char * val); + /// Sets numerical flag, overwrite if exists + DLL_HEADER void SetFlag (const char * name, double val); + /// Sets boolean flag + DLL_HEADER void SetFlag (const char * name); + /// Sets string arary falg + DLL_HEADER void SetFlag (const char * name, const Array & val); + /// Sets double array flag + DLL_HEADER void SetFlag (const char * name, const Array & val); + + /// Save flags to file + DLL_HEADER void SaveFlags (const char * filename) const; + /// write flags to stream + DLL_HEADER void PrintFlags (ostream & ost) const; + /// Load flags from file + DLL_HEADER void LoadFlags (const char * filename); + /// set flag of form -name=hello -val=0.5 -defined + DLL_HEADER void SetCommandLineFlag (const char * st); + + /// Returns string flag, default value if not exists + DLL_HEADER const char * GetStringFlag (const char * name, const char * def) const; + /// Returns numerical flag, default value if not exists + DLL_HEADER double GetNumFlag (const char * name, double def) const; + /// Returns address of numerical flag, null if not exists + DLL_HEADER const double * GetNumFlagPtr (const char * name) const; + /// Returns address of numerical flag, null if not exists + DLL_HEADER double * GetNumFlagPtr (const char * name); + /// Returns boolean flag + DLL_HEADER bool GetDefineFlag (const char * name) const; + /// Returns string list flag, empty array if not exist + DLL_HEADER const Array & GetStringListFlag (const char * name) const; + /// Returns num list flag, empty array if not exist + DLL_HEADER const Array & GetNumListFlag (const char * name) const; + + + /// Test, if string flag is defined + DLL_HEADER bool StringFlagDefined (const char * name) const; + /// Test, if num flag is defined + DLL_HEADER bool NumFlagDefined (const char * name) const; + /// Test, if string list flag is defined + DLL_HEADER bool StringListFlagDefined (const char * name) const; + /// Test, if num list flag is defined + DLL_HEADER bool NumListFlagDefined (const char * name) const; +}; + +} + +#endif + diff --git a/libsrc/general/gzstream.cpp b/libsrc/general/gzstream.cpp new file mode 100644 index 00000000..bbb4ba8a --- /dev/null +++ b/libsrc/general/gzstream.cpp @@ -0,0 +1,165 @@ +// ============================================================================ +// gzstream, C++ iostream classes wrapping the zlib compression library. +// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// ============================================================================ +// +// File : gzstream.C +// Revision : $Revision: 1.7 $ +// Revision_date : $Date: 2003/01/08 14:41:27 $ +// Author(s) : Deepak Bandyopadhyay, Lutz Kettner +// +// Standard streambuf implementation following Nicolai Josuttis, "The +// Standard C++ Library". +// ============================================================================ + +#include "gzstream.h" +#include +#include // for memcpy + +#ifdef GZSTREAM_NAMESPACE +namespace GZSTREAM_NAMESPACE { +#endif + +// ---------------------------------------------------------------------------- +// Internal classes to implement gzstream. See header file for user classes. +// ---------------------------------------------------------------------------- + +// -------------------------------------- +// class gzstreambuf: +// -------------------------------------- + +gzstreambuf* gzstreambuf::open( const char* name, int open_mode) { + if ( is_open()) + return (gzstreambuf*)0; + mode = open_mode; + // no append nor read/write mode + if ((mode & std::ios::ate) || (mode & std::ios::app) + || ((mode & std::ios::in) && (mode & std::ios::out))) + return (gzstreambuf*)0; + char fmode[10]; + char* fmodeptr = fmode; + if ( mode & std::ios::in) + *fmodeptr++ = 'r'; + else if ( mode & std::ios::out) + *fmodeptr++ = 'w'; + *fmodeptr++ = 'b'; + *fmodeptr = '\0'; + file = gzopen( name, fmode); + if (file == 0) + return (gzstreambuf*)0; + opened = 1; + return this; +} + +gzstreambuf * gzstreambuf::close() { + if ( is_open()) { + sync(); + opened = 0; + if ( gzclose( file) == Z_OK) + return this; + } + return (gzstreambuf*)0; +} + +int gzstreambuf::underflow() { // used for input buffer only + if ( gptr() && ( gptr() < egptr())) + return * reinterpret_cast( gptr()); + + if ( ! (mode & std::ios::in) || ! opened) + return EOF; + // Josuttis' implementation of inbuf + int n_putback = gptr() - eback(); + if ( n_putback > 4) + n_putback = 4; + memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback); + + int num = gzread( file, buffer+4, bufferSize-4); + if (num <= 0) // ERROR or EOF + return EOF; + + // reset buffer pointers + setg( buffer + (4 - n_putback), // beginning of putback area + buffer + 4, // read position + buffer + 4 + num); // end of buffer + + // return next character + return * reinterpret_cast( gptr()); +} + +int gzstreambuf::flush_buffer() { + // Separate the writing of the buffer from overflow() and + // sync() operation. + int w = pptr() - pbase(); + if ( gzwrite( file, pbase(), w) != w) + return EOF; + pbump( -w); + return w; +} + +int gzstreambuf::overflow( int c) { // used for output buffer only + if ( ! ( mode & std::ios::out) || ! opened) + return EOF; + if (c != EOF) { + *pptr() = c; + pbump(1); + } + if ( flush_buffer() == EOF) + return EOF; + return c; +} + +int gzstreambuf::sync() { + // Changed to use flush_buffer() instead of overflow( EOF) + // which caused improper behavior with std::endl and flush(), + // bug reported by Vincent Ricard. + if ( pptr() && pptr() > pbase()) { + if ( flush_buffer() == EOF) + return -1; + } + return 0; +} + +// -------------------------------------- +// class gzstreambase: +// -------------------------------------- + +gzstreambase::gzstreambase( const char* name, int mode) { + init( &buf); + open( name, mode); +} + +gzstreambase::~gzstreambase() { + buf.close(); +} + +void gzstreambase::open( const char* name, int open_mode) { + if ( ! buf.open( name, open_mode)) + clear( rdstate() | std::ios::badbit); +} + +void gzstreambase::close() { + if ( buf.is_open()) + if ( ! buf.close()) + clear( rdstate() | std::ios::badbit); +} + +#ifdef GZSTREAM_NAMESPACE +} // namespace GZSTREAM_NAMESPACE +#endif + +// ============================================================================ +// EOF // diff --git a/libsrc/general/gzstream.h b/libsrc/general/gzstream.h new file mode 100644 index 00000000..861653f4 --- /dev/null +++ b/libsrc/general/gzstream.h @@ -0,0 +1,121 @@ +// ============================================================================ +// gzstream, C++ iostream classes wrapping the zlib compression library. +// Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// ============================================================================ +// +// File : gzstream.h +// Revision : $Revision: 1.5 $ +// Revision_date : $Date: 2002/04/26 23:30:15 $ +// Author(s) : Deepak Bandyopadhyay, Lutz Kettner +// +// Standard streambuf implementation following Nicolai Josuttis, "The +// Standard C++ Library". +// ============================================================================ + +#ifndef GZSTREAM_H +#define GZSTREAM_H 1 + +// standard C++ with new header file names and std:: namespace +#include +#include +#include + +#ifdef GZSTREAM_NAMESPACE +namespace GZSTREAM_NAMESPACE { +#endif + +// ---------------------------------------------------------------------------- +// Internal classes to implement gzstream. See below for user classes. +// ---------------------------------------------------------------------------- + +class gzstreambuf : public std::streambuf { +private: + static const int bufferSize = 47+256; // size of data buff + // totals 512 bytes under g++ for igzstream at the end. + + gzFile file; // file handle for compressed file + char buffer[bufferSize]; // data buffer + char opened; // open/close state of stream + int mode; // I/O mode + + int flush_buffer(); +public: + gzstreambuf() : opened(0) { + setp( buffer, buffer + (bufferSize-1)); + setg( buffer + 4, // beginning of putback area + buffer + 4, // read position + buffer + 4); // end position + // ASSERT: both input & output capabilities will not be used together + } + int is_open() { return opened; } + gzstreambuf* open( const char* name, int open_mode); + gzstreambuf* close(); + ~gzstreambuf() { close(); } + + virtual int overflow( int c = EOF); + virtual int underflow(); + virtual int sync(); +}; + +class gzstreambase : virtual public std::ios { +protected: + gzstreambuf buf; +public: + gzstreambase() { init(&buf); } + gzstreambase( const char* name, int open_mode); + ~gzstreambase(); + void open( const char* name, int open_mode); + void close(); + gzstreambuf* rdbuf() { return &buf; } +}; + +// ---------------------------------------------------------------------------- +// User classes. Use igzstream and ogzstream analogously to ifstream and +// ofstream respectively. They read and write files based on the gz* +// function interface of the zlib. Files are compatible with gzip compression. +// ---------------------------------------------------------------------------- + +class igzstream : public gzstreambase, public std::istream { +public: + igzstream() : std::istream( &buf) {} + igzstream( const char* name, int open_mode = std::ios::in) + : gzstreambase( name, open_mode), std::istream( &buf) {} + gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } + void open( const char* name, int open_mode = std::ios::in) { + gzstreambase::open( name, open_mode); + } +}; + +class ogzstream : public gzstreambase, public std::ostream { +public: + ogzstream() : std::ostream( &buf) {} + ogzstream( const char* name, int mode = std::ios::out) + : gzstreambase( name, mode), std::ostream( &buf) {} + gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } + void open( const char* name, int open_mode = std::ios::out) { + gzstreambase::open( name, open_mode); + } +}; + +#ifdef GZSTREAM_NAMESPACE +} // namespace GZSTREAM_NAMESPACE +#endif + +#endif // GZSTREAM_H +// ============================================================================ +// EOF // + diff --git a/libsrc/general/hashtabl.cpp b/libsrc/general/hashtabl.cpp new file mode 100644 index 00000000..36caf12f --- /dev/null +++ b/libsrc/general/hashtabl.cpp @@ -0,0 +1,326 @@ +/**************************************************************************/ +/* File: hashtabl.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Abstract data type HASHTABLE +*/ + +#include +#include +#include + +namespace netgen +{ + //using namespace netgen; + + void INDEX_4 :: Sort () + { + if (i[0] > i[1]) Swap (i[0], i[1]); + if (i[2] > i[3]) Swap (i[2], i[3]); + if (i[0] > i[2]) Swap (i[0], i[2]); + if (i[1] > i[3]) Swap (i[1], i[3]); + if (i[1] > i[2]) Swap (i[1], i[2]); + } + + + + void INDEX_4Q :: Sort () + { + if (min2 (i[1], i[2]) < min2 (i[0], i[3])) + { Swap (i[0], i[1]); Swap (i[2], i[3]);} + if (i[3] < i[0]) + { Swap (i[0], i[3]); Swap (i[1], i[2]);} + if (i[3] < i[1]) + { Swap (i[1], i[3]); } + } + + + ostream & operator<<(ostream & s, const INDEX_2 & i2) + { + return s << i2.I1() << ", " << i2.I2(); + } + + ostream & operator<<(ostream & s, const INDEX_3 & i3) + { + return s << i3.I1() << ", " << i3.I2() << ", " << i3.I3(); + } + + ostream & operator<<(ostream & s, const INDEX_4 & i4) + { + return s << i4.I1() << ", " << i4.I2() << ", " << i4.I3() << ", " << i4.I4(); + } + + ostream & operator<<(ostream & s, const INDEX_4Q & i4) + { + return s << i4.I1() << ", " << i4.I2() << ", " << i4.I3() << ", " << i4.I4(); + } + + + int BASE_INDEX_HASHTABLE :: Position (int bnr, const INDEX & ind) const + { + for (int i = 1; i <= hash.EntrySize (bnr); i++) + if (hash.Get(bnr, i) == ind) + return i; + return 0; + } + + + + /* + int BASE_INDEX_2_HASHTABLE :: Position (int bnr, const INDEX_2 & ind) const + { + int i; + for (i = 1; i <= hash.EntrySize (bnr); i++) + if (hash.Get(bnr, i) == ind) + return i; + return 0; + } + */ + + void BASE_INDEX_2_HASHTABLE :: PrintStat (ostream & ost) const + { + int n = hash.Size(); + int i; + int sumn = 0, sumnn = 0; + + for (i = 1; i <= n; i++) + { + sumn += hash.EntrySize(i); + sumnn += sqr (hash.EntrySize(i)); + } + + ost << "Hashtable: " << endl + << "size : " << n << endl + << "elements per row : " << (double(sumn) / double(n)) << endl + << "av. acces time : " + << (sumn ? (double (sumnn) / double(sumn)) : 0) << endl; + } + + + /* + int BASE_INDEX_3_HASHTABLE :: Position (int bnr, const INDEX_3 & ind) const + { + int i; + const INDEX_3 * pi = &hash.Get(bnr, 1); + int n = hash.EntrySize(bnr); + for (i = 1; i <= n; ++i, ++pi) + { + if (*pi == ind) + return i; + } + + return 0; + } + */ + + + + + + + + + + + + + + + + + + + + + BASE_INDEX_CLOSED_HASHTABLE :: + BASE_INDEX_CLOSED_HASHTABLE (int size) + : hash(size) + { + // hash.SetName ("index-hashtable, hash"); + + invalid = -1; + for (int i = 1; i <= size; i++) + hash.Elem(i) = invalid; + } + + void BASE_INDEX_CLOSED_HASHTABLE :: + BaseSetSize (int size) + { + hash.SetSize(size); + for (int i = 1; i <= size; i++) + hash.Elem(i) = invalid; + } + + int BASE_INDEX_CLOSED_HASHTABLE :: + Position2 (const INDEX & ind) const + { + int i = HashValue(ind); + while (1) + { + i++; + if (i > hash.Size()) i = 1; + if (hash.Get(i) == ind) return i; + if (hash.Get(i) == invalid) return 0; + } + } + + int BASE_INDEX_CLOSED_HASHTABLE :: + PositionCreate2 (const INDEX & ind, int & apos) + { + int i = HashValue(ind); + int startpos = i; + while (1) + { + i++; + if (i > hash.Size()) i = 1; + if (hash.Get(i) == ind) + { + apos = i; + return 0; + } + if (hash.Get(i) == invalid) + { + hash.Elem(i) = ind; + apos = i; + return 1; + } + if (i == startpos) + throw NgException ("Try to set new element in full closed hashtable"); + } + } + + int BASE_INDEX_CLOSED_HASHTABLE :: UsedElements () const + { + int n = hash.Size(); + int cnt = 0; + for (int i = 1; i <= n; i++) + if (hash.Get(i) != invalid) + cnt++; + return cnt; + } + + + + + + + + + + + + BASE_INDEX_2_CLOSED_HASHTABLE :: + BASE_INDEX_2_CLOSED_HASHTABLE (int size) + : hash(size) + { + // hash.SetName ("i2-hashtable, hash"); + + invalid = -1; + for (int i = 1; i <= size; i++) + hash.Elem(i).I1() = invalid; + } + + void BASE_INDEX_2_CLOSED_HASHTABLE :: + BaseSetSize (int size) + { + hash.SetSize(size); + for (int i = 1; i <= size; i++) + hash.Elem(i).I1() = invalid; + } + + + int BASE_INDEX_2_CLOSED_HASHTABLE :: + Position2 (const INDEX_2 & ind) const + { + int i = HashValue(ind); + while (1) + { + i++; + if (i > hash.Size()) i = 1; + if (hash.Get(i) == ind) return i; + if (hash.Get(i).I1() == invalid) return 0; + } + } + + int BASE_INDEX_2_CLOSED_HASHTABLE :: + PositionCreate2 (const INDEX_2 & ind, int & apos) + { + int i = HashValue(ind); + int startpos = i; + while (1) + { + i++; + if (i > hash.Size()) i = 1; + if (hash.Get(i) == ind) + { + apos = i; + return 0; + } + if (hash.Get(i).I1() == invalid) + { + hash.Elem(i) = ind; + apos = i; + return 1; + } + if (i == startpos) + throw NgException ("Try to set new element in full closed hashtable"); + } + } + + int BASE_INDEX_2_CLOSED_HASHTABLE :: UsedElements () const + { + int n = hash.Size(); + int cnt = 0; + for (int i = 1; i <= n; i++) + if (hash.Get(i).I1() != invalid) + cnt++; + return cnt; + } + + + + + + + + + void BASE_INDEX_3_CLOSED_HASHTABLE :: + BaseSetSize (int size) + { + hash.SetSize(size); + for (int i = 0; i < size; i++) + hash[i].I1() = invalid; + } + + bool BASE_INDEX_3_CLOSED_HASHTABLE :: + PositionCreate2 (const INDEX_3 & ind, int & apos) + { + int i = HashValue(ind); + int startpos = i; + while (1) + { + /* + i++; + if (i >= hash.Size()) i = 0; + */ + i = (i+1) % hash.Size(); + if (hash[i] == ind) + { + apos = i; + return false; + } + if (hash[i].I1() == invalid) + { + hash[i] = ind; + apos = i; + return true; + } + if (i == startpos) + throw NgException ("Try to set new element in full closed hashtable"); + } + } +} + diff --git a/libsrc/general/hashtabl.hpp b/libsrc/general/hashtabl.hpp new file mode 100644 index 00000000..d05cdc83 --- /dev/null +++ b/libsrc/general/hashtabl.hpp @@ -0,0 +1,1369 @@ +#ifndef FILE_HASHTABL +#define FILE_HASHTABL + +/**************************************************************************/ +/* File: hashtabl.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +namespace netgen +{ + +/** + Abstract data type HASHTABLE. + Hash is done by one INDEX +*/ +class BASE_INDEX_HASHTABLE +{ +protected: + /// keys are stored in this table + TABLE hash; + +public: + /// + BASE_INDEX_HASHTABLE (int size) + : hash (size) { }; + +protected: + /// + int HashValue (const INDEX & ind) const + { + return ind % hash.Size() + 1; + } + + /// + int Position (int bnr, const INDEX & ind) const; +}; + +/// +template +class INDEX_HASHTABLE : private BASE_INDEX_HASHTABLE +{ + /// + TABLE cont; + +public: + /// + inline INDEX_HASHTABLE (int size); + /// + inline void Set (const INDEX & hash, const T & acont); + /// + inline const T & Get (const INDEX & ahash) const; + /// + inline bool Used (const INDEX & ahash) const; + /// + inline int GetNBags () const; + /// + inline int GetBagSize (int bnr) const; + /// + inline void GetData (int bnr, int colnr, INDEX & ahash, T & acont) const; + + /// + inline void PrintMemInfo (ostream & ost) const; +}; + + + + + + + + + + +/// +class BASE_INDEX_2_HASHTABLE +{ +protected: + /// + TABLE hash; + +public: + /// + BASE_INDEX_2_HASHTABLE (int size) + : hash (size) { }; + + /// + void PrintStat (ostream & ost) const; + void BaseSetSize(int s) {hash.SetSize(s);} + //protected: + /// + int HashValue (const INDEX_2 & ind) const + { + return (ind.I1() + ind.I2()) % hash.Size() + 1; + } + /// + int Position (int bnr, const INDEX_2 & ind) const + { + for (int i = 1; i <= hash.EntrySize (bnr); i++) + if (hash.Get(bnr, i) == ind) + return i; + return 0; + } +}; + + +/// +template +class INDEX_2_HASHTABLE : public BASE_INDEX_2_HASHTABLE +{ + /// + TABLE cont; + +public: + /// + INDEX_2_HASHTABLE (int size) + : BASE_INDEX_2_HASHTABLE (size), cont(size) + { ; } + + /// + void SetSize(int s) + { + cont.SetSize(s); + BaseSetSize(s); + } + + /// + void Set (const INDEX_2 & ahash, const T & acont) + { + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + if (pos) + cont.Set (bnr, pos, acont); + else + { + hash.Add1 (bnr, ahash); + cont.Add1 (bnr, acont); + } + } + + /// + const T & Get (const INDEX_2 & ahash) const + { + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + return cont.Get (bnr, pos); + } + + /// + bool Used (const INDEX_2 & ahash) const + { + return Position (HashValue (ahash), ahash) > 0; + } + /// + int GetNBags () const + { + return cont.Size(); + } + + /// + int GetBagSize (int bnr) const + { + return cont.EntrySize (bnr); + } + + /// + void GetData (int bnr, int colnr, + INDEX_2 & ahash, T & acont) const + { + ahash = hash.Get(bnr, colnr); + acont = cont.Get(bnr, colnr); + } + + /// + void SetData (int bnr, int colnr, + const INDEX_2 & ahash, const T & acont) + { + hash.Set(bnr, colnr, ahash); + cont.Set(bnr, colnr, acont); + } + + /// + void PrintMemInfo (ostream & ost) const + { + ost << "Hash: " << endl; + hash.PrintMemInfo (ost); + ost << "Cont: " << endl; + cont.PrintMemInfo (ost); + } + + + void DeleteData () + { + int n = hash.Size(); + hash.SetSize (n); + cont.SetSize (n); + } + + + class Iterator + { + const INDEX_2_HASHTABLE & ht; + int bagnr, pos; + public: + Iterator (const INDEX_2_HASHTABLE & aht, + int abagnr, int apos) + : ht(aht), bagnr(abagnr), pos(apos) + { ; } + + int BagNr() const { return bagnr; } + int Pos() const { return pos; } + + void operator++ (int) + { + // cout << "begin Operator ++: bagnr = " << bagnr << " - pos = " << pos << endl; + pos++; + while (bagnr < ht.GetNBags() && + pos == ht.GetBagSize(bagnr+1)) + { + pos = 0; + bagnr++; + } + // cout << "end Operator ++: bagnr = " << bagnr << " - pos = " << pos << endl; + } + + bool operator != (int i) const + { + return bagnr != i; + } + + }; + + Iterator Begin () const + { + Iterator it(*this, 0, -1); + it++; + return it; + } + + int End() const + { + return GetNBags(); + } + + void GetData (const Iterator & it, + INDEX_2 & ahash, T & acont) const + { + ahash = hash[it.BagNr()][it.Pos()]; + acont = cont[it.BagNr()][it.Pos()]; + } + + const INDEX_2 & GetHash (const Iterator & it) const + { return hash[it.BagNr()][it.Pos()]; } + + const T & GetData (const Iterator & it) const + { return cont[it.BagNr()][it.Pos()]; } +}; + + + +template +inline ostream & operator<< (ostream & ost, const INDEX_2_HASHTABLE & ht) +{ + for (typename INDEX_2_HASHTABLE::Iterator it = ht.Begin(); + it != ht.End(); it++) + { + ost << ht.GetHash(it) << ": " << ht.GetData(it) << endl; + } + + return ost; +} + + + + + + + +/// +class BASE_INDEX_3_HASHTABLE +{ +protected: + /// + TABLE hash; + +public: + /// + BASE_INDEX_3_HASHTABLE (int size) + : hash (size) { }; + +protected: + /// + int HashValue (const INDEX_3 & ind) const + { + return (ind.I1() + ind.I2() + ind.I3()) % hash.Size() + 1; + } + + /// + int Position (int bnr, const INDEX_3 & ind) const + { + const INDEX_3 * pi = &hash.Get(bnr, 1); + int n = hash.EntrySize(bnr); + for (int i = 1; i <= n; ++i, ++pi) + { + if (*pi == ind) + return i; + } + + return 0; + } + + +}; + + +/// +template +class INDEX_3_HASHTABLE : private BASE_INDEX_3_HASHTABLE +{ + /// + TABLE cont; + +public: + /// + inline INDEX_3_HASHTABLE (int size); + /// + inline void Set (const INDEX_3 & ahash, const T & acont); + /// + inline const T & Get (const INDEX_3 & ahash) const; + /// + inline bool Used (const INDEX_3 & ahash) const; + /// + inline int GetNBags () const; + /// + inline int GetBagSize (int bnr) const; + /// + inline void SetData (int bnr, int colnr, const INDEX_3 & ahash, const T & acont); + /// + inline void GetData (int bnr, int colnr, INDEX_3 & ahash, T & acont) const; + /// returns position, if not existing, will create (create == return 1) + inline int PositionCreate (const INDEX_3 & ahash, int & bnr, int & colnr); + /// + inline void SetSize (int size); + + /// + inline void PrepareSet (const INDEX_3 & ahash); + /// + inline void AllocateElements (); + + /// + inline void PrintMemInfo (ostream & ost) const; + /// + inline void DeleteData (); + + + + + + + + + + class Iterator + { + const INDEX_3_HASHTABLE & ht; + int bagnr, pos; + public: + Iterator (const INDEX_3_HASHTABLE & aht, + int abagnr, int apos) + : ht(aht), bagnr(abagnr), pos(apos) + { ; } + + int BagNr() const { return bagnr; } + int Pos() const { return pos; } + + void operator++ (int) + { + // cout << "begin Operator ++: bagnr = " << bagnr << " - pos = " << pos << endl; + pos++; + while (bagnr < ht.GetNBags() && + pos == ht.GetBagSize(bagnr+1)) + { + pos = 0; + bagnr++; + } + // cout << "end Operator ++: bagnr = " << bagnr << " - pos = " << pos << endl; + } + + bool operator != (int i) const + { + return bagnr != i; + } + + }; + + Iterator Begin () const + { + Iterator it(*this, 0, -1); + it++; + return it; + } + + int End() const + { + return GetNBags(); + } + + void GetData (const Iterator & it, + INDEX_3 & ahash, T & acont) const + { + ahash = hash[it.BagNr()][it.Pos()]; + acont = cont[it.BagNr()][it.Pos()]; + } + + const INDEX_3 & GetHash (const Iterator & it) const + { return hash[it.BagNr()][it.Pos()]; } + + const T & GetData (const Iterator & it) const + { return cont[it.BagNr()][it.Pos()]; } + + + +}; + + + + + + +template +inline ostream & operator<< (ostream & ost, const INDEX_3_HASHTABLE & ht) +{ + for (typename INDEX_3_HASHTABLE::Iterator it = ht.Begin(); + it != ht.End(); it++) + { + ost << ht.GetHash(it) << ": " << ht.GetData(it) << endl; + } + + return ost; +} + + + + + + + + + + + + + + + + + + + + + + + + +/// Closed Hashing HT + +class BASE_INDEX_CLOSED_HASHTABLE +{ +protected: + /// + // MoveableArray hash; + Array hash; + /// + int invalid; +public: + /// + BASE_INDEX_CLOSED_HASHTABLE (int size); + + int Size() const { return hash.Size(); } + int UsedPos (int pos) const { return ! (hash.Get(pos) == invalid); } + int UsedElements () const; + + /// + int HashValue (const INDEX & ind) const + { + return (3*ind) % hash.Size() + 1; + } + + + int Position (const INDEX & ind) const + { + int i = HashValue(ind); + while (1) + { + if (hash.Get(i) == ind) return i; + if (hash.Get(i) == invalid) return 0; + i++; + if (i > hash.Size()) i = 1; + } + } + + int CalcPositionCosts (const INDEX & ind) const + { + int i = HashValue(ind); + int costs = 1; + while (1) + { + if (hash.Get(i) == ind) return costs; + if (hash.Get(i) == invalid) return costs; + i++; + if (i > hash.Size()) i = 1; + costs++; + } + } + + + + // returns 1, if new postion is created + int PositionCreate (const INDEX & ind, int & apos) + { + int i = HashValue (ind); + if (hash.Get(i) == ind) + { + apos = i; + return 0; + } + if (hash.Get(i) == invalid) + { + hash.Elem(i) = ind; + apos = i; + return 1; + } + return PositionCreate2 (ind, apos); + } + +protected: + int Position2 (const INDEX & ind) const; + int PositionCreate2 (const INDEX & ind, int & apos); + void BaseSetSize (int asize); +}; + + +template +class INDEX_CLOSED_HASHTABLE : public BASE_INDEX_CLOSED_HASHTABLE +{ + /// +// MoveableArray cont; + Array cont; + +public: + /// + INDEX_CLOSED_HASHTABLE (int size) + : BASE_INDEX_CLOSED_HASHTABLE(size), cont(size) + { + ; // cont.SetName ("ind-hashtable, contents"); + } + + + void Set (const INDEX & ahash, const T & acont) + { + int pos; + PositionCreate (ahash, pos); + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; + } + + const T & Get (const INDEX & ahash) const + { + int pos = Position (ahash); + return cont.Get(pos); + } + + /// + bool Used (const INDEX & ahash) const + { + int pos = Position (ahash); + return (pos != 0); + } + + + /// + inline void SetData (int pos, const INDEX & ahash, const T & acont) + { + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; + } + + /// + void GetData (int pos, INDEX & ahash, T & acont) const + { + ahash = hash.Get(pos); + acont = cont.Get(pos); + } + + /// + inline void SetData (int pos, const T & acont) + { + cont.Elem(pos) = acont; + } + + /// + void GetData (int pos, T & acont) const + { + acont = cont.Get(pos); + } + + /// + const T & GetData (int pos) { return cont.Get(pos); } + /// + inline void SetSize (int size) + { + BaseSetSize(size); + cont.SetSize(size); + } + + /// + inline void DeleteData () + { SetSize (cont.Size()); } + + void SetName (const char * aname) + { + // cont.SetName(aname); + // hash.SetName(aname); + } +}; + + + + + + + +/// Closed Hashing HT + +class BASE_INDEX_2_CLOSED_HASHTABLE +{ +protected: + /// + // MoveableArray hash; + Array hash; + /// + int invalid; +public: + /// + BASE_INDEX_2_CLOSED_HASHTABLE (int size); + + int Size() const { return hash.Size(); } + int UsedPos (int pos) const { return ! (hash.Get(pos).I1() == invalid); } + int UsedElements () const; + + /// + int HashValue (const INDEX_2 & ind) const + { + return (ind.I1() + 71 * ind.I2()) % hash.Size() + 1; + } + + + int Position (const INDEX_2 & ind) const + { + int i = HashValue(ind); + while (1) + { + if (hash.Get(i) == ind) return i; + if (hash.Get(i).I1() == invalid) return 0; + i++; + if (i > hash.Size()) i = 1; + } + } + + // returns 1, if new postion is created + int PositionCreate (const INDEX_2 & ind, int & apos) + { + int i = HashValue (ind); + if (hash.Get(i) == ind) + { + apos = i; + return 0; + } + if (hash.Get(i).I1() == invalid) + { + hash.Elem(i) = ind; + apos = i; + return 1; + } + return PositionCreate2 (ind, apos); + } + +protected: + /// + + int Position2 (const INDEX_2 & ind) const; + int PositionCreate2 (const INDEX_2 & ind, int & apos); + void BaseSetSize (int asize); +}; + + +template +class INDEX_2_CLOSED_HASHTABLE : public BASE_INDEX_2_CLOSED_HASHTABLE +{ + /// +// MoveableArray cont; + Array cont; + +public: + /// + inline INDEX_2_CLOSED_HASHTABLE (int size); + /// + inline void Set (const INDEX_2 & ahash, const T & acont); + /// + inline const T & Get (const INDEX_2 & ahash) const; + /// + inline bool Used (const INDEX_2 & ahash) const; + /// + inline void SetData (int pos, const INDEX_2 & ahash, const T & acont); + /// + inline void GetData (int pos, INDEX_2 & ahash, T & acont) const; + /// + inline void SetData (int pos, const T & acont); + /// + inline void GetData (int pos, T & acont) const; + /// + const T & GetData (int pos) { return cont.Get(pos); } + /// + inline void SetSize (int size); + /// + inline void PrintMemInfo (ostream & ost) const; + /// + inline void DeleteData () + { SetSize (cont.Size()); } + + void SetName (const char * aname) + { + ; + // cont.SetName(aname); + // hash.SetName(aname); + } +}; + + + +template +inline ostream & operator<< (ostream & ost, const INDEX_2_CLOSED_HASHTABLE & ht) +{ + for (int i = 0; i < ht.Size(); i++) + if (ht.UsedPos(i)) + { + INDEX_2 hash; + T data; + ht.GetData (i, hash, data); + ost << "hash = " << hash << ", data = " << data << endl; + } + return ost; +} + + + + + + +class BASE_INDEX_3_CLOSED_HASHTABLE +{ +protected: + // MoveableArray hash; + Array hash; + int invalid; + +protected: + BASE_INDEX_3_CLOSED_HASHTABLE (int size) + : hash(size) + { + // hash.SetName ("i3-hashtable, hash"); + invalid = -1; + for (int i = 0; i < size; i++) + hash[i].I1() = invalid; + } + +public: + int Size() const + { + return hash.Size(); + } + + bool UsedPos (int pos) const + { + return ! (hash[pos].I1() == invalid); + } + + int UsedElements () const + { + int n = hash.Size(); + int cnt = 0; + for (int i = 0; i < n; i++) + if (hash[i].I1() != invalid) + cnt++; + return cnt; + } + + int HashValue (const INDEX_3 & ind) const + { + return (ind.I1() + 15 * ind.I2() + 41 * ind.I3()) % hash.Size(); + } + + int Position (const INDEX_3 & ind) const + { + int i = HashValue(ind); + while (1) + { + if (hash[i] == ind) return i; + if (hash[i].I1() == invalid) return -1; + i = (i+1) % hash.Size(); + } + } + + int Costs (const INDEX_3 & ind) const + { + int i = HashValue(ind); + int c = 1; + while (1) + { + if (hash[i] == ind) return c; + if (hash[i].I1() == invalid) return c; + i = (i+1) % hash.Size(); + c++; + } + } + + + + // returns true, if new postion is created + bool PositionCreate (const INDEX_3 & ind, int & apos) + { + int i = HashValue (ind); + if (hash[i] == ind) + { + apos = i; + return false; + } + if (hash[i].I1() == invalid) + { + hash[i] = ind; + apos = i; + return true; + } + return PositionCreate2 (ind, apos); + } + +protected: + bool PositionCreate2 (const INDEX_3 & ind, int & apos); + void BaseSetSize (int asize); +}; + + + +template +class INDEX_3_CLOSED_HASHTABLE : public BASE_INDEX_3_CLOSED_HASHTABLE +{ + // MoveableArray cont; + Array cont; + +public: + INDEX_3_CLOSED_HASHTABLE (int size) + : BASE_INDEX_3_CLOSED_HASHTABLE(size), cont(size) + { + ; //cont.SetName ("i3-hashtable, contents"); + } + + void Set (const INDEX_3 & ahash, const T & acont) + { + int pos; + PositionCreate (ahash, pos); + hash[pos] = ahash; + cont[pos] = acont; + } + + const T & Get (const INDEX_3 & ahash) const + { + return cont[Position (ahash)]; + } + + bool Used (const INDEX_3 & ahash) const + { + return (Position (ahash) != -1); + } + + void SetData (int pos, const INDEX_3 & ahash, const T & acont) + { + hash[pos] = ahash; + cont[pos] = acont; + } + + void GetData (int pos, INDEX_3 & ahash, T & acont) const + { + ahash = hash[pos]; + acont = cont[pos]; + } + + void SetData (int pos, const T & acont) + { + cont[pos] = acont; + } + + void GetData (int pos, T & acont) const + { + acont = cont[pos]; + } + + const T & GetData (int pos) const + { + return cont[pos]; + } + + void SetSize (int size) + { + BaseSetSize(size); + cont.SetSize(size); + } + + void PrintMemInfo (ostream & ost) const + { + cout << "Hashtable: " << Size() + << " entries of size " << sizeof(INDEX_3) << " + " << sizeof(T) + << " = " << Size() * (sizeof(INDEX_3) + sizeof(T)) << " bytes" << endl; + + } + + void DeleteData () + { + SetSize (cont.Size()); + } + + void SetName (const char * aname) + { + ; + // cont.SetName(aname); + // hash.SetName(aname); + } +}; + + + +template +inline ostream & operator<< (ostream & ost, const INDEX_3_CLOSED_HASHTABLE & ht) +{ + for (int i = 0; i < ht.Size(); i++) + if (ht.UsedPos(i)) + { + INDEX_3 hash; + T data; + ht.GetData (i, hash, data); + ost << "hash = " << hash << ", data = " << data << endl; + } + return ost; +} + + + + + + + + + + + + + + + +template +inline INDEX_3_HASHTABLE :: INDEX_3_HASHTABLE (int size) + : BASE_INDEX_3_HASHTABLE (size), cont(size) +{ + ; +} + +template +inline int INDEX_3_HASHTABLE :: PositionCreate (const INDEX_3 & ahash, int & bnr, int & colnr) +{ + bnr = HashValue (ahash); + colnr = Position (bnr, ahash); + if (!colnr) + { + hash.Add (bnr, ahash); + cont.AddEmpty (bnr); + colnr = cont.EntrySize (bnr); + return 1; + } + return 0; +} + + +template +inline void INDEX_3_HASHTABLE :: Set (const INDEX_3 & ahash, const T & acont) +{ + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + if (pos) + cont.Set (bnr, pos, acont); + else + { + hash.Add1 (bnr, ahash); + cont.Add1 (bnr, acont); + } +} + +template +inline const T & INDEX_3_HASHTABLE :: Get (const INDEX_3 & ahash) const +{ + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + return cont.Get (bnr, pos); +} + +template +inline bool INDEX_3_HASHTABLE :: Used (const INDEX_3 & ahash) const +{ + return (Position (HashValue (ahash), ahash)) ? 1 : 0; +} + +template +inline int INDEX_3_HASHTABLE :: GetNBags () const +{ + return cont.Size(); +} + +template +inline int INDEX_3_HASHTABLE :: GetBagSize (int bnr) const +{ + return cont.EntrySize (bnr); +} + +template +inline void INDEX_3_HASHTABLE :: GetData (int bnr, int colnr, INDEX_3 & ahash, T & acont) const +{ + ahash = hash.Get(bnr, colnr); + acont = cont.Get(bnr, colnr); +} + +template +inline void INDEX_3_HASHTABLE :: SetData (int bnr, int colnr, const INDEX_3 & ahash, const T & acont) +{ + hash.Set(bnr, colnr, ahash); + cont.Set(bnr, colnr, acont); +} + +template +inline void INDEX_3_HASHTABLE :: SetSize (int size) +{ + hash.SetSize (size); + cont.SetSize (size); +} + +template +inline void INDEX_3_HASHTABLE :: DeleteData () +{ + int n = hash.Size(); + hash.SetSize (n); + cont.SetSize (n); +} + +template +inline void INDEX_3_HASHTABLE :: PrepareSet (const INDEX_3 & ahash) +{ + int bnr = HashValue (ahash); + hash.IncSizePrepare (bnr-1); + cont.IncSizePrepare (bnr-1); +} + + +template +inline void INDEX_3_HASHTABLE :: AllocateElements () +{ + hash.AllocateElementsOneBlock(); + cont.AllocateElementsOneBlock(); +} + + + +template +inline void INDEX_3_HASHTABLE :: PrintMemInfo (ostream & ost) const + { + ost << "Hash: " << endl; + hash.PrintMemInfo (ost); + ost << "Cont: " << endl; + cont.PrintMemInfo (ost); + } + + + + + +template +inline INDEX_HASHTABLE :: INDEX_HASHTABLE (int size) + : BASE_INDEX_HASHTABLE (size), cont(size) + { + ; + } + +template +inline void INDEX_HASHTABLE :: Set (const INDEX & ahash, const T & acont) + { + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + if (pos) + cont.Set (bnr, pos, acont); + else + { + hash.Add (bnr, ahash); + cont.Add (bnr, acont); + } + } + +template +inline const T & INDEX_HASHTABLE :: Get (const INDEX & ahash) const + { + int bnr = HashValue (ahash); + int pos = Position (bnr, ahash); + return cont.Get (bnr, pos); + } + +template +inline bool INDEX_HASHTABLE :: Used (const INDEX & ahash) const + { + return (Position (HashValue (ahash), ahash)) ? 1 : 0; + } + +template +inline int INDEX_HASHTABLE :: GetNBags () const + { + return hash.Size(); + } + +template +inline int INDEX_HASHTABLE :: GetBagSize (int bnr) const + { + return hash.EntrySize(bnr); + } + +template +inline void INDEX_HASHTABLE :: GetData (int bnr, int colnr, INDEX & ahash, T & acont) const + { + ahash = hash.Get(bnr, colnr); + acont = cont.Get(bnr, colnr); + } + +template +inline void INDEX_HASHTABLE :: PrintMemInfo (ostream & ost) const + { + ost << "Hash: " << endl; + hash.PrintMemInfo (ost); + ost << "Cont: " << endl; + cont.PrintMemInfo (ost); + } + + + + + + + + + + + + + + + +/* *********** Closed Hashing ************************* */ + + + +template +inline INDEX_2_CLOSED_HASHTABLE :: +INDEX_2_CLOSED_HASHTABLE (int size) + : BASE_INDEX_2_CLOSED_HASHTABLE(size), cont(size) +{ + // cont.SetName ("i2-hashtable, contents"); +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +Set (const INDEX_2 & ahash, const T & acont) +{ + int pos; + PositionCreate (ahash, pos); + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline const T & INDEX_2_CLOSED_HASHTABLE :: +Get (const INDEX_2 & ahash) const +{ + int pos = Position (ahash); + return cont.Get(pos); +} + +template +inline bool INDEX_2_CLOSED_HASHTABLE :: +Used (const INDEX_2 & ahash) const +{ + int pos = Position (ahash); + return (pos != 0); +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +SetData (int pos, const INDEX_2 & ahash, const T & acont) +{ + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +GetData (int pos, INDEX_2 & ahash, T & acont) const +{ + ahash = hash.Get(pos); + acont = cont.Get(pos); +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +SetData (int pos, const T & acont) +{ + cont.Elem(pos) = acont; +} + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +GetData (int pos, T & acont) const +{ + acont = cont.Get(pos); +} + + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +SetSize (int size) +{ + BaseSetSize(size); + cont.SetSize(size); +} + + + +template +inline void INDEX_2_CLOSED_HASHTABLE :: +PrintMemInfo (ostream & ost) const +{ + cout << "Hashtable: " << Size() + << " entries of size " << sizeof(INDEX_2) << " + " << sizeof(T) + << " = " << Size() * (sizeof(INDEX_2) + sizeof(T)) << " bytes." + << " Used els: " << UsedElements() + << endl; +} + + + + + + + + + + + + + + + + +/* +template +inline INDEX_3_CLOSED_HASHTABLE :: +INDEX_3_CLOSED_HASHTABLE (int size) + : BASE_INDEX_3_CLOSED_HASHTABLE(size), cont(size) +{ + cont.SetName ("i3-hashtable, contents"); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +Set (const INDEX_3 & ahash, const T & acont) +{ + int pos; + PositionCreate (ahash, pos); + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline const T & INDEX_3_CLOSED_HASHTABLE :: +Get (const INDEX_3 & ahash) const +{ + int pos = Position (ahash); + return cont[pos]; +} + +template +inline bool INDEX_3_CLOSED_HASHTABLE :: +Used (const INDEX_3 & ahash) const +{ + int pos = Position (ahash); + return (pos != 0); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +SetData (int pos, const INDEX_3 & ahash, const T & acont) +{ + hash.Elem(pos) = ahash; + cont.Elem(pos) = acont; +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +GetData (int pos, INDEX_3 & ahash, T & acont) const +{ + ahash = hash.Get(pos); + acont = cont.Get(pos); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +SetData (int pos, const T & acont) +{ + cont.Elem(pos) = acont; +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +GetData (int pos, T & acont) const +{ + acont = cont.Get(pos); +} + +template +inline const T & INDEX_3_CLOSED_HASHTABLE :: +GetData (int pos) const +{ + return cont.Get(pos); +} + + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +SetSize (int size) +{ + BaseSetSize(size); + cont.SetSize(size); +} + +template +inline void INDEX_3_CLOSED_HASHTABLE :: +PrintMemInfo (ostream & ost) const +{ + cout << "Hashtable: " << Size() + << " entries of size " << sizeof(INDEX_3) << " + " << sizeof(T) + << " = " << Size() * (sizeof(INDEX_3) + sizeof(T)) << " bytes" << endl; +} +*/ + + +} + + +#endif diff --git a/libsrc/general/mpi_interface.cpp b/libsrc/general/mpi_interface.cpp new file mode 100644 index 00000000..57d69ab9 --- /dev/null +++ b/libsrc/general/mpi_interface.cpp @@ -0,0 +1,56 @@ +/**************************************************************************/ +/* File: mpi_interface.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 04. Apr. 97 */ +/**************************************************************************/ + +#include +#include + + +namespace netgen +{ + + +#ifdef PARALLEL + + void MyMPI_SendCmd (const char * cmd) + { + char buf[100]; + strcpy (buf, cmd); + // MPI_Bcast (&buf, 100, MPI_CHAR, 0, MPI_COMM_WORLD); + + for (int dest = 1; dest < ntasks; dest++) + MPI_Bsend( &buf, 100, MPI_CHAR, dest, MPI_TAG_CMD, MPI_COMM_WORLD); + } + + string MyMPI_RecvCmd () + { + char buf[100]; + // MPI_Bcast (&buf, 100, MPI_CHAR, 0, MPI_COMM_WORLD); + + // VT_OFF(); + MPI_Status status; + int flag; + do + { + MPI_Iprobe (0, MPI_TAG_CMD, MPI_COMM_WORLD, &flag, &status); + if (!flag) + { + VT_TRACER ("sleep"); + usleep (1000); + } + } + while (!flag); + // VT_ON(); + + MPI_Recv( &buf, 100, MPI_CHAR, 0, MPI_TAG_CMD, MPI_COMM_WORLD, &status); + + return string(buf); + } + +#endif + + +} + diff --git a/libsrc/general/mpi_interface.hpp b/libsrc/general/mpi_interface.hpp new file mode 100644 index 00000000..a78794b1 --- /dev/null +++ b/libsrc/general/mpi_interface.hpp @@ -0,0 +1,359 @@ +#ifndef FILE_PARALLEL +#define FILE_PARALLEL + + + +#ifdef VTRACE +#include "vt_user.h" +#else + #define VT_USER_START(n) + #define VT_USER_END(n) + #define VT_TRACER(n) +#endif + + +namespace netgen +{ + + extern DLL_HEADER int id, ntasks; + + +#ifdef PARALLEL + + enum { MPI_TAG_CMD = 110 }; + enum { MPI_TAG_MESH = 210 }; + enum { MPI_TAG_VIS = 310 }; + + extern MPI_Comm mesh_comm; + + template + MPI_Datatype MyGetMPIType ( ) + { cerr << "ERROR in GetMPIType() -- no type found" << endl;return 0; } + + template <> + inline MPI_Datatype MyGetMPIType ( ) + { return MPI_INT; } + + template <> + inline MPI_Datatype MyGetMPIType ( ) + { return MPI_DOUBLE; } + + + template class Vec; + template <> + inline MPI_Datatype MyGetMPIType > () + { + static MPI_Datatype MPI_T = 0; + if (!MPI_T) + { + MPI_Type_contiguous ( 3, MPI_DOUBLE, &MPI_T); + MPI_Type_commit ( &MPI_T ); + } + return MPI_T; + }; + + + inline void MyMPI_Send (int i, int dest, int tag) + { + int hi = i; + MPI_Send( &hi, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); + } + + inline void MyMPI_Recv (int & i, int src, int tag) + { + MPI_Status status; + MPI_Recv( &i, 1, MPI_INT, src, tag, MPI_COMM_WORLD, &status); + } + + + + inline void MyMPI_Send (const string & s, int dest, int tag) + { + MPI_Send( const_cast (s.c_str()), s.length(), MPI_CHAR, dest, tag, MPI_COMM_WORLD); + } + + inline void MyMPI_Recv (string & s, int src, int tag) + { + MPI_Status status; + int len; + MPI_Probe (src, tag, MPI_COMM_WORLD, &status); + MPI_Get_count (&status, MPI_CHAR, &len); + s.assign (len, ' '); + MPI_Recv( &s[0], len, MPI_CHAR, src, tag, MPI_COMM_WORLD, &status); + } + + + + + template + inline void MyMPI_Send (FlatArray s, int dest, int tag) + { + MPI_Send( &s.First(), s.Size(), MyGetMPIType(), dest, tag, MPI_COMM_WORLD); + } + + template + inline void MyMPI_Recv ( FlatArray s, int src, int tag) + { + MPI_Status status; + MPI_Recv( &s.First(), s.Size(), MyGetMPIType(), src, tag, MPI_COMM_WORLD, &status); + } + + template + inline void MyMPI_Recv ( Array & s, int src, int tag) + { + MPI_Status status; + int len; + MPI_Probe (src, tag, MPI_COMM_WORLD, &status); + MPI_Get_count (&status, MyGetMPIType(), &len); + + s.SetSize (len); + MPI_Recv( &s.First(), len, MyGetMPIType(), src, tag, MPI_COMM_WORLD, &status); + } + + template + inline int MyMPI_Recv ( Array & s, int tag) + { + MPI_Status status; + int len; + MPI_Probe (MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status); + + int src = status.MPI_SOURCE; + + MPI_Get_count (&status, MyGetMPIType(), &len); + + s.SetSize (len); + MPI_Recv( &s.First(), len, MyGetMPIType(), src, tag, MPI_COMM_WORLD, &status); + + return src; + } + + + /* + template + inline void MyMPI_ISend (FlatArray s, int dest, int tag, MPI_Request & request) + { + MPI_Isend( &s.First(), s.Size(), MyGetMPIType(), dest, tag, MPI_COMM_WORLD, & request); + } + + + template + inline void MyMPI_IRecv (FlatArray s, int dest, int tag, MPI_Request & request) + { + MPI_Irecv( &s.First(), s.Size(), MyGetMPIType(), dest, tag, MPI_COMM_WORLD, & request); + } + */ + + template + inline MPI_Request MyMPI_ISend (FlatArray s, int dest, int tag, MPI_Comm comm = MPI_COMM_WORLD) + { + MPI_Request request; + MPI_Isend( &s.First(), s.Size(), MyGetMPIType(), dest, tag, comm, &request); + return request; + } + + + template + inline MPI_Request MyMPI_IRecv (FlatArray s, int dest, int tag, MPI_Comm comm = MPI_COMM_WORLD) + { + MPI_Request request; + MPI_Irecv( &s.First(), s.Size(), MyGetMPIType(), dest, tag, comm, &request); + return request; + } + + /* + template + inline void MyMPI_ISend (FlatArray s, int dest, int tag) + { + MPI_Request request; + MPI_Isend( &s.First(), s.Size(), MyGetMPIType(), dest, tag, MPI_COMM_WORLD, &request); + MPI_Request_free (&request); + } + + + template + inline void MyMPI_IRecv (FlatArray s, int dest, int tag) + { + MPI_Request request; + MPI_Irecv( &s.First(), s.Size(), MyGetMPIType(), dest, tag, MPI_COMM_WORLD, &request); + MPI_Request_free (&request); + } + */ + + + + /* + send a table entry to each of the prcesses in the group ... + receive-table entries will be set + */ + + /* + template + inline void MyMPI_ExchangeTable (TABLE & send_data, + TABLE & recv_data, int tag, + MPI_Comm comm = MPI_COMM_WORLD) + { + int ntasks, rank; + MPI_Comm_size(comm, &ntasks); + MPI_Comm_rank(comm, &rank); + + Array requests; + for (int dest = 0; dest < ntasks; dest++) + if (dest != rank) + requests.Append (MyMPI_ISend (send_data[dest], dest, tag, comm)); + + for (int i = 0; i < ntasks-1; i++) + { + MPI_Status status; + MPI_Probe (MPI_ANY_SOURCE, tag, comm, &status); + int size, src = status.MPI_SOURCE; + MPI_Get_count (&status, MPI_INT, &size); + recv_data.SetEntrySize (src, size, sizeof(T)); + requests.Append (MyMPI_IRecv (recv_data[src], src, tag, comm)); + } + MPI_Barrier (comm); + MPI_Waitall (requests.Size(), &requests[0], MPI_STATUS_IGNORE); + } + */ + + template + inline void MyMPI_ExchangeTable (TABLE & send_data, + TABLE & recv_data, int tag, + MPI_Comm comm = MPI_COMM_WORLD) + { + int ntasks, rank; + MPI_Comm_size(comm, &ntasks); + MPI_Comm_rank(comm, &rank); + + Array send_sizes(ntasks); + Array recv_sizes(ntasks); + for (int i = 0; i < ntasks; i++) + send_sizes[i] = send_data[i].Size(); + + MPI_Alltoall (&send_sizes[0], 1, MPI_INT, + &recv_sizes[0], 1, MPI_INT, comm); + + // in-place is buggy ! +// MPI_Alltoall (MPI_IN_PLACE, 1, MPI_INT, +// &recv_sizes[0], 1, MPI_INT, comm); + + + for (int i = 0; i < ntasks; i++) + recv_data.SetEntrySize (i, recv_sizes[i], sizeof(T)); + + Array requests; + for (int dest = 0; dest < ntasks; dest++) + if (dest != rank && send_data[dest].Size()) + requests.Append (MyMPI_ISend (send_data[dest], dest, tag, comm)); + + for (int dest = 0; dest < ntasks; dest++) + if (dest != rank && recv_data[dest].Size()) + requests.Append (MyMPI_IRecv (recv_data[dest], dest, tag, comm)); + + // MPI_Barrier (comm); + MPI_Waitall (requests.Size(), &requests[0], MPI_STATUS_IGNORE); + } + + + + + + + + extern void MyMPI_SendCmd (const char * cmd); + extern string MyMPI_RecvCmd (); + + + + + template + inline void MyMPI_Bcast (T & s, MPI_Comm comm = MPI_COMM_WORLD) + { + MPI_Bcast (&s, 1, MyGetMPIType(), 0, comm); + } + + template + inline void MyMPI_Bcast (Array & s, MPI_Comm comm = MPI_COMM_WORLD) + { + int size = s.Size(); + MyMPI_Bcast (size, comm); + if (id != 0) s.SetSize (size); + MPI_Bcast (&s[0], size, MyGetMPIType(), 0, comm); + } + + template + inline void MyMPI_Bcast (Array & s, int root, MPI_Comm comm = MPI_COMM_WORLD) + { + int id; + MPI_Comm_rank(comm, &id); + + int size = s.Size(); + MPI_Bcast (&size, 1, MPI_INT, root, comm); + if (id != root) s.SetSize (size); + if ( !size ) return; + MPI_Bcast (&s[0], size, MyGetMPIType(), root, comm); + } + + template + inline void MyMPI_Allgather (const T & send, FlatArray recv, MPI_Comm comm) + { + MPI_Allgather( const_cast (&send), 1, MyGetMPIType(), &recv[0], 1, MyGetMPIType(), comm); + } + + template + inline void MyMPI_Alltoall (FlatArray send, FlatArray recv, MPI_Comm comm) + { + MPI_Alltoall( &send[0], 1, MyGetMPIType(), &recv[0], 1, MyGetMPIType(), comm); + } + +// template +// inline void MyMPI_Alltoall_Block (FlatArray send, FlatArray recv, int blocklen, MPI_Comm comm) +// { +// MPI_Alltoall( &send[0], blocklen, MyGetMPIType(), &recv[0], blocklen, MyGetMPIType(), comm); +// } + + + + /* + inline void MyMPI_Send ( int *& s, int len, int dest, int tag) + { + int hlen = len; + MPI_Send( &hlen, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); + MPI_Send( s, len, MPI_INT, dest, tag, MPI_COMM_WORLD); + } + + + inline void MyMPI_Recv ( int *& s, int & len, int src, int tag) + { + MPI_Status status; + MPI_Recv( &len, 1, MPI_INT, src, tag, MPI_COMM_WORLD, &status); + if ( s ) + delete [] s; + s = new int [len]; + MPI_Recv( s, len, MPI_INT, src, tag, MPI_COMM_WORLD, &status); + } + + + + inline void MyMPI_Send ( double * s, int len, int dest, int tag) + { + MPI_Send( &len, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); + MPI_Send( s, len, MPI_DOUBLE, dest, tag, MPI_COMM_WORLD); + } + + + inline void MyMPI_Recv ( double *& s, int & len, int src, int tag) + { + MPI_Status status; + MPI_Recv( &len, 1, MPI_INT, src, tag, MPI_COMM_WORLD, &status); + if ( s ) + delete [] s; + s = new double [len]; + MPI_Recv( s, len, MPI_DOUBLE, src, tag, MPI_COMM_WORLD, &status); + } + */ + +#endif // PARALLEL + +} + +#endif diff --git a/libsrc/general/myadt.hpp b/libsrc/general/myadt.hpp new file mode 100644 index 00000000..cdbbd61f --- /dev/null +++ b/libsrc/general/myadt.hpp @@ -0,0 +1,48 @@ +#ifndef FILE_MYADT +#define FILE_MYADT + +/**************************************************************************/ +/* File: myadt.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + include for all abstract data types +*/ + + + +#include "../include/mystdlib.h" +#include "../include/mydefs.hpp" + + +#include "ngexception.hpp" +#include "parthreads.hpp" +// #include "moveablemem.hpp" +#include "dynamicmem.hpp" + +#include "template.hpp" +#include "array.hpp" +#include "table.hpp" +#include "hashtabl.hpp" + + +#include "symbolta.hpp" +#include "bitarray.hpp" +#include "flags.hpp" +#include "spbita2d.hpp" + +#include "seti.hpp" +#include "optmem.hpp" +#include "autoptr.hpp" +#include "sort.hpp" +#include "stack.hpp" +#include "mystring.hpp" +#include "profiler.hpp" + +#include "mpi_interface.hpp" +#include "netgenout.hpp" +#include "gzstream.h" + +#endif diff --git a/libsrc/general/mystring.cpp b/libsrc/general/mystring.cpp new file mode 100644 index 00000000..dc59c80e --- /dev/null +++ b/libsrc/general/mystring.cpp @@ -0,0 +1,426 @@ + +//************************************************************** +// +// filename: mystring.cpp +// +// project: doctoral thesis +// +// autor: Dipl.-Ing. Gerstmayr Johannes +// +// generated: 20.12.98 +// last change: 20.12.98 +// description: implementation for strings +// remarks: +// +//************************************************************** + +// string class +#include +#include + +#include +#include + + +namespace netgen +{ + + void ReadEnclString(istream & in, string & str, const char encl) + { + char currchar; + str = ""; + + in.get(currchar); + while(in && (currchar == ' ' || currchar == '\t' || currchar == '\n') ) + in.get(currchar); + + if(currchar == encl) + { + in.get(currchar); + while(in && currchar != encl) + { + str += currchar; + in.get(currchar); + } + } + else + { + in.putback(currchar); + in >> str; + } + } + + + + + + +void DefaultStringErrHandler() +{ + cerr << "Error : string operation out of range\n" << flush; +} + +void (*MyStr::ErrHandler)() = DefaultStringErrHandler; + + /* +MyStr::MyStr() +{ + length = 0; + str = shortstr; + str[0] = 0; +} + */ + +MyStr::MyStr(const char *s) +{ + length = unsigned(strlen(s)); + + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, s); +} + +/* +MyStr::MyStr(char s) +{ + length = 1; + str = shortstr; + str[0] = s; + str[1] = (char)0; +} +*/ + +MyStr::MyStr(const MyStr& s) +{ + length = s.length; + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, s.str); +} + +MyStr::MyStr(int i) +{ + char buffer[32]; + sprintf(buffer, "%d", i); + length = unsigned(strlen(buffer)); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, buffer); +} + +MyStr::MyStr(void * p) +{ + char buffer[32]; + sprintf(buffer, "%p", p); + length = unsigned(strlen(buffer)); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, buffer); +} + + +MyStr::MyStr(long l) +{ + char buffer[32]; + sprintf(buffer, "%ld", l); + length = unsigned(strlen(buffer)); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, buffer); +} + +MyStr::MyStr(double d) +{ + char buffer[32]; + //if (fabs(d) < 1E-100) {d = 0;} + sprintf(buffer, "%g", d); + length = unsigned(strlen(buffer)); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, buffer); +} + +MyStr::MyStr(const Point3d& p) +{ + char buffer[80]; + //if (fabs(d) < 1E-100) {d = 0;} + sprintf(buffer, "[%g, %g, %g]", p.X(), p.Y(), p.Z()); + length = unsigned(strlen(buffer)); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, buffer); +} + +MyStr::MyStr(const Vec3d& p) +{ + char buffer[80]; + //if (fabs(d) < 1E-100) {d = 0;} + sprintf(buffer, "[%g, %g, %g]", p.X(), p.Y(), p.Z()); + length = unsigned(strlen(buffer)); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, buffer); +} + +MyStr::MyStr(unsigned n, int) +{ + length = n; + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + str[n] = 0; +} + +MyStr::MyStr(const string & st) +{ + length = unsigned(st.length()); + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy (str, st.c_str()); +} + + + +MyStr MyStr::Left(unsigned r) +{ + if(r > length) + { + MyStr::ErrHandler(); + MyStr s; + return s; + } + else + { + MyStr tmp(r, 0); + strncpy(tmp.str, str, r); + return tmp; + } +} + +MyStr MyStr::Right(unsigned l) +{ + if(l > length) + { + MyStr::ErrHandler(); + MyStr s; + return s; + } + else + { + MyStr tmp(l, 0); + strncpy(tmp.str, str + length - l, l); + return tmp; + } +} + +MyStr& MyStr::InsertAt(unsigned pos, const MyStr& s) +{ + if(pos > length) + { + MyStr::ErrHandler(); + return *this; + } + int newLength = length + s.length; + char *tmp = new char[newLength + 1]; + strncpy(tmp, str, pos); + strcpy(tmp + pos, s.str); + strcpy(tmp + pos + s.length, str + pos); + + if (length > SHORTLEN) delete [] str; + length = newLength; + if (length > SHORTLEN) + str = tmp; + else + { + strcpy (shortstr, tmp); + delete [] tmp; + str = shortstr; + } + return *this; +} + +MyStr &MyStr::WriteAt(unsigned pos, const MyStr& s) +{ + if(pos > length) + { + MyStr::ErrHandler(); + return *this; + } + unsigned n = length - pos; + if(s.length < n) + n = s.length; + strncpy(str + pos, s.str, n); + return *this; +} + +void MyStr::ConvertTextToExcel() +{ + /* + for (int i = 0; i < Length(); i++) + { + if ((*this)[i]==',') {(*this)[i] = ';';} + else if ((*this)[i]=='.') {(*this)[i] = ',';} + } + */ +} + +void MyStr::ConvertExcelToText() +{ + /* + for (int i = 0; i < Length(); i++) + { + if ((*this)[i]==',') {(*this)[i] = '.';} + else if ((*this)[i]==';') {(*this)[i] = ',';} + } + */ +} + +MyStr& MyStr::operator = (const MyStr& s) +{ + if (length > SHORTLEN) delete [] str; + length = s.length; + if (length > SHORTLEN) + str = new char[length + 1]; + else + str = shortstr; + strcpy(str, s.str); + return *this; +} + +MyStr operator + (const MyStr& s1, const MyStr& s2) +{ + MyStr tmp(s1.length + s2.length, 0); + if (s1.length != 0) strcpy(tmp.str, s1.str); + if (s2.length != 0) strcpy(tmp.str + s1.length, s2.str); + return tmp; +} + +void MyStr::operator += (const MyStr& s) +{ + if (length+s.length <= SHORTLEN) + { + if (s.length != 0) strcpy(shortstr + length, s.str); + } + else + { + char *tmp = new char[length + s.length + 1]; + if (length != 0) strcpy(tmp, str); + if (s.length != 0) strcpy(tmp + length, s.str); + if (length > SHORTLEN) delete [] str; + length += s.length; + str = tmp; + } +} + +char& MyStr::operator [] (unsigned n) +{ + static char dummy; + if(n < length) + return str[n]; + else + { + MyStr::ErrHandler(); + return dummy; + } +} + +char MyStr::operator [] (unsigned n) const +{ + static char dummy; + if(n < length) + return str[n]; + else + { + MyStr::ErrHandler(); + return dummy; + } +} + +MyStr MyStr::operator () (unsigned l, unsigned r) +{ + if((l > r) || (r > length)) + { + MyStr::ErrHandler(); + MyStr s; + return s; + } + else + { + int n = r - l + 1; + MyStr tmp(n, 0); + strncpy(tmp.str, str + 1, n); + return tmp; + } +} + +string MyStr::cpp_string(void) const +{ + string aux(str,length); + return aux; +} + +/* +istream& operator >> (istream& is, MyStr& s) +{ + const int buflen = 1000; + char buffer[buflen+1]; + + int end = 0; + s = ""; + MyStr str; + + while (!end) + { + is.get(buffer, buflen); + str = MyStr(buffer); + s += str; + if (is.peek() == EOF) {end = 1;} + } + + return is; +} +*/ +/* +#ifdef __borland +::ifstream& operator >> (::ifstream& is, MyStr& s) // wb +{ // wb + const int buflen = 1000; // wb + char buffer[buflen+1]; // wb + // wb + int end = 0; // wb + s = ""; // wb + MyStr str; // wb + // wb + while (!end) // wb + { // wb + is.get(buffer, buflen); // wb + str = MyStr(buffer); // wb + s += str; // wb + if (is.peek() == EOF) {end = 1;} // wb + } // wb + // wb + return is; // wb +} + +#endif +*/ +} diff --git a/libsrc/general/mystring.hpp b/libsrc/general/mystring.hpp new file mode 100644 index 00000000..af522fc8 --- /dev/null +++ b/libsrc/general/mystring.hpp @@ -0,0 +1,220 @@ + +//************************************************************** +// +// filename: mystring.h +// +// project: doctoral thesis, program smart +// +// autor: Dipl.-Ing. Gerstmayr Johannes +// +// generated: 20.12.98 +// last change: 20.12.98 +// description: base class for strings +// remarks: string with n characters has +// 0..n-1 characters and at pos n a 0 +// +//************************************************************** + + +#ifndef MYSTRING__H +#define MYSTRING__H + +namespace netgen +{ + +class Point3d; +class Vec3d; + + +// extract string str which is enclosed by the given character encl from a given string in +void ReadEnclString(istream & in, string & str, const char encl); + + +class MyStr; + +DLL_HEADER MyStr operator + (const MyStr &, const MyStr &); +DLL_HEADER int operator == (const MyStr &, const MyStr &); +DLL_HEADER int operator < (const MyStr &, const MyStr &); +DLL_HEADER int operator <= (const MyStr &, const MyStr &); +DLL_HEADER int operator > (const MyStr &, const MyStr &); +DLL_HEADER int operator >= (const MyStr &, const MyStr &); +DLL_HEADER int operator != (const MyStr &, const MyStr &); +DLL_HEADER ostream& operator << (ostream &, const MyStr &); +DLL_HEADER istream& operator >> (istream &, MyStr &); + +class DLL_HEADER MyStr +{ +public: + MyStr(); + MyStr(const char *); + MyStr(char); + MyStr(const MyStr &); + MyStr(int); + MyStr(void *); + MyStr(long); + MyStr(double); + MyStr(const Point3d& p); + MyStr(const Vec3d& p); + MyStr(const string & st); + + ~MyStr(); + MyStr Left(unsigned); + MyStr Right(unsigned); + MyStr& InsertAt(unsigned, const MyStr &); + MyStr& WriteAt(unsigned, const MyStr &); + unsigned Length() const; + int Find(const char); + int Find(const char *); + int Find(const MyStr &); + MyStr& operator = (const MyStr &); + DLL_HEADER friend MyStr operator + (const MyStr &, const MyStr &); + void operator += (const MyStr &); + char* c_str(); + string cpp_string(void) const; + + //change every ',' -> ';', '.' -> ',' + void ConvertTextToExcel(); + //change every ','->'.', ';'->',' + void ConvertExcelToText(); + + MyStr operator () (unsigned, unsigned); + operator int(); + operator double(); + operator long(); + operator char *(); + char& operator [] (unsigned int); + char operator [] (unsigned int) const; + + DLL_HEADER friend int operator == (const MyStr &, const MyStr &); + DLL_HEADER friend int operator < (const MyStr &, const MyStr &); + DLL_HEADER friend int operator <= (const MyStr &, const MyStr &); + DLL_HEADER friend int operator > (const MyStr &, const MyStr &); + DLL_HEADER friend int operator >= (const MyStr &, const MyStr &); + DLL_HEADER friend int operator != (const MyStr &, const MyStr &); + DLL_HEADER friend ostream& operator << (ostream &, const MyStr &); + DLL_HEADER friend istream& operator >> (istream &, MyStr &); + static void SetToErrHandler(void (*)()); +private: + MyStr(unsigned, int); + char *str; + unsigned length; + enum { SHORTLEN = 24 }; + char shortstr[SHORTLEN+1]; + static void(*ErrHandler)(); +}; + + +inline MyStr::MyStr() +{ + length = 0; + str = shortstr; + str[0] = 0; +} + +inline MyStr::MyStr(char s) +{ + length = 1; + str = shortstr; + str[0] = s; + str[1] = (char)0; +} + +inline MyStr::~MyStr() +{ + if (length > SHORTLEN) + delete [] str; +} + +inline unsigned MyStr::Length() const +{ + return length; +} + +inline int MyStr::Find(const char c) +{ + char *pos = strchr(str, int(c)); + return pos ? int(pos - str) : -1; +} + +inline int MyStr::Find(const MyStr &s) +{ + char *pos = strstr(str, s.str); + return pos ? int(pos - str) : -1; +} + +inline int MyStr::Find(const char *s) +{ + char *pos = strstr(str, s); + return pos ? int(pos - str) : -1; +} + +inline MyStr::operator int() +{ + return atoi(str); +} + +inline MyStr::operator double() +{ + return atof(str); +} + +inline MyStr::operator long() +{ + return atol(str); +} + +inline MyStr::operator char *() +{ + return str; +} + +inline char* MyStr::c_str() +{ + return str; +} + + +inline int operator == (const MyStr &s1, const MyStr& s2) +{ + return strcmp(s1.str, s2.str) == 0; +} + +inline int operator < (const MyStr &s1, const MyStr& s2) +{ + return strcmp(s1.str, s2.str) < 0; +} + +inline int operator <= (const MyStr &s1, const MyStr& s2) +{ + return strcmp(s1.str, s2.str) <= 0; +} + +inline int operator > (const MyStr &s1, const MyStr& s2) +{ + return strcmp(s1.str, s2.str) > 0; +} + +inline int operator >= (const MyStr &s1, const MyStr& s2) +{ + return strcmp(s1.str, s2.str) >= 0; +} + +inline int operator != (const MyStr &s1, const MyStr& s2) +{ + return !(s1 == s2); +} + +inline ostream& operator << (ostream& os, const MyStr& s) +{ + return os << s.str; +} + +inline void MyStr::SetToErrHandler(void (*Handler)()) +{ + ErrHandler = Handler; +}; + +} +#endif + + diff --git a/libsrc/general/netgenout.hpp b/libsrc/general/netgenout.hpp new file mode 100644 index 00000000..fafe495e --- /dev/null +++ b/libsrc/general/netgenout.hpp @@ -0,0 +1,208 @@ +#ifndef NETGEN_OUT_STREAM_HPP__ +#define NETGEN_OUT_STREAM_HPP__ + +// #include +// #include +// #include + +namespace netgen +{ + +#ifdef PARALLEL +extern int id; +extern int ntasks; +#endif +DLL_HEADER extern int printmessage_importance; +DLL_HEADER extern int printdots; + + + +class Imp +{ + int importance; +public: + Imp () : importance(0) { ; } + + Imp ( int aimportance ) : importance(aimportance) { ; } + + int GetImp () const { return importance; } +}; + + +class Proc +{ + int proc; +public: + Proc () : proc(0) { ; } + + Proc ( int aproc ) : proc(aproc) { ; } + + int GetProc () const { return proc; } +}; + +class Procs +{ + const netgen::FlatArray procs; + +public: + + Procs ( const netgen::FlatArray & aprocs ) : procs (aprocs) { ; } + + const netgen::FlatArray & GetProcs () const { return procs; } +}; + + + +class NetgenOutStream +{ + ostream * out; + + bool print; + bool printheader; + + +public: + NetgenOutStream() : + out(&std::cout), + print(1), + printheader(1) + { + ; + } + + NetgenOutStream(ostream * aout, Imp imp ) : + out(aout), + printheader(1) + { + if ( netgen::printmessage_importance >= imp.GetImp() ) + print = true; + else + print = false; + } + + NetgenOutStream(ostream * aout, Proc proc ) : + out(aout), + printheader(1) + { +#ifdef PARALLEL + if ( netgen::id == proc.GetProc() ) + print = true; + else + print = false; +#else + if ( 0 == proc.GetProc() ) + print = true; + else + print = false; + +#endif + } + + NetgenOutStream(ostream * aout, Procs & procs ) : + out(aout), + printheader(1) + { +#ifdef PARALLEL + if ( procs.GetProcs().Contains(netgen::id) ) + print = true; + else + print = false; +#else + if ( procs.GetProcs().Contains(0) ) + print = true; + else + print = false; + +#endif + } + + ostream & OStream () + { + return *out; + } + + template + NetgenOutStream & operator<< (T & var) + { + if ( print ) + { +#ifdef PARALLEL + if ( printheader ) + { + *out << "proc " << netgen::id << ": "; + printheader = false; + } +#endif + *out << var; + } + return (*this); + } + + NetgenOutStream& operator<< (ostream& ( *pf )(ostream&)) + { + if ( print ) + *out << (*pf) ; + + return (*this); + } + + NetgenOutStream& operator<< (ios& ( *pf )(ios&)) + { + if ( print) + *out << (*pf) ; + + printheader = 1; + + return (*this); + } + + NetgenOutStream& operator<< (ios_base& ( *pf )(ios_base&)) + { + if (print ) + *out << (*pf) ; + return (*this); + } + + +}; + +/* +NetgenOutStream operator<< ( ostream & ost, Imp imp ); +NetgenOutStream operator<< ( ostream & ost, Proc proc ); +NetgenOutStream operator<< ( ostream & ost, Procs & procs ); +*/ + +inline NetgenOutStream operator<< ( ostream & ost, Imp imp ) + { + return ( NetgenOutStream ( &ost, imp ) ); + } + +inline NetgenOutStream operator<< ( ostream & ost, Proc proc ) + { + return ( NetgenOutStream ( &ost, proc ) ); + } + + +inline NetgenOutStream operator<< ( ostream & ost, Procs & procs ) + { + return ( NetgenOutStream ( &ost, procs ) ); + } + + + +// { +// return ( NetgenOutStream ( &ost, imp.GetImp() ) ); +// } + +// template +// NetgenOutStream& operator<< (NetgenOutStream& out, T c ) +// { +// out.OStream() << c << endl; +// return out; +// } + + +} + + +#endif diff --git a/libsrc/general/ngexception.cpp b/libsrc/general/ngexception.cpp new file mode 100644 index 00000000..2496f6b3 --- /dev/null +++ b/libsrc/general/ngexception.cpp @@ -0,0 +1,33 @@ +/**************************************************************************/ +/* File: ngexception.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 16. Jan. 02 */ +/**************************************************************************/ + +#include + +namespace netgen +{ + //using namespace netgen; + + + + NgException :: NgException (const string & s) + : what(s) + { + ; + } + + + NgException :: ~NgException () + { + ; + } + + /// append string to description + void NgException :: Append (const string & s) + { + what += s; + } + +} diff --git a/libsrc/general/ngexception.hpp b/libsrc/general/ngexception.hpp new file mode 100644 index 00000000..70dc0a4a --- /dev/null +++ b/libsrc/general/ngexception.hpp @@ -0,0 +1,33 @@ +#ifndef FILE_NGEXCEPTION +#define FILE_NGEXCEPTION + +/**************************************************************************/ +/* File: ngexception.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 16. Jan. 2002 */ +/**************************************************************************/ + +namespace netgen +{ + +/// Base class for all ng exceptions +class NgException +{ + /// verbal description of exception + string what; +public: + /// + DLL_HEADER NgException (const string & s); + /// + DLL_HEADER virtual ~NgException (); + + /// append string to description + DLL_HEADER void Append (const string & s); + // void Append (const char * s); + + /// verbal description of exception + const string & What() const { return what; } +}; +} + +#endif diff --git a/libsrc/general/optmem.cpp b/libsrc/general/optmem.cpp new file mode 100644 index 00000000..4d31f987 --- /dev/null +++ b/libsrc/general/optmem.cpp @@ -0,0 +1,62 @@ +/**************************************************************************/ +/* File: optmem.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 04. Apr. 97 */ +/**************************************************************************/ + +/* + Abstract data type Array +*/ + + +#include +#include + +namespace netgen +{ + + BlockAllocator :: BlockAllocator (unsigned asize, unsigned ablocks) + : bablocks (0) + { + if (asize < sizeof(void*)) + asize = sizeof(void*); + size = asize; + blocks = ablocks; + freelist = NULL; + } + + BlockAllocator :: ~BlockAllocator () + { + for (int i = 0; i < bablocks.Size(); i++) + delete [] bablocks[i]; + } + + void * BlockAllocator :: Alloc () + { + // return new char[size]; + if (!freelist) + { + // cout << "freelist = " << freelist << endl; + // cout << "BlockAlloc: " << size*blocks << endl; + char * hcp = new char [size * blocks]; + bablocks.Append (hcp); + bablocks.Last() = hcp; + for (unsigned i = 0; i < blocks-1; i++) + *(void**)&(hcp[i * size]) = &(hcp[ (i+1) * size]); + *(void**)&(hcp[(blocks-1)*size]) = NULL; + freelist = hcp; + } + + void * p = freelist; + freelist = *(void**)freelist; + return p; + } + + /* + void BlockAllocator :: Free (void * p) + { + *(void**)p = freelist; + freelist = p; + } + */ +} diff --git a/libsrc/general/optmem.hpp b/libsrc/general/optmem.hpp new file mode 100644 index 00000000..cd55f16e --- /dev/null +++ b/libsrc/general/optmem.hpp @@ -0,0 +1,62 @@ +#ifndef FILE_OPTMEM +#define FILE_OPTMEM + +/**************************************************************************/ +/* File: optmem.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 04. Apr. 97 */ +/**************************************************************************/ + +namespace netgen +{ + +/** + Optimized Memory allocation classes +*/ + +class BlockAllocator +{ +private: + /// + unsigned size, blocks; + /// + void * freelist; + /// + Array bablocks; +public: + /// + BlockAllocator (unsigned asize, unsigned ablocks = 100); + /// + ~BlockAllocator (); + /// + + void * Alloc (); + /* + { + if (!freelist) + Alloc2(); + + void * p = freelist; + // freelist = *(void**)freelist; + freelist = *static_cast (freelist); + + return p; + } + */ + + + /// + void Free (void * p) + { + *(void**)p = freelist; + freelist = p; + } + + +private: + // void Alloc2 (); +}; + +} + +#endif diff --git a/libsrc/general/parthreads.cpp b/libsrc/general/parthreads.cpp new file mode 100644 index 00000000..81e9d0b6 --- /dev/null +++ b/libsrc/general/parthreads.cpp @@ -0,0 +1,40 @@ +/**************************************************************************/ +/* File: parthreads.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + + +#include +#include + +/* + +namespace netgen +{ + using namespace netgen; + +#ifdef WIN32 + + NgLock :: NgLock (NgMutex & mut) + : sl(&mut.cs) + { + ; + } + + void NgLock :: Lock () + { + sl.Lock(); + } + void NgLock :: UnLock () + { + sl.Unlock(); + } + + +#else + +#endif +} + +*/ diff --git a/libsrc/general/parthreads.hpp b/libsrc/general/parthreads.hpp new file mode 100644 index 00000000..c1037909 --- /dev/null +++ b/libsrc/general/parthreads.hpp @@ -0,0 +1,192 @@ +#ifndef FILE_PARTHREADS +#define FILE_PARTHREADS + +/**************************************************************************/ +/* File: parthreads.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 22. Nov. 2000 */ +/**************************************************************************/ + +/* + Parallel thread, Mutex, +*/ + +namespace netgen +{ + +#ifdef NO_PARALLEL_THREADS + +class NgMutex { }; + +class NgLock +{ +public: + NgLock (NgMutex & mut, bool lock = 0) { ; } + void Lock () { ; } + void UnLock () { ; } +}; + + +#else + +#ifdef _MSC_VER + +#ifdef MSVC_EXPRESS +// #include + + +class NgMutex +{ + pthread_mutex_t mut; +public: + NgMutex () + { + pthread_mutex_init (&mut, NULL); + } + friend class NgLock; +}; + +class NgLock +{ + pthread_mutex_t & mut; + bool locked; +public: + NgLock (NgMutex & ngmut, bool lock = false) + : mut (ngmut.mut) + { + if (lock) + pthread_mutex_lock (&mut); + + locked = lock; + }; + + ~NgLock() + { + if (locked) + pthread_mutex_unlock (&mut); + } + + void Lock () + { + pthread_mutex_lock (&mut); + locked = true; + } + void UnLock () + { + pthread_mutex_unlock (&mut); + locked = false; + } + /* + int TryLock () + { + return pthread_mutex_trylock (&mut); + } + */ +}; + +#else // Using MS VC++ Standard / Enterprise / Professional edition... + + +class NgMutex +{ + CCriticalSection cs; + +public: + NgMutex () + { ; } + friend class NgLock; +}; + +class NgLock +{ + CSingleLock sl; + bool locked; +public: + NgLock (NgMutex & mut, bool lock = 0) + : sl(&mut.cs) + { + if (lock) sl.Lock(); + locked = lock; + } + + ~NgLock () + { + if (locked) sl.Unlock(); + } + + void Lock () + { + sl.Lock(); + locked = 1; + } + + void UnLock () + { + sl.Unlock(); + locked = 0; + } +}; + +#endif // MSVC_EXPRESS + +#else + + +// #include + +class NgMutex +{ + pthread_mutex_t mut; +public: + NgMutex () + { + pthread_mutex_init (&mut, NULL); + } + friend class NgLock; +}; + +class NgLock +{ + pthread_mutex_t & mut; + bool locked; +public: + NgLock (NgMutex & ngmut, bool lock = false) + : mut (ngmut.mut) + { + if (lock) + pthread_mutex_lock (&mut); + + locked = lock; + }; + + ~NgLock() + { + if (locked) + pthread_mutex_unlock (&mut); + } + + void Lock () + { + pthread_mutex_lock (&mut); + locked = true; + } + void UnLock () + { + pthread_mutex_unlock (&mut); + locked = false; + } + /* + int TryLock () + { + return pthread_mutex_trylock (&mut); + } + */ +}; + +#endif + +#endif + +} + +#endif diff --git a/libsrc/general/profiler.cpp b/libsrc/general/profiler.cpp new file mode 100644 index 00000000..06ea6934 --- /dev/null +++ b/libsrc/general/profiler.cpp @@ -0,0 +1,127 @@ +/**************************************************************************/ +/* File: profiler.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 19. Apr. 2002 */ +/**************************************************************************/ + + +#include + +namespace netgen +{ + //using namespace netgen; + + long int NgProfiler::tottimes[SIZE]; + long int NgProfiler::starttimes[SIZE]; + long int NgProfiler::counts[SIZE]; + string NgProfiler::names[SIZE]; + int NgProfiler::usedcounter[SIZE]; + + + NgProfiler :: NgProfiler() + { + for (int i = 0; i < SIZE; i++) + { + tottimes[i] = 0; + usedcounter[i] = 0; + } + + total_timer = CreateTimer ("total CPU time"); + StartTimer (total_timer); + } + + NgProfiler :: ~NgProfiler() + { +#ifndef PARALLEL + StopTimer (total_timer); +#endif + + //ofstream prof; + //prof.open("ng.prof"); + + // ofstream-constructor may be called after STL-stuff is destructed, + // which leads to an "order of destruction"-problem, + // thus we use the C-variant: + + if (getenv ("NGPROFILE")) + { + char filename[100]; +#ifdef PARALLEL + sprintf (filename, "netgen.prof.%d", id); +#else + sprintf (filename, "netgen.prof"); +#endif + + if (id == 0) printf ("write profile to file netgen.prof\n"); + FILE *prof = fopen(filename,"w"); + Print (prof); + fclose(prof); + } + } + + +// void NgProfiler :: Print (ostream & prof) +// { +// for (int i = 0; i < SIZE; i++) +// if (counts[i] != 0 || usedcounter[i] != 0) +// { +// prof.setf (ios::fixed, ios::floatfield); +// prof.setf (ios::showpoint); + +// prof // << "job " << setw(3) << i +// << "calls " << setw(8) << counts[i] +// << ", time " << setprecision(2) << setw(6) << double(tottimes[i]) / CLOCKS_PER_SEC << " sec"; + +// if (usedcounter[i]) +// prof << " " << names[i]; +// else +// prof << " " << i; + +// prof << endl; +// } +// } + + + void NgProfiler :: Print (FILE * prof) + { + for (int i = 0; i < SIZE; i++) + if (counts[i] != 0 || usedcounter[i] != 0) + { + //fprintf(prof,"job %3i calls %8i, time %6.2f sec",i,counts[i],double(tottimes[i]) / CLOCKS_PER_SEC); + fprintf(prof,"calls %8li, time %6.2f sec",counts[i],double(tottimes[i]) / CLOCKS_PER_SEC); + if(usedcounter[i]) + fprintf(prof," %s",names[i].c_str()); + else + fprintf(prof," %i",i); + fprintf(prof,"\n"); + } + } + + int NgProfiler :: CreateTimer (const string & name) + { + for (int i = SIZE-1; i > 0; i--) + if(names[i] == name) + return i; + + for (int i = SIZE-1; i > 0; i--) + if (!usedcounter[i]) + { + usedcounter[i] = 1; + names[i] = name; + return i; + } + return -1; + } + + + void NgProfiler :: ClearTimers () + { + for (int i = 0; i < SIZE; i++) + { + tottimes[i] = 0; + counts[i] = 0; + } + } + + NgProfiler prof; +} diff --git a/libsrc/general/profiler.hpp b/libsrc/general/profiler.hpp new file mode 100644 index 00000000..c39a5fbc --- /dev/null +++ b/libsrc/general/profiler.hpp @@ -0,0 +1,68 @@ +#ifndef FILE_NG_PROFILER +#define FILE_NG_PROFILER + +/**************************************************************************/ +/* File: profiler.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 5. Jan. 2005 */ +/**************************************************************************/ + + + +#ifdef VTRACE +#include "vt_user.h" +#else + #define VT_USER_START(n) + #define VT_USER_END(n) + #define VT_TRACER(n) +#endif + +namespace netgen +{ + +class NgProfiler +{ + enum { SIZE = 1000 }; + + static long int tottimes[SIZE]; + static long int starttimes[SIZE]; + static long int counts[SIZE]; + static string names[SIZE]; + static int usedcounter[SIZE]; + + int total_timer; +public: + NgProfiler(); + ~NgProfiler(); + static int CreateTimer (const string & name); + + static void StartTimer (int nr) + { + starttimes[nr] = clock(); counts[nr]++; + // VT_USER_START (const_cast (names[nr].c_str())); + VT_USER_START ( (char * const) (names[nr].c_str())); + } + static void StopTimer (int nr) + { + tottimes[nr] += clock()-starttimes[nr]; + VT_USER_END (const_cast (names[nr].c_str())); + } + + //static void Print (ostream & ost); + static void Print (FILE * prof); + + static void ClearTimers (); + + class RegionTimer + { + int nr; + public: + RegionTimer (int anr) : nr(anr) + { StartTimer (nr); } + ~RegionTimer () { StopTimer (nr); } + }; +}; + +} + +#endif diff --git a/libsrc/general/seti.cpp b/libsrc/general/seti.cpp new file mode 100644 index 00000000..e7f5b2ea --- /dev/null +++ b/libsrc/general/seti.cpp @@ -0,0 +1,70 @@ +#include +#include + + +namespace netgen +{ + //using namespace netgen; + + IndexSet :: IndexSet (int maxind) + { + SetMaxIndex (maxind); + } + + IndexSet :: ~IndexSet () + { + Clear(); + } + + + void IndexSet :: SetMaxIndex (int maxind) + { + if (maxind > flags.Size()) + { + flags.SetSize (2 * maxind); + flags.Clear(); + } + } + + /* + int IndexSet :: IsIn (int ind) const + { + return flags.Test (ind); + } + */ + + /* + void IndexSet :: Add (int ind) + { + if (ind > flags.Size()) + { + cerr << "out of range" << endl; + exit (1); + } + + if (!flags.Test(ind)) + { + set.Append (ind); + flags.Set (ind); + } + } + */ + + void IndexSet :: Del (int ind) + { + for (int i = 1; i <= set.Size(); i++) + if (set.Get(i) == ind) + { + set.DeleteElement (ind); + break; + } + flags.Clear (ind); + } + + void IndexSet :: Clear () + { + for (int i = 1; i <= set.Size(); i++) + flags.Clear (set.Get(i)); + set.SetSize (0); + } +} diff --git a/libsrc/general/seti.hpp b/libsrc/general/seti.hpp new file mode 100644 index 00000000..4adbb09c --- /dev/null +++ b/libsrc/general/seti.hpp @@ -0,0 +1,50 @@ +#ifndef FILE_SETI +#define FILE_SETI + + +/**************************************************************************/ +/* File: seti.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Mar. 98 */ +/**************************************************************************/ + +namespace netgen +{ + +/** + Set of Integers + */ +class IndexSet +{ + Array set; + BitArray flags; +public: + IndexSet (int maxind); + + ~IndexSet (); + /// increase range to maxind + void SetMaxIndex (int maxind); + int IsIn (int ind) const + { + return flags.Test (ind); + } + + void Add (int ind) + { + if (!flags.Test(ind)) + { + set.Append (ind); + flags.Set (ind); + } + } + + void Del (int ind); + void Clear (); + + const Array & GetArray() { return set; } +}; + +} + +#endif + diff --git a/libsrc/general/sort.cpp b/libsrc/general/sort.cpp new file mode 100644 index 00000000..a6adda1a --- /dev/null +++ b/libsrc/general/sort.cpp @@ -0,0 +1,75 @@ +/**************************************************************************/ +/* File: sort.cc */ +/* Author: Joachim Schoeberl */ +/* Date: 07. Jan. 00 */ +/**************************************************************************/ + +/* + Sorting +*/ + + +#include +#include +#include + +namespace netgen +{ + + void Sort (const Array & values, + Array & order) + { + int n = values.Size(); + int i, j; + + order.SetSize (n); + + for (i = 1; i <= n; i++) + order.Elem(i) = i; + for (i = 1; i <= n-1; i++) + for (j = 1; j <= n-1; j++) + if (values.Get(order.Elem(j)) > values.Get(order.Elem(j+1))) + { + Swap (order.Elem(j), order.Elem(j+1)); + } + } + + + void QuickSortRec (const Array & values, + Array & order, + int left, int right) + { + int i, j; + double midval; + + i = left; + j = right; + midval = values.Get(order.Get((i+j)/2)); + + do + { + while (values.Get(order.Get(i)) < midval) i++; + while (midval < values.Get(order.Get(j))) j--; + + if (i <= j) + { + Swap (order.Elem(i), order.Elem(j)); + i++; j--; + } + } + while (i <= j); + if (left < j) QuickSortRec (values, order, left, j); + if (i < right) QuickSortRec (values, order, i, right); + } + + void QuickSort (const Array & values, + Array & order) + { + int i, n = values.Size(); + order.SetSize (n); + for (i = 1; i <= n; i++) + order.Elem(i) = i; + + QuickSortRec (values, order, 1, order.Size()); + } +} diff --git a/libsrc/general/sort.hpp b/libsrc/general/sort.hpp new file mode 100644 index 00000000..3a9b41db --- /dev/null +++ b/libsrc/general/sort.hpp @@ -0,0 +1,46 @@ +#ifndef FILE_SORT +#define FILE_SORT + +/**************************************************************************/ +/* File: sort.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 07. Jan. 00 */ +/**************************************************************************/ + +namespace netgen +{ + +// order(i) is sorted index of element i +extern void Sort (const Array & values, + Array & order); + +extern void QuickSort (const Array & values, + Array & order); + + + + +template +inline void BubbleSort (int size, T * data) +{ + T hv; + for (int i = 0; i < size; i++) + for (int j = i+1; j < size; j++) + if (data[i] > data[j]) + { + hv = data[i]; + data[i] = data[j]; + data[j] = hv; + } +} + +template +inline void BubbleSort (Array & data) +{ + if(data.Size() > 0) + BubbleSort (data.Size(), &data[data.Begin()]); +} + +} + +#endif diff --git a/libsrc/general/spbita2d.cpp b/libsrc/general/spbita2d.cpp new file mode 100644 index 00000000..45e86413 --- /dev/null +++ b/libsrc/general/spbita2d.cpp @@ -0,0 +1,172 @@ +/**************************************************************************/ +/* File: spbita2d.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Implementation of sparse 2 dimensional bitarray +*/ + + +#include +#include + +namespace netgen +{ + //using namespace netgen; + + SPARSE_BIT_Array_2D :: SPARSE_BIT_Array_2D (int ah, int aw) + { + lines = NULL; + SetSize (ah, aw); + } + + SPARSE_BIT_Array_2D :: ~SPARSE_BIT_Array_2D () + { + DeleteElements (); + delete lines; + } + + + void SPARSE_BIT_Array_2D :: SetSize (int ah, int aw) + { + DeleteElements(); + if (lines) + { + delete lines; + lines = NULL; + } + + if (!aw) aw = ah; + + height = ah; + width = aw; + + if (!ah) return; + lines = new linestruct[ah]; + + if (lines) + { + for (int i = 0; i < ah; i++) + { + lines[i].size = 0; + lines[i].maxsize = 0; + lines[i].col = NULL; + } + } + else + { + height = width = 0; + MyError ("SPARSE_Array::SetSize: Out of memory"); + } + } + + + + void SPARSE_BIT_Array_2D :: DeleteElements () + { + if (lines) + { + for (int i = 0; i < height; i++) + { + if (lines[i].col) + { + delete [] lines[i].col; + lines[i].col = NULL; + lines[i].size = 0; + lines[i].maxsize = 0; + } + } + } + } + + + int SPARSE_BIT_Array_2D :: Test (int i, int j) const + { + int k, max, *col; + + if (!lines) return 0; + if (i < 1 || i > height) return 0; + + col = lines[i-1].col; + max = lines[i-1].size; + + for (k = 0; k < max; k++, col++) + if (*col == j) return 1; + + return 0; + } + + + + void SPARSE_BIT_Array_2D :: Set(int i, int j) + { + int k, max, *col; + + i--; + col = lines[i].col; + max = lines[i].size; + + for (k = 0; k < max; k++, col++) + if (*col == j) + return; + + if (lines[i].size) + { + if (lines[i].size == lines[i].maxsize) + { + col = new int[lines[i].maxsize+2]; + if (col) + { + lines[i].maxsize += 2; + memcpy (col, lines[i].col, sizeof (int) * lines[i].size); + delete [] lines[i].col; + lines[i].col = col; + } + else + { + MyError ("SPARSE_BIT_Array::Set: Out of mem 1"); + return; + } + } + else + col = lines[i].col; + + if (col) + { + k = lines[i].size-1; + while (k >= 0 && col[k] > j) + { + col[k+1] = col[k]; + k--; + } + + k++; + lines[i].size++; + col[k] = j; + return; + } + else + { + MyError ("SPARSE_Array::Set: Out of memory 2"); + } + } + else + { + lines[i].col = new int[4]; + if (lines[i].col) + { + lines[i].maxsize = 4; + lines[i].size = 1; + lines[i].col[0] = j; + return; + } + else + { + MyError ("SparseMatrix::Elem: Out of memory 3"); + } + } + } + +} diff --git a/libsrc/general/spbita2d.hpp b/libsrc/general/spbita2d.hpp new file mode 100644 index 00000000..ba451fc7 --- /dev/null +++ b/libsrc/general/spbita2d.hpp @@ -0,0 +1,59 @@ +#ifndef FILE_SPBITA2D +#define FILE_SPBITA2D + +/**************************************************************************/ +/* File: spbita2d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/** + Implementation of sparse 2 dimensional bitarray +*/ + +namespace netgen +{ + +class SPARSE_BIT_Array_2D + { + class linestruct { public: INDEX size; INDEX maxsize; INDEX * col; }; + + /// + linestruct * lines; + /// + INDEX height, width; + + public: + + /// + SPARSE_BIT_Array_2D (INDEX ah = 0, INDEX aw = 0); + /// + ~SPARSE_BIT_Array_2D (); + + /// + void SetSize (INDEX ah, INDEX aw = 0); + /// + void DeleteElements (); + + /// + int Get (INDEX i, INDEX j) const; + + /// + INDEX Height () const { return height; } + /// + INDEX Width () const { return width; } + + /// + void Set (INDEX i, INDEX j); + /// + int Test (INDEX i, INDEX j) const; + + /// + INDEX BitsInLine (INDEX i) const { return lines[i-1].size; } + /// + INDEX GetIndex (INDEX i, INDEX nr) const { return lines[i-1].col[nr-1]; } + }; + +} + +#endif diff --git a/libsrc/general/stack.hpp b/libsrc/general/stack.hpp new file mode 100644 index 00000000..83adee64 --- /dev/null +++ b/libsrc/general/stack.hpp @@ -0,0 +1,114 @@ +#ifndef FILE_STACK +#define FILE_STACK + +/*****************************************************************************/ +/* File: stack.hh */ +/* Author: Wolfram Muehlhuber */ +/* Date: September 98 */ +/*****************************************************************************/ + +/* + + Stack class, based on a resizable array + + */ + + +// #include "array.hpp" + +namespace netgen +{ + +/// +template class STACK +{ +public: + /// + inline STACK (INDEX asize = 0, INDEX ainc = 0); + /// + inline ~STACK (); + + /// + inline void Push (const T & el); + /// + inline T & Pop (); + /// + const inline T & Top () const; + /// + inline int IsEmpty () const; + /// + inline void MakeEmpty (); + +private: + /// + Array elems; + /// + INDEX size; +}; + + + + +/* + + Stack class, based on a resizable array + + */ + +template +inline STACK :: STACK (INDEX asize, INDEX ainc) + : elems(asize, ainc) +{ + size = 0; +} + + +template +inline STACK :: ~STACK () +{ + ; +} + + +template +inline void STACK :: Push (const T & el) +{ + if (size < elems.Size()) + elems.Elem(++size) = el; + else + { + elems.Append(el); + size++; + } +} + + +template +inline T & STACK :: Pop () +{ + return elems.Elem(size--); +} + + +template +const inline T & STACK :: Top () const +{ + return elems.Get(size); +} + +template +inline int STACK :: IsEmpty () const +{ + return (size == 0); +} + + +template +inline void STACK :: MakeEmpty () +{ + size = 0; +} + +} + +#endif diff --git a/libsrc/general/symbolta.cpp b/libsrc/general/symbolta.cpp new file mode 100644 index 00000000..bd35ac7c --- /dev/null +++ b/libsrc/general/symbolta.cpp @@ -0,0 +1,52 @@ +/**************************************************************************/ +/* File: symbolta.cc */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Abstract data type Symbol Table +*/ + +#include +#include + + +#ifndef FILE_SYMBOLTABLECC +#define FILE_SYMBOLTABLECC +// necessary for SGI ???? + + +namespace netgen +{ + //using namespace netgen; + + BASE_SYMBOLTABLE :: BASE_SYMBOLTABLE () + { + ; + } + + + BASE_SYMBOLTABLE :: ~BASE_SYMBOLTABLE() + { + DelNames(); + } + + + void BASE_SYMBOLTABLE :: DelNames() + { + for (int i = 0; i < names.Size(); i++) + delete [] names[i]; + names.SetSize (0); + } + + int BASE_SYMBOLTABLE :: Index (const char * name) const + { + if (!name) return 0; + for (int i = 0; i < names.Size(); i++) + if (strcmp (names[i], name) == 0) return i+1; + return 0; + } +} + +#endif diff --git a/libsrc/general/symbolta.hpp b/libsrc/general/symbolta.hpp new file mode 100644 index 00000000..cfb6d957 --- /dev/null +++ b/libsrc/general/symbolta.hpp @@ -0,0 +1,161 @@ +#ifndef FILE_SYMBOLTA +#define FILE_SYMBOLTA + + +/**************************************************************************/ +/* File: symbolta.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +namespace netgen +{ + +/** + Base class for the generic SYMBOLTABLE. + An array of identifiers is maintained. +*/ +class BASE_SYMBOLTABLE +{ +protected: + /// identifiers + Array names; + +public: + /// Constructor + BASE_SYMBOLTABLE (); + /// + ~BASE_SYMBOLTABLE (); + /// + void DelNames (); + /// Index of symbol name, returns 0 if not used. + int Index (const char * name) const; +}; + + +/** + Abstract data type Symbol Table. + + To a string an value of the generic type T is associated. + The string is not copied into the symbol table class! +*/ +template +class SYMBOLTABLE : public BASE_SYMBOLTABLE +{ +private: + /// Associated data + Array data; + +public: + /// Creates a symboltable + inline SYMBOLTABLE (); + /// Returns size of symboltable + inline INDEX Size() const; + /// Returns reference to element, error if not used + inline T & Elem (const char * name); + /// Returns reference to i-th element + inline T & Elem (int i) + { return data.Elem(i); } + /// Returns element, error if not used + inline const T & Get (const char * name) const; + /// Returns i-th element + inline const T & Get (int i) const; + /// Returns name of i-th element + inline const char* GetName (int i) const; + /// Associates el to the string name, overrides if name is used + inline void Set (const char * name, const T & el); + /// Checks whether name is used + inline bool Used (const char * name) const; + /// Deletes symboltable + inline void DeleteAll (); + + inline T & operator[] (int i) + { return data[i]; } + inline const T & operator[] (int i) const + { return data[i]; } + +private: + /// Prevents from copying symboltable by pointer assignment + SYMBOLTABLE & operator= (SYMBOLTABLE &); +}; + + + + +template +inline SYMBOLTABLE :: SYMBOLTABLE () +{ + ; +} + + +template +inline INDEX SYMBOLTABLE :: Size() const +{ + return data.Size(); +} + +template +inline T & SYMBOLTABLE :: Elem (const char * name) +{ + int i = Index (name); + if (i) + return data.Elem (i); + else + return data.Elem(1); +} + +template +inline const T & SYMBOLTABLE :: Get (const char * name) const +{ + int i; + i = Index (name); + if (i) + return data.Get(i); + else + return data.Get(1); +} + +template +inline const T & SYMBOLTABLE :: Get (int i) const +{ + return data.Get(i); +} + +template +inline const char* SYMBOLTABLE :: GetName (int i) const +{ + return names.Get(i); +} + +template +inline void SYMBOLTABLE :: Set (const char * name, const T & el) +{ + int i; + i = Index (name); + if (i) + data.Set(i, el); + else + { + data.Append (el); + char * hname = new char [strlen (name) + 1]; + strcpy (hname, name); + names.Append (hname); + } +} + +template +inline bool SYMBOLTABLE :: Used (const char * name) const +{ + return (Index(name)) ? true : false; +} + +template +inline void SYMBOLTABLE :: DeleteAll () +{ + DelNames(); + data.DeleteAll(); +} + +} +#endif diff --git a/libsrc/general/table.cpp b/libsrc/general/table.cpp new file mode 100644 index 00000000..d9d6cf13 --- /dev/null +++ b/libsrc/general/table.cpp @@ -0,0 +1,214 @@ +/**************************************************************************/ +/* File: table.cpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +/* + Abstract data type TABLE +*/ + +#include +#include + +namespace netgen +{ + //using namespace netgen; + + BASE_TABLE :: BASE_TABLE (int size) + : data(size) + { + for (int i = 0; i < size; i++) + { + data[i].maxsize = 0; + data[i].size = 0; + data[i].col = NULL; + } + oneblock = NULL; + } + + BASE_TABLE :: BASE_TABLE (const FlatArray & entrysizes, int elemsize) + : data(entrysizes.Size()) + { + int i, cnt = 0; + int n = entrysizes.Size(); + + for (i = 0; i < n; i++) + cnt += entrysizes[i]; + oneblock = new char[elemsize * cnt]; + // mem_total_alloc_table += elemsize * cnt; + + cnt = 0; + for (i = 0; i < n; i++) + { + data[i].maxsize = entrysizes[i]; + data[i].size = 0; + + data[i].col = &oneblock[elemsize * cnt]; + cnt += entrysizes[i]; + } + } + + BASE_TABLE :: ~BASE_TABLE () + { + if (oneblock) + delete [] oneblock; + else + { + for (int i = 0; i < data.Size(); i++) + delete [] (char*)data[i].col; + } + } + + void BASE_TABLE :: SetSize (int size) + { + for (int i = 0; i < data.Size(); i++) + delete [] (char*)data[i].col; + + data.SetSize(size); + for (int i = 0; i < size; i++) + { + data[i].maxsize = 0; + data[i].size = 0; + data[i].col = NULL; + } + } + + void BASE_TABLE :: ChangeSize (int size) + { + int oldsize = data.Size(); + if (size == oldsize) + return; + + if (size < oldsize) + for (int i = size; i < oldsize; i++) + delete [] (char*)data[i].col; + + data.SetSize(size); + + for (int i = oldsize; i < size; i++) + { + data[i].maxsize = 0; + data[i].size = 0; + data[i].col = NULL; + } + } + + void BASE_TABLE :: IncSize2 (int i, int elsize) + { +#ifdef DEBUG + if (i < 0 || i >= data.Size()) + { + MyError ("BASE_TABLE::Inc: Out of range"); + return; + } +#endif + + linestruct & line = data[i]; + if (line.size == line.maxsize) + { + void * p = new char [(line.maxsize+5) * elsize]; + + memcpy (p, line.col, line.maxsize * elsize); + delete [] (char*)line.col; + + line.col = p; + line.maxsize += 5; + } + + line.size++; + } + + + + + void BASE_TABLE :: SetEntrySize2 (int i, int newsize, int elsize) + { + linestruct & line = data[i]; + if (newsize > line.maxsize) + { + void * p = new char [newsize * elsize]; + + memcpy (p, line.col, min2 (newsize, line.size) * elsize); + delete [] (char*)line.col; + + line.col = p; + } + + line.size = newsize; + } + + + + + + /* + void BASE_TABLE :: DecSize (int i) + { +#ifdef DEBUG + if (i < 0 || i >= data.Size()) + { + MyError ("BASE_TABLE::Dec: Out of range"); + return; + } +#endif + + linestruct & line = data[i]; + +#ifdef DEBUG + if (line.size == 0) + { + MyError ("BASE_TABLE::Dec: EntrySize < 0"); + return; + } +#endif + + line.size--; + } + */ + + + + void BASE_TABLE :: AllocateElementsOneBlock (int elemsize) + { + int cnt = 0; + int n = data.Size(); + + for (int i = 0; i < n; i++) + cnt += data[i].maxsize; + oneblock = new char[elemsize * cnt]; + + cnt = 0; + for (int i = 0; i < n; i++) + { + data[i].size = 0; + data[i].col = &oneblock[elemsize * cnt]; + cnt += data[i].maxsize; + } + } + + + + int BASE_TABLE :: AllocatedElements () const + { + int els = 0; + for (int i = 0; i < data.Size(); i++) + els += data[i].maxsize; + return els; + } + + int BASE_TABLE :: UsedElements () const + { + int els = 0; + for (int i = 0; i < data.Size(); i++) + els += data[i].size; + return els; + } + + void BASE_TABLE :: SetElementSizesToMaxSizes () + { + for (int i = 0; i < data.Size(); i++) + data[i].size = data[i].maxsize; + } + +} diff --git a/libsrc/general/table.hpp b/libsrc/general/table.hpp new file mode 100644 index 00000000..f63b8074 --- /dev/null +++ b/libsrc/general/table.hpp @@ -0,0 +1,239 @@ +#ifndef FILE_TABLE +#define FILE_TABLE + +/**************************************************************************/ +/* File: table.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +namespace netgen +{ + + +/// Base class to generic class TABLE. +class BASE_TABLE +{ +protected: + + /// + class linestruct + { + public: + /// + int size; + /// + int maxsize; + /// + void * col; + }; + + /// + Array data; + char * oneblock; + +public: + /// + BASE_TABLE (int size); + /// + BASE_TABLE (const FlatArray & entrysizes, int elemsize); + /// + ~BASE_TABLE (); + /// + void SetSize (int size); + /// + void ChangeSize (int size); + + /// increment size of entry i by one, i is 0-based + void IncSize (int i, int elsize) + { + if (data[i].size < data[i].maxsize) + data[i].size++; + else + IncSize2 (i, elsize); + } + + void SetEntrySize (int i, int newsize, int elsize) + { + if (newsize < data[i].maxsize) + data[i].size = newsize; + else + SetEntrySize2 (i, newsize, elsize); + } + + /// + void IncSize2 (int i, int elsize); + void SetEntrySize2 (int i, int newsize, int elsize); + + // void DecSize (int i); + + /// + void AllocateElementsOneBlock (int elemsize); + + int AllocatedElements () const; + int UsedElements () const; + + void SetElementSizesToMaxSizes (); +}; + + + + + + + +/** + Abstract data type TABLE. + + To an integer i in the range from 1 to size a set of elements of the + generic type T is associated. +*/ +template +class TABLE : public BASE_TABLE +{ +public: + /// Creates table. + inline TABLE () : BASE_TABLE(0) { ; } + + /// Creates table of size size + inline TABLE (int size) : BASE_TABLE (size) { ; } + + /// Creates fixed maximal element size table + inline TABLE (const FlatArray & entrysizes) + : BASE_TABLE (FlatArray (entrysizes.Size(), const_cast(&entrysizes[BASE])), + sizeof(T)) + { ; } + + /// Changes Size of table to size, deletes data + inline void SetSize (int size) + { + BASE_TABLE::SetSize (size); + } + + /// Changes Size of table to size, keep data + inline void ChangeSize (int size) + { + BASE_TABLE::ChangeSize (size); + } + + + /// Inserts element acont into row i, BASE-based. Does not test if already used. + inline void Add (int i, const T & acont) + { + IncSize (i-BASE, sizeof (T)); + ((T*)data[i-BASE].col)[data[i-BASE].size-1] = acont; + } + + + /// Inserts element acont into row i, 1-based. Does not test if already used. + inline void Add1 (int i, const T & acont) + { + IncSize (i-1, sizeof (T)); + ((T*)data.Elem(i).col)[data.Elem(i).size-1] = acont; + } + + /// + void IncSizePrepare (int i) + { + data[i-BASE].maxsize++; + } + + + /// Inserts element acont into row i. BASE-based. Does not test if already used, assumes to have enough memory + inline void AddSave (int i, const T & acont) + { + ((T*)data[i-BASE].col)[data[i-BASE].size] = acont; + data[i-BASE].size++; + } + + /// Inserts element acont into row i. 1-based. Does not test if already used, assumes to have mem + inline void AddSave1 (int i, const T & acont) + { + ((T*)data.Elem(i).col)[data.Elem(i).size] = acont; + data.Elem(i).size++; + } + + /// Inserts element acont into row i. Does not test if already used. + inline void AddEmpty (int i) + { + IncSize (i-BASE, sizeof (T)); + } + + /** Set the nr-th element in the i-th row to acont. + Does not check for overflow. */ + inline void Set (int i, int nr, const T & acont) + { ((T*)data.Get(i).col)[nr-1] = acont; } + /** Returns the nr-th element in the i-th row. + Does not check for overflow. */ + inline const T & Get (int i, int nr) const + { return ((T*)data.Get(i).col)[nr-1]; } + + + /** Returns pointer to the first element in row i. */ + inline const T * GetLine (int i) const + { + return ((const T*)data.Get(i).col); + } + + + /// Returns size of the table. + inline int Size () const + { + return data.Size(); + } + + /// Returns size of the i-th row. + inline int EntrySize (int i) const + { return data.Get(i).size; } + + /* + inline void DecEntrySize (int i) + { DecSize(i); } + */ + void AllocateElementsOneBlock () + { BASE_TABLE::AllocateElementsOneBlock (sizeof(T)); } + + + inline void PrintMemInfo (ostream & ost) const + { + int els = AllocatedElements(); + ost << "table: allocaed " << els + << " a " << sizeof(T) << " Byts = " + << els * sizeof(T) + << " bytes in " << Size() << " bags." + << " used: " << UsedElements() + << endl; + } + + /// Access entry. + FlatArray operator[] (int i) const + { +#ifdef DEBUG + if (i-BASE < 0 || i-BASE >= data.Size()) + cout << "table out of range, i = " << i << ", s = " << data.Size() << endl; +#endif + + return FlatArray (data[i-BASE].size, (T*)data[i-BASE].col); + } +}; + + +template +inline ostream & operator<< (ostream & ost, const TABLE & table) +{ + for (int i = BASE; i < table.Size()+BASE; i++) + { + ost << i << ": "; + FlatArray row = table[i]; + ost << "(" << row.Size() << ") "; + for (int j = 0; j < row.Size(); j++) + ost << row[j] << " "; + ost << endl; + } + return ost; +} + +} + +#endif + diff --git a/libsrc/general/template.hpp b/libsrc/general/template.hpp new file mode 100644 index 00000000..63bdb378 --- /dev/null +++ b/libsrc/general/template.hpp @@ -0,0 +1,468 @@ +#ifndef FILE_TEMPLATE +#define FILE_TEMPLATE + +/**************************************************************************/ +/* File: template.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + +namespace netgen +{ + +/* + templates, global types, defines and variables +*/ + +/// The following value may be adapted to the hardware ! +#ifndef CLOCKS_PER_SEC +#define CLOCKS_PER_SEC 1000000 +#endif + + +// #include +/** output stream for testing. + testout is opened by main */ +DLL_HEADER extern ostream * testout; + +/** use instead of cout */ +extern ostream * mycout; + +/** error output stream */ +extern ostream * myerr; + +/** Error messages display. + Error messages are displayed by this function */ +DLL_HEADER extern void MyError (const char * ch); + + +/** Rings the bell. + Produces nr beeps. */ +extern void MyBeep (int nr = 1); + + +template +inline void Swap (T & a, T & b) +{ + T temp = a; + a = b; + b = temp; +} + +/* +template +inline void swap (T & a, T & b) +{ + T temp = a; + a = b; + b = temp; +} +*/ + + + +/** + INDEX is a typedef for (at least) 4-byte integer + */ +typedef int INDEX; + +/** + BOOL is a typedef for boolean variables + */ +// typedef int BOOL; + +typedef int ELIND; +typedef int PIND; + + +class twoint +{ +public: /// + int i1, i2; /// + twoint() {}; + /// + twoint(int ii1, int ii2) {i1 = ii1; i2 = ii2;} + friend int operator== (const twoint& t1, const twoint& t2); + /// + void Swap() {int x = i1; i1 = i2; i2 = x;} + void Sort() {if (i1 > i2) {Swap();}} +}; + +inline int operator== (const twoint& t1, const twoint& t2) +{ + return t1.i1 == t2.i1 && t1.i2 == t2.i2; +} + +class threeint +{ +public: /// + int i1, i2, i3; /// + threeint() {}; + /// + threeint(int ii1, int ii2, int ii3) {i1 = ii1; i2 = ii2; i3 = ii3;} +}; + +/// +class twodouble +{ +public: + /// + double d1, d2; + /// + twodouble() {d1 = 0; d2 = 0;}; + /// + twodouble(double id1, double id2) {d1 = id1; d2 = id2;} + /// + void Swap() {double x = d1; d1 = d2; d2 = x;} +}; + +class fourint { public: int i1, i2, i3, i4; fourint() {}; }; + + +/// +class INDEX_2; +ostream & operator<<(ostream & s, const INDEX_2 & i2); + + +class INDEX_2 +{ + /// + INDEX i[2]; + +public: + /// + INDEX_2 () { } + /// + INDEX_2 (INDEX ai1, INDEX ai2) + { i[0] = ai1; i[1] = ai2; } + + /// + INDEX_2 (const INDEX_2 & in2) + { i[0] = in2.i[0]; i[1] = in2.i[1]; } + + /// + int operator== (const INDEX_2 & in2) const + { return i[0] == in2.i[0] && i[1] == in2.i[1]; } + + /// + + + INDEX_2 Sort () + { + if (i[0] > i[1]) + { + INDEX hi = i[0]; + i[0] = i[1]; + i[1] = hi; + } + return *this; + } + + static INDEX_2 Sort (int i1, int i2) + { + if (i1 > i2) + return INDEX_2 (i2,i1); + else + return INDEX_2 (i1,i2); + } + + + /// + INDEX & I1 () { return i[0]; } + /// + INDEX & I2 () { return i[1]; } + /// + INDEX & I (int j) { return i[j-1]; } + /// + const INDEX & I1 () const { return i[0]; } + /// + const INDEX & I2 () const { return i[1]; } + /// + const INDEX & I (int j) const { return i[j-1]; } + /// + int & operator[] (int j) { return i[j]; } + /// + const int & operator[] (int j) const { return i[j]; } + /// + friend ostream & operator<<(ostream & s, const INDEX_2 & i2); +}; + + +inline INDEX_2 Sort (const INDEX_2 & i2) +{ + INDEX_2 tmp = i2; + tmp.Sort(); + return tmp; +} + + +/// +class INDEX_3 +{ + /// + INDEX i[3]; + +public: + /// + INDEX_3 () { } + /// + INDEX_3 (INDEX ai1, INDEX ai2, INDEX ai3) + { i[0] = ai1; i[1] = ai2; i[2] = ai3; } + + /// + INDEX_3 (const INDEX_3 & in2) + { i[0] = in2.i[0]; i[1] = in2.i[1]; i[2] = in2.i[2]; } + + + static INDEX_3 Sort (INDEX_3 i3) + { + return i3.Sort(); + } + + static INDEX_3 Sort (int i1, int i2, int i3) + { + if (i1 > i2) Swap (i1, i2); + if (i2 > i3) Swap (i2, i3); + if (i1 > i2) Swap (i1, i2); + return INDEX_3 (i1, i2, i3); + } + + INDEX_3 Sort () + { + if (i[0] > i[1]) Swap (i[0], i[1]); + if (i[1] > i[2]) Swap (i[1], i[2]); + if (i[0] > i[1]) Swap (i[0], i[1]); + return *this; + } + + int operator== (const INDEX_3 & in2) const + { return i[0] == in2.i[0] && i[1] == in2.i[1] && i[2] == in2.i[2];} + + /// + INDEX & I1 () { return i[0]; } + /// + INDEX & I2 () { return i[1]; } + /// + INDEX & I3 () { return i[2]; } + /// + INDEX & I (int j) { return i[j-1]; } + /// + const INDEX & I1 () const { return i[0]; } + /// + const INDEX & I2 () const { return i[1]; } + /// + const INDEX & I3 () const { return i[2]; } + /// + const INDEX & I (int j) const { return i[j-1]; } + /// + int & operator[] (int j) { return i[j]; } + /// + const int & operator[] (int j) const { return i[j]; } + + /// + friend ostream & operator<<(ostream & s, const INDEX_3 & i3); +}; + + + +/// +class INDEX_4 +{ + /// + INDEX i[4]; + +public: + /// + INDEX_4 () { } + /// + INDEX_4 (INDEX ai1, INDEX ai2, INDEX ai3, INDEX ai4) + { i[0] = ai1; i[1] = ai2; i[2] = ai3; i[3] = ai4; } + + /// + INDEX_4 (const INDEX_4 & in2) + { i[0] = in2.i[0]; i[1] = in2.i[1]; i[2] = in2.i[2]; i[3] = in2.i[3]; } + + /// + void Sort (); + + /// + int operator== (const INDEX_4 & in2) const + { return + i[0] == in2.i[0] && i[1] == in2.i[1] && + i[2] == in2.i[2] && i[3] == in2.i[3]; } + + /// + INDEX & I1 () { return i[0]; } + /// + INDEX & I2 () { return i[1]; } + /// + INDEX & I3 () { return i[2]; } + /// + INDEX & I4 () { return i[3]; } + /// + INDEX & I (int j) { return i[j-1]; } + /// + const INDEX & I1 () const { return i[0]; } + /// + const INDEX & I2 () const { return i[1]; } + /// + const INDEX & I3 () const { return i[2]; } + /// + const INDEX & I4 () const { return i[3]; } + /// + const INDEX & I (int j) const { return i[j-1]; } + /// + int & operator[] (int j) { return i[j]; } + /// + const int & operator[] (int j) const { return i[j]; } + + /// + friend ostream & operator<<(ostream & s, const INDEX_4 & i4); +}; + + + + + + + + +/// The sort preserves quads !!! +class INDEX_4Q +{ + /// + INDEX i[4]; + +public: + /// + INDEX_4Q () { } + /// + INDEX_4Q (INDEX ai1, INDEX ai2, INDEX ai3, INDEX ai4) + { i[0] = ai1; i[1] = ai2; i[2] = ai3; i[3] = ai4; } + + /// + INDEX_4Q (const INDEX_4Q & in2) + { i[0] = in2.i[0]; i[1] = in2.i[1]; i[2] = in2.i[2]; i[3] = in2.i[3]; } + + /// + void Sort (); + + /// + int operator== (const INDEX_4Q & in2) const + { return + i[0] == in2.i[0] && i[1] == in2.i[1] && + i[2] == in2.i[2] && i[3] == in2.i[3]; } + + /// + INDEX & I1 () { return i[0]; } + /// + INDEX & I2 () { return i[1]; } + /// + INDEX & I3 () { return i[2]; } + /// + INDEX & I4 () { return i[3]; } + /// + INDEX & I (int j) { return i[j-1]; } + /// + const INDEX & I1 () const { return i[0]; } + /// + const INDEX & I2 () const { return i[1]; } + /// + const INDEX & I3 () const { return i[2]; } + /// + const INDEX & I4 () const { return i[3]; } + /// + const INDEX & I (int j) const { return i[j-1]; } + /// + friend ostream & operator<<(ostream & s, const INDEX_4Q & i4); +}; + + +inline bool operator< (const INDEX_4 & a, const INDEX_4 & b) +{ + for (int j = 0; j < 4; j++) + { + if (a[j] < b[j]) return true; + if (a[j] > b[j]) return false; + } + return false; +} + + + + + + + + + + +/// +template +inline T min2 (T a, T b) +{ + /// + return (a < b) ? a : b; +} +/// +template +inline T max2 (T a, T b) +{ + /// + return (a > b) ? a : b; +} +/// +template +inline T min3 (T a, T b, T c) +{ + /// + return (a < b) ? (a < c) ? a : c + : (b < c) ? b : c; +} +/// +template +inline T max3 (T a, T b, T c) +{ + /// + return (a > b) ? ((a > c) ? a : c) + : ((b > c) ? b : c); +} + +/// + +/// +template +inline int sgn (T a) +{ + return (a > 0) ? 1 : ( ( a < 0) ? -1 : 0 ); +} + +/// +template +inline T sqr (const T a) +{ + return a * a; +} + +/// +template +inline T pow3 (const T a) +{ + return a * a * a; +} + + + +/* +template +void BubbleSort (int size, T * data); + +template +void MergeSort (int size, T * data, T * help); +*/ + + + +} + +#endif diff --git a/libsrc/geom2d/Makefile.am b/libsrc/geom2d/Makefile.am new file mode 100644 index 00000000..5e0b326b --- /dev/null +++ b/libsrc/geom2d/Makefile.am @@ -0,0 +1,21 @@ +noinst_HEADERS = geom2dmesh.hpp geometry2d.hpp vsgeom2d.hpp + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(TCL_INCLUDES) + +METASOURCES = AUTO + +lib_LTLIBRARIES = libgeom2d.la + +if NGGUI +lib_LTLIBRARIES += libgeom2dvis.la +endif + + + +libgeom2d_la_SOURCES = genmesh2d.cpp geom2dmesh.cpp geometry2d.cpp +libgeom2d_la_LIBADD = $(top_builddir)/libsrc/meshing/libmesh.la + +libgeom2dvis_la_SOURCES = geom2dpkg.cpp vsgeom2d.cpp +libgeom2dvis_la_LIBADD = libgeom2d.la + + diff --git a/libsrc/geom2d/Makefile.in b/libsrc/geom2d/Makefile.in new file mode 100644 index 00000000..405e1b35 --- /dev/null +++ b/libsrc/geom2d/Makefile.in @@ -0,0 +1,604 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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@ +@NGGUI_TRUE@am__append_1 = libgeom2dvis.la +subdir = libsrc/geom2d +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libgeom2d_la_DEPENDENCIES = $(top_builddir)/libsrc/meshing/libmesh.la +am_libgeom2d_la_OBJECTS = genmesh2d.lo geom2dmesh.lo geometry2d.lo +libgeom2d_la_OBJECTS = $(am_libgeom2d_la_OBJECTS) +libgeom2dvis_la_DEPENDENCIES = libgeom2d.la +am_libgeom2dvis_la_OBJECTS = geom2dpkg.lo vsgeom2d.lo +libgeom2dvis_la_OBJECTS = $(am_libgeom2dvis_la_OBJECTS) +@NGGUI_TRUE@am_libgeom2dvis_la_rpath = -rpath $(libdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgeom2d_la_SOURCES) $(libgeom2dvis_la_SOURCES) +DIST_SOURCES = $(libgeom2d_la_SOURCES) $(libgeom2dvis_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = geom2dmesh.hpp geometry2d.hpp vsgeom2d.hpp +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(TCL_INCLUDES) +METASOURCES = AUTO +lib_LTLIBRARIES = libgeom2d.la $(am__append_1) +libgeom2d_la_SOURCES = genmesh2d.cpp geom2dmesh.cpp geometry2d.cpp +libgeom2d_la_LIBADD = $(top_builddir)/libsrc/meshing/libmesh.la +libgeom2dvis_la_SOURCES = geom2dpkg.cpp vsgeom2d.cpp +libgeom2dvis_la_LIBADD = libgeom2d.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/geom2d/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/geom2d/Makefile +.PRECIOUS: 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): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgeom2d.la: $(libgeom2d_la_OBJECTS) $(libgeom2d_la_DEPENDENCIES) $(EXTRA_libgeom2d_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libgeom2d_la_OBJECTS) $(libgeom2d_la_LIBADD) $(LIBS) +libgeom2dvis.la: $(libgeom2dvis_la_OBJECTS) $(libgeom2dvis_la_DEPENDENCIES) $(EXTRA_libgeom2dvis_la_DEPENDENCIES) + $(CXXLINK) $(am_libgeom2dvis_la_rpath) $(libgeom2dvis_la_OBJECTS) $(libgeom2dvis_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genmesh2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geom2dmesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geom2dpkg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geometry2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsgeom2d.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + 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-libLTLIBRARIES + +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: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES 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 uninstall uninstall-am uninstall-libLTLIBRARIES + + +# 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/libsrc/geom2d/genmesh2d.cpp b/libsrc/geom2d/genmesh2d.cpp new file mode 100644 index 00000000..56dfcf96 --- /dev/null +++ b/libsrc/geom2d/genmesh2d.cpp @@ -0,0 +1,612 @@ +#include +#include + +namespace netgen +{ + extern DLL_HEADER MeshingParameters mparam; + + extern void Optimize2d (Mesh & mesh, MeshingParameters & mp); + + + + + void CalcPartition (const SplineSegExt & spline, + // double l, + MeshingParameters & mp, Mesh & mesh, + // double h, double h1, double h2, double hcurve, + double elto0, Array & points) + { + double fperel, oldf, f; + + int n = 10000; + + Array > xi(n); + Array hi(n); + + for (int i = 0; i < n; i++) + { + xi[i] = spline.GetPoint ( (i+0.5) / n ); + hi[i] = mesh.GetH (Point<3> (xi[i](0), xi[i](1), 0)); + } + + // limit slope + double gradh = 1/elto0; + for (int i = 0; i < n-1; i++) + { + double hnext = hi[i] + gradh * (xi[i+1]-xi[i]).Length(); + hi[i+1] = min(hi[i+1], hnext); + } + for (int i = n-1; i > 1; i--) + { + double hnext = hi[i] + gradh * (xi[i-1]-xi[i]).Length(); + hi[i-1] = min(hi[i-1], hnext); + } + + points.SetSize (0); + + double len = spline.Length(); + double dt = len / n; + + double sum = 0; + for (int i = 1; i <= n; i++) + { + double t = (i-0.5)*dt; + double fun = hi[i-1]; + sum += dt / fun; + } + + int nel = int (sum+1); + fperel = sum / nel; + + points.Append (0); + + int i = 1; + oldf = 0; + + for (int j = 1; j <= n && i < nel; j++) + { + double t = (j-0.5)*dt; + double fun = hi[j-1]; + + f = oldf + dt / fun; + + while (i * fperel < f && i < nel) + { + points.Append ( dt * (j-1) + (i * fperel - oldf) * fun); + i++; + } + oldf = f; + t += dt; + } + points.Append (len); + } + + + + + + + + + + // partitionizes spline curve + void Partition (const SplineSegExt & spline, + MeshingParameters & mp, double hxxx, double elto0, + Mesh & mesh, Point3dTree & searchtree, int segnr) + { + int n = 100; + + Point<2> mark, oldmark; + Array curvepoints; + double edgelength, edgelengthold; + + CalcPartition (spline, mp, mesh, elto0, curvepoints); + + double dt = 1.0 / n; + + int j = 1; + + Point<2> pold = spline.GetPoint (0); + double lold = 0; + oldmark = pold; + edgelengthold = 0; + Array locsearch; + + for (int i = 1; i <= n; i++) + { + Point<2> p = spline.GetPoint (i*dt); + double l = lold + Dist (p, pold); + while (j < curvepoints.Size() && (l >= curvepoints[j] || i == n)) + { + double frac = (curvepoints[j]-lold) / (l-lold); + edgelength = i*dt + (frac-1)*dt; + mark = spline.GetPoint (edgelength); + + { + PointIndex pi1 = -1, pi2 = -1; + + Point3d mark3(mark(0), mark(1), 0); + Point3d oldmark3(oldmark(0), oldmark(1), 0); + + double h = mesh.GetH (Point<3> (oldmark(0), oldmark(1), 0)); + Vec<3> v (1e-4*h, 1e-4*h, 1e-4*h); + searchtree.GetIntersecting (oldmark3 - v, oldmark3 + v, locsearch); + + for (int k = 0; k < locsearch.Size(); k++) + if ( mesh[PointIndex(locsearch[k])].GetLayer() == spline.layer) + pi1 = locsearch[k]; + + searchtree.GetIntersecting (mark3 - v, mark3 + v, locsearch); + for (int k = 0; k < locsearch.Size(); k++) + if ( mesh[PointIndex(locsearch[k])].GetLayer() == spline.layer) + pi2 = locsearch[k]; + + if (pi1 == -1) + { + pi1 = mesh.AddPoint(oldmark3, spline.layer); + searchtree.Insert (oldmark3, pi1); + } + if (pi2 == -1) + { + pi2 = mesh.AddPoint(mark3, spline.layer); + searchtree.Insert (mark3, pi2); + } + + Segment seg; + seg.edgenr = segnr; + seg.si = spline.bc; // segnr; + seg[0] = pi1; + seg[1] = pi2; + seg.domin = spline.leftdom; + seg.domout = spline.rightdom; + seg.epgeominfo[0].edgenr = segnr; + seg.epgeominfo[0].dist = edgelengthold; + seg.epgeominfo[1].edgenr = segnr; + seg.epgeominfo[1].dist = edgelength; + seg.singedge_left = spline.hpref_left; + seg.singedge_right = spline.hpref_right; + mesh.AddSegment (seg); + } + + oldmark = mark; + edgelengthold = edgelength; + j++; + } + + pold = p; + lold = l; + } + } + + + + void SplineGeometry2d :: PartitionBoundary (MeshingParameters & mp, double h, Mesh & mesh2d) + { + enum { D = 2 }; + Box bbox; + GetBoundingBox (bbox); + double dist = Dist (bbox.PMin(), bbox.PMax()); + Point<3> pmin; + Point<3> pmax; + + pmin(2) = -dist; pmax(2) = dist; + for(int j=0;j & p1 = spline.StartPI(); + const GeomPoint<2> & p2 = spline.EndPI(); + + double h1 = min (p1.hmax, h/p1.refatpoint); + mesh2d.RestrictLocalH (Point<3>(p1(0),p1(1),0), h1); + double h2 = min (p2.hmax, h/p2.refatpoint); + mesh2d.RestrictLocalH (Point<3>(p2(0),p2(1),0), h2); + + double len = spline.Length(); + mesh2d.RestrictLocalHLine (Point<3>(p1(0),p1(1),0), + Point<3>(p2(0),p2(1),0), len/mp.segmentsperedge); + + double hcurve = min (spline.hmax, h/spline.reffak); + double hl = GetDomainMaxh (spline.leftdom); + if (hl > 0) hcurve = min2 (hcurve, hl); + double hr = GetDomainMaxh (spline.rightdom); + if (hr > 0) hcurve = min2 (hcurve, hr); + + int np = 1000; + for (double t = 0.5/np; t < 1; t += 1.0/np) + { + Point<2> x = spline.GetPoint(t); + double hc = 1.0/mp.curvaturesafety / (1e-99+spline.CalcCurvature (t)); + mesh2d.RestrictLocalH (Point<3> (x(0), x(1), 0), min2(hc, hcurve)); + } + } + + for (int i = 0; i < splines.Size(); i++) + if (GetSpline(i).copyfrom == -1) + { + // astrid - set boundary meshsize to domain meshsize h + // if no domain mesh size is given, the max h value from the bounding box is used + double hl = GetDomainMaxh ( GetSpline(i).leftdom ); + double hr = GetDomainMaxh ( GetSpline(i).rightdom ); + + double useh = h; + if (hl > 0) useh = min2 (h, hl); + if (hr > 0) useh = min2 (h, hr); + Partition(GetSpline(i), mp, useh, elto0, mesh2d, searchtree, i+1); + } + else + { + CopyEdgeMesh (GetSpline(i).copyfrom, i+1, mesh2d, searchtree); + } + } + + + + + + + void SplineGeometry2d :: CopyEdgeMesh (int from, int to, Mesh & mesh, Point3dTree & searchtree) + { + // const int D = 2; + + Array mappoints (mesh.GetNP()); + Array param (mesh.GetNP()); + mappoints = -1; + param = 0; + + Point3d pmin, pmax; + mesh.GetBox (pmin, pmax); + double diam2 = Dist2(pmin, pmax); + + if (printmessage_importance>0) + cout << "copy edge, from = " << from << " to " << to << endl; + + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + if (seg.edgenr == from) + { + mappoints.Elem(seg[0]) = 1; + param.Elem(seg[0]) = seg.epgeominfo[0].dist; + + mappoints.Elem(seg[1]) = 1; + param.Elem(seg[1]) = seg.epgeominfo[1].dist; + } + } + + bool mapped = false; + for (int i = 1; i <= mappoints.Size(); i++) + { + if (mappoints.Get(i) != -1) + { + Point<2> newp = splines.Get(to)->GetPoint (param.Get(i)); + Point<3> newp3 (newp(0), newp(1), 0); + + int npi = -1; + + for (PointIndex pi = PointIndex::BASE; + pi < mesh.GetNP()+PointIndex::BASE; pi++) + if (Dist2 (mesh.Point(pi), newp3) < 1e-12 * diam2) + npi = pi; + + if (npi == -1) + { + npi = mesh.AddPoint (newp3); + searchtree.Insert (newp3, npi); + } + + mappoints.Elem(i) = npi; + + mesh.GetIdentifications().Add (i, npi, to); + mapped = true; + } + } + if(mapped) + mesh.GetIdentifications().SetType(to,Identifications::PERIODIC); + + // copy segments + int oldnseg = mesh.GetNSeg(); + for (int i = 1; i <= oldnseg; i++) + { + const Segment & seg = mesh.LineSegment(i); + if (seg.edgenr == from) + { + Segment nseg; + nseg.edgenr = to; + nseg.si = GetSpline(to-1).bc; // splines.Get(to)->bc; + nseg[0] = mappoints.Get(seg[0]); + nseg[1] = mappoints.Get(seg[1]); + nseg.domin = GetSpline(to-1).leftdom; + nseg.domout = GetSpline(to-1).rightdom; + + nseg.epgeominfo[0].edgenr = to; + nseg.epgeominfo[0].dist = param.Get(seg[0]); + nseg.epgeominfo[1].edgenr = to; + nseg.epgeominfo[1].dist = param.Get(seg[1]); + mesh.AddSegment (nseg); + } + } + } + + + + + + void MeshFromSpline2D (SplineGeometry2d & geometry, + Mesh *& mesh, + MeshingParameters & mp) + { + PrintMessage (1, "Generate Mesh from spline geometry"); + + double h = mp.maxh; + + Box<2> bbox = geometry.GetBoundingBox (); + + if (bbox.Diam() < h) + { + h = bbox.Diam(); + mp.maxh = h; + } + + mesh = new Mesh; + mesh->SetDimension (2); + + Point3d pmin(bbox.PMin()(0), bbox.PMin()(1), -bbox.Diam()); + Point3d pmax(bbox.PMax()(0), bbox.PMax()(1), bbox.Diam()); + + mesh->SetLocalH (pmin, pmax, mparam.grading); + mesh->SetGlobalH (h); + + + + geometry.PartitionBoundary (mp, h, *mesh); + + + // marks mesh points for hp-refinement + for (int i = 0; i < geometry.GetNP(); i++) + if (geometry.GetPoint(i).hpref) + { + double mindist = 1e99; + PointIndex mpi(0); + Point<2> gp = geometry.GetPoint(i); + Point<3> gp3(gp(0), gp(1), 0); + for (PointIndex pi = PointIndex::BASE; + pi < mesh->GetNP()+PointIndex::BASE; pi++) + if (Dist2(gp3, (*mesh)[pi]) < mindist) + { + mpi = pi; + mindist = Dist2(gp3, (*mesh)[pi]); + } + (*mesh)[mpi].Singularity(1.); + } + + + int maxdomnr = 0; + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + { + if ( (*mesh)[si].domin > maxdomnr) maxdomnr = (*mesh)[si].domin; + if ( (*mesh)[si].domout > maxdomnr) maxdomnr = (*mesh)[si].domout; + } + + mesh->ClearFaceDescriptors(); + for (int i = 1; i <= maxdomnr; i++) + mesh->AddFaceDescriptor (FaceDescriptor (i, 0, 0, i)); + + // set Array bcnames... + // number of bcnames + int maxsegmentindex = 0; + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + { + if ( (*mesh)[si].si > maxsegmentindex) maxsegmentindex = (*mesh)[si].si; + } + + mesh->SetNBCNames(maxsegmentindex); + + for ( int sindex = 0; sindex < maxsegmentindex; sindex++ ) + mesh->SetBCName ( sindex, geometry.GetBCName( sindex+1 ) ); + + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + (*mesh)[si].SetBCName ( (*mesh).GetBCNamePtr( (*mesh)[si].si-1 ) ); + + + mesh->CalcLocalH(mparam.grading); + + int bnp = mesh->GetNP(); // boundary points + + int hquad = mparam.quad; + + + for (int domnr = 1; domnr <= maxdomnr; domnr++) + if (geometry.GetDomainTensorMeshing (domnr)) + { // tensor product mesh + + Array nextpi(bnp); + Array si1(bnp), si2(bnp); + PointIndex firstpi; + + nextpi = -1; + si1 = -1; + si2 = -1; + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + { + int p1 = -1, p2 = -2; + + if ( (*mesh)[si].domin == domnr) + { p1 = (*mesh)[si][0]; p2 = (*mesh)[si][1]; } + if ( (*mesh)[si].domout == domnr) + { p1 = (*mesh)[si][1]; p2 = (*mesh)[si][0]; } + + if (p1 == -1) continue; + + nextpi[p1] = p2; // counter-clockwise + + int index = (*mesh)[si].si; + if (si1[p1] != index && si2[p1] != index) + { si2[p1] = si1[p1]; si1[p1] = index; } + if (si1[p2] != index && si2[p2] != index) + { si2[p2] = si1[p2]; si1[p2] = index; } + } + + PointIndex c1(0), c2, c3, c4; // 4 corner points + int nex = 1, ney = 1; + + for (PointIndex pi = 1; pi <= si2.Size(); pi++) + if (si2[pi] != -1) + { c1 = pi; break; } + + for (c2 = nextpi[c1]; si2[c2] == -1; c2 = nextpi[c2], nex++); + for (c3 = nextpi[c2]; si2[c3] == -1; c3 = nextpi[c3], ney++); + for (c4 = nextpi[c3]; si2[c4] == -1; c4 = nextpi[c4]); + + + + Array pts ( (nex+1) * (ney+1) ); // x ... inner loop + pts = -1; + + for (PointIndex pi = c1, i = 0; pi != c2; pi = nextpi[pi], i++) + pts[i] = pi; + for (PointIndex pi = c2, i = 0; pi != c3; pi = nextpi[pi], i++) + pts[(nex+1)*i+nex] = pi; + for (PointIndex pi = c3, i = 0; pi != c4; pi = nextpi[pi], i++) + pts[(nex+1)*(ney+1)-i-1] = pi; + for (PointIndex pi = c4, i = 0; pi != c1; pi = nextpi[pi], i++) + pts[(nex+1)*(ney-i)] = pi; + + + for (PointIndex pix = nextpi[c1], ix = 0; pix != c2; pix = nextpi[pix], ix++) + for (PointIndex piy = nextpi[c2], iy = 0; piy != c3; piy = nextpi[piy], iy++) + { + Point<3> p = (*mesh)[pix] + ( (*mesh)[piy] - (*mesh)[c2] ); + pts[(nex+1)*(iy+1) + ix+1] = mesh -> AddPoint (p , 1, FIXEDPOINT); + } + + for (int i = 0; i < ney; i++) + for (int j = 0; j < nex; j++) + { + Element2d el(QUAD); + el[0] = pts[i*(nex+1)+j]; + el[1] = pts[i*(nex+1)+j+1]; + el[2] = pts[(i+1)*(nex+1)+j+1]; + el[3] = pts[(i+1)*(nex+1)+j]; + el.SetIndex (domnr); + + mesh -> AddSurfaceElement (el); + } + } + + + + + for (int domnr = 1; domnr <= maxdomnr; domnr++) + { + if (geometry.GetDomainTensorMeshing (domnr)) continue; + + if ( geometry.GetDomainMaxh ( domnr ) > 0 ) + h = geometry.GetDomainMaxh(domnr); + + + PrintMessage (3, "Meshing domain ", domnr, " / ", maxdomnr); + + int oldnf = mesh->GetNSE(); + + mparam.quad = hquad || geometry.GetDomainQuadMeshing (domnr); + + Meshing2 meshing (mparam, Box<3> (pmin, pmax)); + + Array compress(bnp); + compress = -1; + int cnt = 0; + for (PointIndex pi = PointIndex::BASE; pi < bnp+PointIndex::BASE; pi++) + if ( (*mesh)[pi].GetLayer() == geometry.GetDomainLayer(domnr)) + { + meshing.AddPoint ( (*mesh)[pi], pi); + cnt++; + compress[pi] = cnt; + } + + PointGeomInfo gi; + gi.trignum = 1; + for (SegmentIndex si = 0; si < mesh->GetNSeg(); si++) + { + if ( (*mesh)[si].domin == domnr) + { + meshing.AddBoundaryElement ( compress[(*mesh)[si][0]], + compress[(*mesh)[si][1]], gi, gi); + } + if ( (*mesh)[si].domout == domnr) + { + meshing.AddBoundaryElement ( compress[(*mesh)[si][1]], + compress[(*mesh)[si][0]], gi, gi); + + } + + } + + + mparam.checkoverlap = 0; + + meshing.GenerateMesh (*mesh, mparam, h, domnr); + + for (SurfaceElementIndex sei = oldnf; sei < mesh->GetNSE(); sei++) + (*mesh)[sei].SetIndex (domnr); + + + // astrid + char * material; + geometry.GetMaterial( domnr, material ); + if ( material ) + { + (*mesh).SetMaterial ( domnr, material ); + } + + } + + mparam.quad = hquad; + + + + int hsteps = mp.optsteps2d; + + mp.optimize2d = "smcm"; + mp.optsteps2d = hsteps/2; + Optimize2d (*mesh, mp); + + mp.optimize2d = "Smcm"; + mp.optsteps2d = (hsteps+1)/2; + Optimize2d (*mesh, mp); + + mp.optsteps2d = hsteps; + + mesh->Compress(); + mesh -> SetNextMajorTimeStamp(); + + + extern DLL_HEADER void Render(); + Render(); + } + + + + + + + + +} diff --git a/libsrc/geom2d/geom2dmesh.cpp b/libsrc/geom2d/geom2dmesh.cpp new file mode 100644 index 00000000..87472d21 --- /dev/null +++ b/libsrc/geom2d/geom2dmesh.cpp @@ -0,0 +1,82 @@ +#include +#include + +namespace netgen +{ + + Refinement2d :: Refinement2d (const SplineGeometry2d & ageometry) + : Refinement(), geometry(ageometry) + { + ; + } + + Refinement2d :: ~Refinement2d () + { + ; + } + + + void Refinement2d :: + PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const + { + newp = p1+secpoint*(p2-p1); + newgi.trignum = 1; + } + + + + void Refinement2d :: + PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const + { + Point<2> p2d; + + p2d = geometry.GetSplines().Get(ap1.edgenr) -> + GetPoint (((1-secpoint)*ap1.dist+secpoint*ap2.dist)); + + // (*testout) << "refine 2d line, ap1.dist, ap2.dist = " << ap1.dist << ", " << ap2.dist << endl; + // (*testout) << "p1, p2 = " << p1 << p2 << ", newp = " << p2d << endl; + + newp = Point3d (p2d(0), p2d(1), 0); + newgi.edgenr = ap1.edgenr; + newgi.dist = ((1-secpoint)*ap1.dist+secpoint*ap2.dist); + }; + + + + Vec<3> Refinement2d :: GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const + { + Vec<2> t2d = geometry.GetSplines().Get(ap1.edgenr) -> GetTangent(ap1.dist); + return Vec<3> (t2d(0), t2d(1), 0); + } + + Vec<3> Refinement2d :: GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const + { + return Vec<3> (0,0,1); + } + + + void Refinement2d :: ProjectToSurface (Point<3> & p, int surfi, const PointGeomInfo & /* gi */) const + { + p(2) = 0; + } + + + void Refinement2d :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & egi) const + { + Point<2> p2d (p(0), p(1)), pp; + double t; + geometry.GetSplines().Get(egi.edgenr) -> Project (p2d, pp, t); + p = Point<3> (pp(0), pp(1), 0); + } +} diff --git a/libsrc/geom2d/geom2dmesh.hpp b/libsrc/geom2d/geom2dmesh.hpp new file mode 100644 index 00000000..9b72216d --- /dev/null +++ b/libsrc/geom2d/geom2dmesh.hpp @@ -0,0 +1,52 @@ +#ifndef FILE_GEOM2DMESH +#define FILE_GEOM2DMESH + +/**************************************************************************/ +/* File: geom2dmesh.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 22. Jan. 01 */ +/**************************************************************************/ + + +namespace netgen +{ + + class Refinement2d : public Refinement + { + const class SplineGeometry2d & geometry; + + public: + Refinement2d (const class SplineGeometry2d & ageometry); + virtual ~Refinement2d (); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const; + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const; + + + virtual Vec<3> GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const; + + virtual Vec<3> GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const; + + virtual void ProjectToSurface (Point<3> & p, int surfi, const PointGeomInfo & /* gi */) const; + + virtual void ProjectToEdge (Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & egi) const; + }; + + +} + + + +#endif diff --git a/libsrc/geom2d/geom2dpkg.cpp b/libsrc/geom2d/geom2dpkg.cpp new file mode 100644 index 00000000..15a64531 --- /dev/null +++ b/libsrc/geom2d/geom2dpkg.cpp @@ -0,0 +1,54 @@ +#include +#include +#include + +#include "vsgeom2d.hpp" + +// extern "C" int Ng_CSG_Init (Tcl_Interp * interp); + +namespace netgen +{ + + + // extern DLL_HEADER NetgenGeometry * ng_geometry; + static VisualSceneGeometry2d vsgeom2d; + + + + + + class SplineGeometryVisRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const { return NULL; } + virtual VisualScene * GetVisualScene (const NetgenGeometry * geom) const; + }; + + + VisualScene * SplineGeometryVisRegister :: GetVisualScene (const NetgenGeometry * geom) const + { + const SplineGeometry2d * geometry = dynamic_cast (geom); + if (geometry) + { + vsgeom2d.SetGeometry (geometry); + return &vsgeom2d; + } + return NULL; + } + + +} + + +using namespace netgen; +#ifdef WIN32 +extern "C" __declspec(dllexport) int Ng_geom2d_Init (Tcl_Interp * interp); +#else +extern "C" int Ng_geom2d_Init (Tcl_Interp * interp); +#endif + +int Ng_geom2d_Init (Tcl_Interp * interp) +{ + geometryregister.Append (new SplineGeometryVisRegister); + return TCL_OK; +} diff --git a/libsrc/geom2d/geometry2d.cpp b/libsrc/geom2d/geometry2d.cpp new file mode 100644 index 00000000..ffce88f2 --- /dev/null +++ b/libsrc/geom2d/geometry2d.cpp @@ -0,0 +1,985 @@ +/* + +2d Spline curve for Mesh generator + +*/ + +#include +#include + +namespace netgen +{ + + + + SplineGeometry2d :: ~SplineGeometry2d() + { + for ( int i = 0; i < bcnames.Size(); i++ ) + delete bcnames[i]; + for (int i=0; i x; + char buf[50]; + + + infile.open (filename); + + if ( ! infile.good() ) + throw NgException(string ("Input file '") + + string (filename) + + string ("' not available!")); + + TestComment ( infile ); + + infile >> buf; // file recognition + + tensormeshing.SetSize(0); + quadmeshing.SetSize(0); + + TestComment ( infile ); + if ( strcmp (buf, "splinecurves2dnew") == 0 ) + { + LoadDataNew ( infile ); + } + else if ( strcmp (buf, "splinecurves2dv2") == 0 ) + { + LoadDataV2 ( infile ); + } + else + { + LoadData(infile ); + } + infile.close(); + } + + + + // herbert: fixed TestComment + void SplineGeometry2d :: TestComment ( ifstream & infile ) + { + bool comment = true; + char ch; + while ( comment == true && !infile.eof() ) { + infile.get(ch); + if ( ch == '#' ) { // skip comments + while ( ch != '\n' && !infile.eof() ) { + infile.get(ch); + } + } + else if ( ch == '\n' ) { // skip empty lines + ; + } + else if ( isspace(ch) ) { // skip whitespaces + ; + } + else { // end of comment + infile.putback(ch); + comment = false; + } + } + return; + } + + + + + void SplineGeometry2d :: LoadData ( ifstream & infile ) + { + enum { D = 2 }; + + int nump, numseg, leftdom, rightdom; + Point x; + int hi1, hi2, hi3; + double hd; + char buf[50], ch; + + materials.SetSize(0); + maxh.SetSize(0); + infile >> elto0; + + TestComment ( infile ); + + infile >> nump; + for (int i = 0; i < nump; i++) + { + TestComment ( infile ); + for(int j=0; j> x(j); + infile >> hd; + + Flags flags; + + ch = 'a'; + // infile >> ch; + do { + infile.get (ch); + } while (isspace(ch) && ch != '\n'); + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + do { + infile.get (ch); + } while (isspace(ch) && ch != '\n'); + } + + if (infile.good()) + infile.putback (ch); + + geompoints.Append (GeomPoint(x, hd)); + geompoints.Last().hpref = flags.GetDefineFlag ("hpref"); + geompoints.Last().hmax = 1e99; + } + + PrintMessage (3, nump, " points loaded"); + TestComment ( infile ); + + infile >> numseg; + bcnames.SetSize(numseg); + for ( int i = 0; i < numseg; i++ ) + bcnames[i] = 0; // "default"; + + SplineSeg * spline = 0; + + PrintMessage (3, numseg, " segments loaded"); + for (int i = 0; i < numseg; i++) + { + TestComment ( infile ); + + infile >> leftdom >> rightdom; + + // cout << "add spline " << i << ", left = " << leftdom << ", right = " << rightdom << endl; + + infile >> buf; + // type of spline segement + if (strcmp (buf, "2") == 0) + { // a line + infile >> hi1 >> hi2; + spline = new LineSeg(geompoints[hi1-1], + geompoints[hi2-1]); + } + else if (strcmp (buf, "3") == 0) + { // a rational spline + infile >> hi1 >> hi2 >> hi3; + spline = new SplineSeg3 (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + } + else if (strcmp (buf, "4") == 0) + { // an arc + infile >> hi1 >> hi2 >> hi3; + spline = new CircleSeg (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + // break; + } + else if (strcmp (buf, "discretepoints") == 0) + { + int npts; + infile >> npts; + Array< Point > pts(npts); + for (int j = 0; j < npts; j++) + for(int k=0; k> pts[j](k); + + spline = new DiscretePointsSeg (pts); + } + + + SplineSegExt * spex = new SplineSegExt (*spline); + + infile >> spex->reffak; + spex -> leftdom = leftdom; + spex -> rightdom = rightdom; + spex -> hmax = 1e99; + splines.Append (spex); + + + Flags flags; + ch = 'a'; + infile >> ch; + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + infile >> ch; + } + + if (infile.good()) + infile.putback (ch); + + spex->bc = int (flags.GetNumFlag ("bc", i+1)); + spex->hpref_left = int (flags.GetDefineFlag ("hpref")) || + int (flags.GetDefineFlag ("hprefleft")); + spex->hpref_right = int (flags.GetDefineFlag ("hpref")) || + int (flags.GetDefineFlag ("hprefright")); + spex->copyfrom = int (flags.GetNumFlag ("copy", -1)); + if ( flags.StringFlagDefined("bcname") ) + { + int mybc = spex->bc-1; + delete bcnames[mybc]; + bcnames[mybc] = new string (flags.GetStringFlag("bcname","") ); + } + } + } + + + + + void SplineGeometry2d :: LoadDataNew ( ifstream & infile ) + { + enum { D = 2 }; + int nump, numseg, leftdom, rightdom; + Point x; + int hi1, hi2, hi3; + double hd; + char buf[50], ch; + int pointnr; + + + TestComment ( infile ); + infile >> elto0; + TestComment ( infile ); + + infile >> nump; + geompoints.SetSize(nump); + + for (int i = 0; i < nump; i++) + { + TestComment ( infile ); + infile >> pointnr; + if ( pointnr > nump ) + { + throw NgException(string ("Point number greater than total number of points") ); + } + for(int j=0; j> x(j); + + + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + + Flags flags; + + + // get flags, + ch = 'a'; + // infile >> ch; + do + { + + infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + infile.get(ch); + } + } + while (isspace(ch) && ch != '\n'); + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + do { + infile.get (ch); + } while (isspace(ch) && ch != '\n'); + } + + if (infile.good()) + infile.putback (ch); + + if ( hd == 1 ) + hd = flags.GetNumFlag ( "ref", 1.0); + // geompoints.Append (GeomPoint(x, hd)); + geompoints[pointnr-1] = GeomPoint(x, hd); + geompoints[pointnr-1].hpref = flags.GetDefineFlag ("hpref"); + } + + TestComment ( infile ); + + infile >> numseg; + bcnames.SetSize(numseg); + for ( int i = 0; i < numseg; i++ ) + bcnames[i] = 0;//new"default"; + + SplineSeg * spline = 0; + for (int i = 0; i < numseg; i++) + { + TestComment ( infile ); + + infile >> leftdom >> rightdom; + + // cout << "add spline " << i << ", left = " << leftdom << endl; + + infile >> buf; + // type of spline segement + if (strcmp (buf, "2") == 0) + { // a line + infile >> hi1 >> hi2; + spline = new LineSeg (geompoints[hi1-1], + geompoints[hi2-1]); + } + else if (strcmp (buf, "3") == 0) + { // a rational spline + infile >> hi1 >> hi2 >> hi3; + spline = new SplineSeg3 (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + } + else if (strcmp (buf, "4") == 0) + { // an arc + infile >> hi1 >> hi2 >> hi3; + spline = new CircleSeg (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + // break; + } + else if (strcmp (buf, "discretepoints") == 0) + { + int npts; + infile >> npts; + Array< Point > pts(npts); + for (int j = 0; j < npts; j++) + for(int k=0; k> pts[j](k); + + spline = new DiscretePointsSeg (pts); + } + + // infile >> spline->reffak; + + SplineSegExt * spex = new SplineSegExt (*spline); + + spex -> leftdom = leftdom; + spex -> rightdom = rightdom; + splines.Append (spex); + + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + infile >> ch; + + // get refinement parameter, if it is there + // infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + infile >> ch ; + } + + Flags flags; + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + infile >> ch; + } + + if (infile.good()) + infile.putback (ch); + + spex->bc = int (flags.GetNumFlag ("bc", i+1)); + spex->hpref_left = int (flags.GetDefineFlag ("hpref")) || + int (flags.GetDefineFlag ("hprefleft")); + spex->hpref_right = int (flags.GetDefineFlag ("hpref")) || + int (flags.GetDefineFlag ("hprefright")); + spex->copyfrom = int (flags.GetNumFlag ("copy", -1)); + spex->reffak = flags.GetNumFlag ("ref", 1 ); + spex->hmax = flags.GetNumFlag ("maxh", 1e99 ); + + if ( flags.StringFlagDefined("bcname") ) + { + int mybc = spex->bc-1; + if ( bcnames[mybc] ) delete bcnames[mybc]; + bcnames[mybc] = new string (flags.GetStringFlag("bcname","") ); + } + + if ( hd != 1 ) + spex->reffak = hd; + } + if ( !infile.good() ) + return; + TestComment ( infile ); + int numdomains; + int domainnr; + char material[100]; + + if ( !infile.good() ) + return; + + infile >> numdomains; + materials.SetSize(numdomains) ; + maxh.SetSize ( numdomains ) ; + maxh = 1e99; + + TestComment ( infile ); + + for ( int i=0; i> domainnr; + infile >> material; + strcpy(materials[domainnr-1], material); + + Flags flags; + ch = 'a'; + infile >> ch; + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + infile >> ch; + } + + if (infile.good()) + infile.putback (ch); + + maxh[domainnr-1] = flags.GetNumFlag ( "maxh", 1e99); + } + return; + } + + + + + void SplineGeometry2d :: LoadDataV2 ( ifstream & infile ) + { + enum { D = 2 }; + // new parser by Astrid Sinwel + + PrintMessage (1, "Load 2D Geometry V2"); + int nump, leftdom, rightdom; + Point x; + int hi1, hi2, hi3; + double hd; + char buf[50], ch; + int pointnr; + + string keyword; + + Array < GeomPoint > infilepoints (0); + Array pointnrs (0); + nump = 0; + int numdomains = 0; + + + TestComment ( infile ); + // refinement factor + infile >> elto0; + TestComment ( infile ); + + + // test if next ch is a letter, i.e. new keyword starts + bool ischar = false; + + while ( infile.good() ) + { + infile >> keyword; + + ischar = false; + + if ( keyword == "points" ) + { + PrintMessage (3, "load points"); + infile.get(ch); + infile.putback(ch); + + // test if ch is a letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + + while ( ! ischar ) + { + TestComment ( infile ); + infile >> pointnr; + // pointnrs 1-based + if ( pointnr > nump ) nump = pointnr; + pointnrs.Append(pointnr); + + for(int j=0; j> x(j); + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + + Flags flags; + + + // get flags, + ch = 'a'; + // infile >> ch; + do + { + infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + infile.get(ch); + } + } + while (isspace(ch) && ch != '\n'); + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + do { + infile.get (ch); + } while (isspace(ch) && ch != '\n'); + } + if (infile.good()) + infile.putback (ch); + + if ( hd == 1 ) + hd = flags.GetNumFlag ( "ref", 1.0); + // geompoints.Append (GeomPoint(x, hd)); + + infilepoints.Append ( GeomPoint(x, hd) ); + infilepoints.Last().hpref = flags.GetDefineFlag ("hpref"); + infilepoints.Last().hmax = flags.GetNumFlag ("maxh", 1e99); + + TestComment(infile); + infile.get(ch); + infile.putback(ch); + + // test if letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + } + + // infile.putback (ch); + + geompoints.SetSize(nump); + for ( int i = 0; i < nump; i++ ) + { + geompoints[pointnrs[i] - 1] = infilepoints[i]; + geompoints[pointnrs[i] - 1].hpref = infilepoints[i].hpref; + } + TestComment(infile); + } + + else if ( keyword == "segments" ) + { + PrintMessage (3, "load segments"); + + bcnames.SetSize(0); + infile.get(ch); + infile.putback(ch); + int i = 0; + + // test if ch is a letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + + while ( !ischar ) //ch != 'p' && ch != 'm' ) + { + i++; + TestComment ( infile ); + + SplineSeg * spline = 0; + TestComment ( infile ); + + infile >> leftdom >> rightdom; + + if ( leftdom > numdomains ) numdomains = leftdom; + if ( rightdom > numdomains ) numdomains = rightdom; + + + infile >> buf; + // type of spline segement + if (strcmp (buf, "2") == 0) + { // a line + infile >> hi1 >> hi2; + spline = new LineSeg(geompoints[hi1-1], + geompoints[hi2-1]); + } + else if (strcmp (buf, "3") == 0) + { // a rational spline + infile >> hi1 >> hi2 >> hi3; + spline = new SplineSeg3 (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + } + else if (strcmp (buf, "4") == 0) + { // an arc + infile >> hi1 >> hi2 >> hi3; + spline = new CircleSeg (geompoints[hi1-1], + geompoints[hi2-1], + geompoints[hi3-1]); + } + else if (strcmp (buf, "discretepoints") == 0) + { + int npts; + infile >> npts; + Array< Point > pts(npts); + for (int j = 0; j < npts; j++) + for(int k=0; k> pts[j](k); + + spline = new DiscretePointsSeg (pts); + } + else if (strcmp (buf, "bsplinepoints") == 0) + { + int npts,order; + infile >> npts; + infile >> order; + Array< Point > pts(npts); + for (int j = 0; j < npts; j++) + for(int k=0; k> pts[j](k); + if(order<2) + cerr<<"Minimum order of 2 is required!!"< (pts); + else if(order==3) + spline = new BSplineSeg (pts); + else if(order==4) + spline = new BSplineSeg (pts); + else if(order>4) + cerr<<"Maximum allowed order is 4!!"<> spline->reffak; + SplineSegExt * spex = new SplineSegExt (*spline); + + spex -> leftdom = leftdom; + spex -> rightdom = rightdom; + splines.Append (spex); + + + // hd is now optional, default 1 + // infile >> hd; + hd = 1; + + infile >> ch; + + // get refinement parameter, if it is there + //infile.get (ch); + // if another int-value, set refinement flag to this value + // (corresponding to old files) + /* + if ( int (ch) >= 48 && int(ch) <= 57 ) + { + infile.putback(ch); + infile >> hd; + infile >> ch ; + } + */ + // get flags, + Flags flags; + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + infile >> ch; + } + + if (infile.good()) + infile.putback (ch); + + spex->bc = int (flags.GetNumFlag ("bc", i+1)); + spex->hpref_left = int (flags.GetDefineFlag ("hpref")) || + int (flags.GetDefineFlag ("hprefleft")); + spex->hpref_right = int (flags.GetDefineFlag ("hpref")) || + int (flags.GetDefineFlag ("hprefright")); + spex->copyfrom = int (flags.GetNumFlag ("copy", -1)); + spex->reffak = flags.GetNumFlag ("ref", 1 ); + spex->hmax = flags.GetNumFlag ("maxh", 1e99 ); + if ( hd != 1 ) spex->reffak = hd; + + if ( flags.StringFlagDefined("bcname") ) + { + int mybc = spex->bc-1; + for ( int ii = bcnames.Size(); ii <= mybc; ii++ ) + bcnames.Append ( new string ("default")); + if ( bcnames[mybc] ) delete bcnames[mybc]; + bcnames[mybc] = new string (flags.GetStringFlag("bcname","") ); + } + + TestComment(infile); + infile.get(ch); + infile.putback(ch); + + // test if ch is a letter + if ( int(ch) >= 65 && int(ch) <=90 ) + ischar = true; + if ( int(ch) >= 97 && int(ch) <= 122 ) + ischar = true; + + } + + infile.get(ch); + infile.putback(ch); + + + } + else if ( keyword == "materials" ) + { + TestComment ( infile ); + int domainnr; + char material[100]; + + if ( !infile.good() ) + return; + + materials.SetSize(numdomains) ; + maxh.SetSize ( numdomains ) ; + for ( int i = 0; i < numdomains; i++) + maxh[i] = 1000; + quadmeshing.SetSize ( numdomains ); + quadmeshing = false; + tensormeshing.SetSize ( numdomains ); + tensormeshing = false; + layer.SetSize ( numdomains ); + layer = 1; + + + TestComment ( infile ); + + for ( int i=0; i> domainnr; + infile >> material; + + strcpy (materials[domainnr-1], material); + + Flags flags; + ch = 'a'; + infile >> ch; + while (ch == '-') + { + char flag[100]; + flag[0]='-'; + infile >> (flag+1); + flags.SetCommandLineFlag (flag); + ch = 'a'; + infile >> ch; + } + + if (infile.good()) + infile.putback (ch); + + maxh[domainnr-1] = flags.GetNumFlag ( "maxh", 1000); + if (flags.GetDefineFlag("quad")) quadmeshing[domainnr-1] = true; + if (flags.GetDefineFlag("tensor")) tensormeshing[domainnr-1] = true; + layer[domainnr-1] = int(flags.GetNumFlag ("layer", 1)); + } + } + } + return; + } + + + + + + + + + + /* + void CalcPartition (const SplineSegExt & spline, + double l, double h, double h1, double h2, + double hcurve, double elto0, Array & points) + { + double fperel, oldf, f; + + int n = 1000; + + points.SetSize (0); + + double dt = l / n; + + double sum = 0; + for (int i = 1; i <= n; i++) + { + double t = (i-0.5)*dt; + double fun = min3 (hcurve, t/elto0 + h1, (l-t)/elto0 + h2); + double curv = spline.CalcCurvature (t/l); + cout << "curv = " << curv << endl; + if (curv < 1e-10) curv = 1e-10; + fun = min2 (fun, 0.1/curv); + sum += dt / fun; + } + + int nel = int (sum+1); + fperel = sum / nel; + + points.Append (0); + + int i = 1; + oldf = 0; + // t = 0.5 * dt; + for (int j = 1; j <= n && i < nel; j++) + { + double t = (j-0.5)*dt; + double fun = min3 (hcurve, t/elto0 + h1, (l-t)/elto0 + h2); + double curv = spline.CalcCurvature (t/l); + if (curv < 1e-10) curv = 1e-10; + fun = min2 (fun, 0.1/curv); + + f = oldf + dt / fun; + + while (i * fperel < f && i < nel) + { + points.Append ( dt * (j-1) + (i * fperel - oldf) * fun); + i++; + } + oldf = f; + t += dt; + } + points.Append (l); + } + */ + + + + + + + + string SplineGeometry2d :: GetBCName( const int bcnr ) const + { + if ( bcnames.Size() >= bcnr) + if (bcnames[bcnr-1] ) + return *bcnames[bcnr-1]; + return "default"; + } + + string * SplineGeometry2d :: BCNamePtr( const int bcnr ) + { + if ( bcnr > bcnames.Size() ) + return 0; + else + return bcnames[bcnr-1]; + } + + + + + + void SplineGeometry2d :: GetMaterial( const int domnr, char* & material ) + { + if ( materials.Size() >= domnr) + material = materials[domnr-1]; + else + material = 0; + } + + + double SplineGeometry2d :: GetDomainMaxh( const int domnr ) + { + if ( maxh.Size() >= domnr && domnr > 0) + return maxh[domnr-1]; + else + return -1; + } + + + + extern void MeshFromSpline2D (SplineGeometry2d & geometry, + Mesh *& mesh, + MeshingParameters & mp); + + + int SplineGeometry2d :: GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend) + { + MeshFromSpline2D (*this, mesh, mparam); + return 0; + } + + + Refinement & SplineGeometry2d :: GetRefinement () const + { + return * new Refinement2d (*this); + } + + + + class SplineGeometryRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const; + }; + + NetgenGeometry * SplineGeometryRegister :: Load (string filename) const + { + const char * cfilename = filename.c_str(); + if (strcmp (&cfilename[strlen(cfilename)-4], "in2d") == 0) + { + PrintMessage (1, "Load 2D-Spline geometry file ", cfilename); + + + ifstream infile(cfilename); + + SplineGeometry2d * hgeom = new SplineGeometry2d(); + hgeom -> Load (cfilename); + return hgeom; + } + + return NULL; + } + + class SplineGeoInit + { + public: + SplineGeoInit() + { + geometryregister.Append (new SplineGeometryRegister); + } + }; + + SplineGeoInit sginit; + +} diff --git a/libsrc/geom2d/geometry2d.hpp b/libsrc/geom2d/geometry2d.hpp new file mode 100644 index 00000000..15e9e80d --- /dev/null +++ b/libsrc/geom2d/geometry2d.hpp @@ -0,0 +1,197 @@ +#ifndef FILE_GEOMETRY2D +#define FILE_GEOMETRY2D + +/* *************************************************************************/ +/* File: geometry2d.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + +#include +#include + + +// #include "../gprim/spline.hpp" +// #include "../gprim/splinegeometry.hpp" +#include "geom2dmesh.hpp" + +namespace netgen +{ + + class SplineSegExt : public SplineSeg<2> + { + public: + const SplineSeg<2> & seg; + + /// left domain + int leftdom; + /// right domain + int rightdom; + /// refinement at line + double reffak; + /// maximal h; + double hmax; + /// boundary condition number + int bc; + /// copy spline mesh from other spline (-1.. do not copy) + int copyfrom; + /// perfrom anisotropic refinement (hp-refinement) to edge + bool hpref_left; + /// perfrom anisotropic refinement (hp-refinement) to edge + bool hpref_right; + /// + int layer; + + SplineSegExt (const SplineSeg<2> & hseg) + : seg(hseg) + { + layer = 1; + } + + ~SplineSegExt () + { + delete &seg; + } + + virtual const GeomPoint<2> & StartPI () const + { + return seg.StartPI(); + } + + virtual const GeomPoint<2> & EndPI () const + { + return seg.EndPI(); + } + + virtual Point<2> GetPoint (double t) const + { + return seg.GetPoint(t); + } + + virtual Vec<2> GetTangent (const double t) const + { + return seg.GetTangent(t); + } + + virtual void GetDerivatives (const double t, + Point<2> & point, + Vec<2> & first, + Vec<2> & second) const + { + seg.GetDerivatives (t, point, first, second); + } + + virtual void GetCoeff (Vector & coeffs) const + { + seg.GetCoeff (coeffs); + } + + virtual void GetPoints (int n, Array > & points) const + { + seg.GetPoints (n, points); + } + + virtual double MaxCurvature () const + { + return seg.MaxCurvature(); + } + + virtual string GetType () const + { + return seg.GetType(); + } + + virtual double CalcCurvature (double t) const + { + Point<2> point; + Vec<2> first, second; + GetDerivatives (t, point, first, second); + double curv = fabs(first(0)*second(1)-first(1)*second(0)) / pow(first.Length(), 3); + return curv; + } + + }; + + + + + class SplineGeometry2d : public SplineGeometry<2>, public NetgenGeometry + { + protected: + Array materials; + Array maxh; + Array quadmeshing; + Array tensormeshing; + Array layer; + Array bcnames; + double elto0; + + + public: + DLL_HEADER virtual ~SplineGeometry2d(); + + DLL_HEADER void Load (const char * filename); + + DLL_HEADER void LoadData( ifstream & infile ); + DLL_HEADER void LoadDataNew ( ifstream & infile ); + DLL_HEADER void LoadDataV2 ( ifstream & infile ); + + void TestComment ( ifstream & infile ) ; + + + + const SplineSegExt & GetSpline (const int i) const + { + return dynamic_cast (*splines[i]); + } + + SplineSegExt & GetSpline (const int i) + { + return dynamic_cast (*splines[i]); + } + + + DLL_HEADER virtual int GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend); + + void PartitionBoundary (MeshingParameters & mp, double h, Mesh & mesh2d); + + void CopyEdgeMesh (int from, int to, Mesh & mesh2d, Point3dTree & searchtree); + + + void GetMaterial( const int domnr, char* & material ); + + double GetDomainMaxh ( const int domnr ); + bool GetDomainQuadMeshing ( int domnr ) + { + if ( quadmeshing.Size() ) return quadmeshing[domnr-1]; + else return false; + } + bool GetDomainTensorMeshing ( int domnr ) + { + if ( tensormeshing.Size() ) return tensormeshing[domnr-1]; + else return false; + } + int GetDomainLayer ( int domnr ) + { + if ( layer.Size() ) return layer[domnr-1]; + else return 1; + } + + + string GetBCName ( const int bcnr ) const; + + string * BCNamePtr ( const int bcnr ); + + + DLL_HEADER virtual Refinement & GetRefinement () const; + }; +} + + + + + + + +#endif diff --git a/libsrc/geom2d/vsgeom2d.cpp b/libsrc/geom2d/vsgeom2d.cpp new file mode 100644 index 00000000..2ab2d066 --- /dev/null +++ b/libsrc/geom2d/vsgeom2d.cpp @@ -0,0 +1,110 @@ +#include +#include +#include + +#include "vsgeom2d.hpp" + +namespace netgen +{ + + + /* *********************** Draw 2D Geometry **************** */ + + + VisualSceneGeometry2d :: VisualSceneGeometry2d () + : VisualScene() + { + ; + } + + VisualSceneGeometry2d :: ~VisualSceneGeometry2d () + { + ; + } + + + + void VisualSceneGeometry2d :: DrawScene () + { + if (changeval != geometry2d->GetSplines().Size()) + BuildScene(); + changeval = geometry2d->GetSplines().Size(); + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + SetLight(); + + // glEnable (GL_LIGHT0); + glDisable (GL_LIGHTING); + glPushMatrix(); + glMultMatrixf (transformationmat); + + // SetClippingPlane (); + + glShadeModel (GL_SMOOTH); + glEnable (GL_COLOR_MATERIAL); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + // float mat_col[] = { 0, 0, 1, 1 }; + // glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + glColor3f (0, 0, 1); + + + Array > points, otherpoints; + + for (int i = 1; i <= geometry2d->GetSplines().Size(); i++) + { + geometry2d->GetSplines().Get(i)->GetPoints (200, points); + + glBegin (GL_LINE_STRIP); + for (int j = 0; j < points.Size(); j++) + glVertex3d (points[j](0), points[j](1), 0); + glEnd(); + } + + glColor3f (1, 0, 0); + + for (int i = 1; i <= geometry2d->GetSplines().Size(); i++) + { + int other = geometry2d->GetSpline(i-1).copyfrom; + if (other != -1) + { + geometry2d->GetSplines().Get(i)->GetPoints (6, points); + geometry2d->GetSplines().Get(other)->GetPoints (6, otherpoints); + glBegin (GL_LINES); + for (int j = 1; j < 5; j++) + { + glVertex3d (points[j](0), points[j](1), 0); + glVertex3d (otherpoints[j](0), otherpoints[j](1), 0); + } + glEnd (); + } + } + + + + glPopMatrix(); + + DrawCoordinateCross (); + DrawNetgenLogo (); + + glFinish(); + } + + + void VisualSceneGeometry2d :: BuildScene (int zoomall) + { + Box<2> bbox; + + geometry2d->GetBoundingBox (bbox); + + Point<2> c = Center (bbox.PMin(), bbox.PMax()); + + center = Point3d (c(0), c(1), 0); + rad = Dist (bbox.PMin(), bbox.PMax()) / 2; + + CalcTransformationMatrices(); + } +} diff --git a/libsrc/geom2d/vsgeom2d.hpp b/libsrc/geom2d/vsgeom2d.hpp new file mode 100644 index 00000000..ffb44711 --- /dev/null +++ b/libsrc/geom2d/vsgeom2d.hpp @@ -0,0 +1,28 @@ +#ifndef FILE_VSGEOM2D +#define FILE_VSGEOM2D + +/**************************************************************************/ +/* File: vsgeom2d.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 05. Jan. 2011 */ +/**************************************************************************/ + +namespace netgen +{ + + class VisualSceneGeometry2d : public VisualScene + { + const class SplineGeometry2d * geometry2d; + public: + VisualSceneGeometry2d (); + virtual ~VisualSceneGeometry2d (); + void SetGeometry (const class SplineGeometry2d * ageometry2d) { geometry2d = ageometry2d; } + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + }; + +} + + + +#endif diff --git a/libsrc/gprim/Makefile.am b/libsrc/gprim/Makefile.am new file mode 100644 index 00000000..7d60c42d --- /dev/null +++ b/libsrc/gprim/Makefile.am @@ -0,0 +1,7 @@ +noinst_HEADERS = adtree.hpp geom3d.hpp geomobjects2.hpp geomops2.hpp geomtest3d.hpp transform3d.hpp geom2d.hpp geomfuncs.hpp geomobjects.hpp geomops.hpp gprim.hpp spline.hpp splinegeometry.hpp + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LTLIBRARIES = libgprim.la +libgprim_la_SOURCES = adtree.cpp geom2d.cpp geom3d.cpp geomfuncs.cpp \ + geomtest3d.cpp transform3d.cpp spline.cpp splinegeometry.cpp diff --git a/libsrc/gprim/Makefile.in b/libsrc/gprim/Makefile.in new file mode 100644 index 00000000..99f05ae9 --- /dev/null +++ b/libsrc/gprim/Makefile.in @@ -0,0 +1,546 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc/gprim +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libgprim_la_LIBADD = +am_libgprim_la_OBJECTS = adtree.lo geom2d.lo geom3d.lo geomfuncs.lo \ + geomtest3d.lo transform3d.lo spline.lo splinegeometry.lo +libgprim_la_OBJECTS = $(am_libgprim_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libgprim_la_SOURCES) +DIST_SOURCES = $(libgprim_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = adtree.hpp geom3d.hpp geomobjects2.hpp geomops2.hpp geomtest3d.hpp transform3d.hpp geom2d.hpp geomfuncs.hpp geomobjects.hpp geomops.hpp gprim.hpp spline.hpp splinegeometry.hpp +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LTLIBRARIES = libgprim.la +libgprim_la_SOURCES = adtree.cpp geom2d.cpp geom3d.cpp geomfuncs.cpp \ + geomtest3d.cpp transform3d.cpp spline.cpp splinegeometry.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/gprim/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/gprim/Makefile +.PRECIOUS: 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)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libgprim.la: $(libgprim_la_OBJECTS) $(libgprim_la_DEPENDENCIES) $(EXTRA_libgprim_la_DEPENDENCIES) + $(CXXLINK) $(libgprim_la_OBJECTS) $(libgprim_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adtree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geom2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geom3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geomfuncs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geomtest3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splinegeometry.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform3d.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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 all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags 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 uninstall uninstall-am + + +# 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/libsrc/gprim/adtree.cpp b/libsrc/gprim/adtree.cpp new file mode 100644 index 00000000..5a7fe380 --- /dev/null +++ b/libsrc/gprim/adtree.cpp @@ -0,0 +1,2178 @@ +#include + + +#include +// class DenseMatrix; +#include + +namespace netgen +{ + + + /* ******************************* ADTree ******************************* */ + + + ADTreeNode :: ADTreeNode(int adim) + { + pi = -1; + + left = NULL; + right = NULL; + father = NULL; + nchilds = 0; + dim = adim; + data = new float [dim]; + boxmin = NULL; + boxmax = NULL; + } + + + + + ADTreeNode :: ~ADTreeNode() + { + delete data; + } + + + ADTree :: ADTree (int adim, const float * acmin, + const float * acmax) + : ela(0), stack(1000), stackdir(1000) + { + dim = adim; + cmin = new float [dim]; + cmax = new float [dim]; + memcpy (cmin, acmin, dim * sizeof(float)); + memcpy (cmax, acmax, dim * sizeof(float)); + + root = new ADTreeNode (dim); + root->sep = (cmin[0] + cmax[0]) / 2; + root->boxmin = new float [dim]; + root->boxmax = new float [dim]; + memcpy (root->boxmin, cmin, dim * sizeof(float)); + memcpy (root->boxmax, cmax, dim * sizeof(float)); + } + + ADTree :: ~ADTree () + { + ; + } + + void ADTree :: Insert (const float * p, int pi) + { + ADTreeNode *node(NULL); + ADTreeNode *next; + int dir; + int lr(1); + + float * bmin = new float [dim]; + float * bmax = new float [dim]; + + memcpy (bmin, cmin, dim * sizeof(float)); + memcpy (bmax, cmax, dim * sizeof(float)); + + + next = root; + dir = 0; + while (next) + { + node = next; + + if (node->pi == -1) + { + memcpy (node->data, p, dim * sizeof(float)); + node->pi = pi; + + if (ela.Size() < pi+1) + ela.SetSize (pi+1); + ela[pi] = node; + + return; + } + + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + + dir++; + if (dir == dim) + dir = 0; + } + + + next = new ADTreeNode(dim); + memcpy (next->data, p, dim * sizeof(float)); + next->pi = pi; + next->sep = (bmin[dir] + bmax[dir]) / 2; + next->boxmin = bmin; + next->boxmax = bmax; + + if (ela.Size() < pi+1) + ela.SetSize (pi+1); + ela[pi] = next; + + + if (lr) + node->right = next; + else + node->left = next; + next -> father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree :: DeleteElement (int pi) + { + ADTreeNode * node = ela[pi]; + + node->pi = -1; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + + void ADTree :: SetCriterion (ADTreeCriterion & acriterion) + { + criterion = & acriterion; + } + + + void ADTree :: Reset () + { + stack.Elem(1) = root; + stackdir.Elem(1) = 0; + stackindex = 1; + } + + + int ADTree:: Next () + { + ADTreeNode *node; + int dir; + + if (stackindex == 0) + return -1; + + do + { + node = stack.Get(stackindex); + dir = stackdir.Get(stackindex); + stackindex --; + + if (criterion -> Eval(node)) + { + int ndir = dir + 1; + if (ndir == dim) + ndir = 0; + + if (node -> left && criterion -> Eval (node->left)) + { + stackindex ++; + stack.Elem(stackindex) = node -> left; + stackdir.Elem(stackindex) = ndir; + } + if (node->right && criterion -> Eval (node -> right)) + { + stackindex++; + stack.Elem(stackindex) = node->right; + stackdir.Elem(stackindex) = ndir; + } + + if (node -> pi != -1) + return node->pi; + } + } + while (stackindex > 0); + + return -1; + } + + + void ADTree :: GetMatch (Array & matches) + { + int nodenr; + + Reset(); + + while ( (nodenr = Next()) != -1) + matches.Append (nodenr); + } + + + void ADTree :: PrintRec (ostream & ost, const ADTreeNode * node) const + { + + if (node->data) + { + ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + for (int i = 0; i < dim; i++) + ost << node->data[i] << " "; + ost << endl; + } + if (node->left) + { + ost << "l "; + PrintRec (ost, node->left); + } + if (node->right) + { + ost << "r "; + PrintRec (ost, node->right); + } + } + + + /* ******************************* ADTree3 ******************************* */ + + + ADTreeNode3 :: ADTreeNode3() + { + pi = -1; + + left = NULL; + right = NULL; + father = NULL; + nchilds = 0; + } + + void ADTreeNode3 :: DeleteChilds () + { + if (left) + { + left->DeleteChilds(); + delete left; + left = NULL; + } + if (right) + { + right->DeleteChilds(); + delete right; + right = NULL; + } + } + + + BlockAllocator ADTreeNode3 :: ball(sizeof (ADTreeNode3)); + + + void * ADTreeNode3 :: operator new(size_t s) + { + return ball.Alloc(); + } + + void ADTreeNode3 :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + + + ADTree3 :: ADTree3 (const float * acmin, + const float * acmax) + : ela(0) + { + memcpy (cmin, acmin, 3 * sizeof(float)); + memcpy (cmax, acmax, 3 * sizeof(float)); + + root = new ADTreeNode3; + root->sep = (cmin[0] + cmax[0]) / 2; + } + + ADTree3 :: ~ADTree3 () + { + root->DeleteChilds(); + delete root; + } + + + void ADTree3 :: Insert (const float * p, int pi) + { + ADTreeNode3 *node(NULL); + ADTreeNode3 *next; + int dir; + int lr(0); + + float bmin[3]; + float bmax[3]; + + memcpy (bmin, cmin, 3 * sizeof(float)); + memcpy (bmax, cmax, 3 * sizeof(float)); + + next = root; + dir = 0; + while (next) + { + node = next; + + if (node->pi == -1) + { + memcpy (node->data, p, 3 * sizeof(float)); + node->pi = pi; + + if (ela.Size() < pi+1) + ela.SetSize (pi+1); + ela[pi] = node; + + return; + } + + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + + dir++; + if (dir == 3) + dir = 0; + } + + + next = new ADTreeNode3; + memcpy (next->data, p, 3 * sizeof(float)); + next->pi = pi; + next->sep = (bmin[dir] + bmax[dir]) / 2; + + + if (ela.Size() < pi+1) + ela.SetSize (pi+1); + ela[pi] = next; + + + if (lr) + node->right = next; + else + node->left = next; + next -> father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree3 :: DeleteElement (int pi) + { + ADTreeNode3 * node = ela[pi]; + + node->pi = -1; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + void ADTree3 :: GetIntersecting (const float * bmin, + const float * bmax, + Array & pis) const + { + static Array stack(1000); + static Array stackdir(1000); + ADTreeNode3 * node; + int dir, stacks; + + stack.SetSize (1000); + stackdir.SetSize(1000); + pis.SetSize(0); + + stack.Elem(1) = root; + stackdir.Elem(1) = 0; + stacks = 1; + + while (stacks) + { + node = stack.Get(stacks); + dir = stackdir.Get(stacks); + stacks--; + + if (node->pi != -1) + { + if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && + node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && + node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) + + pis.Append (node->pi); + } + + + int ndir = dir+1; + if (ndir == 3) + ndir = 0; + + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack.Elem(stacks) = node->left; + stackdir.Elem(stacks) = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack.Elem(stacks) = node->right; + stackdir.Elem(stacks) = ndir; + } + } + } + + void ADTree3 :: PrintRec (ostream & ost, const ADTreeNode3 * node) const + { + + if (node->data) + { + ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + for (int i = 0; i < 3; i++) + ost << node->data[i] << " "; + ost << endl; + } + if (node->left) + PrintRec (ost, node->left); + if (node->right) + PrintRec (ost, node->right); + } + + + + + + + + +#ifdef ABC + + /* ******************************* ADTree3Div ******************************* */ + + + ADTreeNode3Div :: ADTreeNode3Div() + { + pi = 0; + + int i; + for (i = 0; i < ADTN_DIV; i++) + childs[i] = NULL; + + father = NULL; + nchilds = 0; + minx = 0; + dist = 1; + } + + void ADTreeNode3Div :: DeleteChilds () + { + int i; + for (i = 0; i < ADTN_DIV; i++) + if (childs[i]) + { + childs[i]->DeleteChilds(); + delete childs[i]; + childs[i] = NULL; + } + } + + + BlockAllocator ADTreeNode3Div :: ball(sizeof (ADTreeNode3Div)); + + void * ADTreeNode3Div :: operator new(size_t) + { + return ball.Alloc(); + } + + void ADTreeNode3Div :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + + + ADTree3Div :: ADTree3Div (const float * acmin, + const float * acmax) + : ela(0) + { + memcpy (cmin, acmin, 3 * sizeof(float)); + memcpy (cmax, acmax, 3 * sizeof(float)); + + root = new ADTreeNode3Div; + + root->minx = cmin[0]; + root->dist = (cmax[0] - cmin[0]) / ADTN_DIV; + + // root->sep = (cmin[0] + cmax[0]) / 2; + } + + ADTree3Div :: ~ADTree3Div () + { + root->DeleteChilds(); + delete root; + } + + + void ADTree3Div :: Insert (const float * p, int pi) + { + ADTreeNode3Div *node; + ADTreeNode3Div *next; + int dir; + int bag; + + float bmin[3]; + float bmax[3]; + + memcpy (bmin, cmin, 3 * sizeof(float)); + memcpy (bmax, cmax, 3 * sizeof(float)); + + + next = root; + dir = 0; + while (next) + { + node = next; + + if (!node->pi) + { + memcpy (node->data, p, 3 * sizeof(float)); + node->pi = pi; + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = node; + + return; + } + + double dx = (bmax[dir] - bmin[dir]) / ADTN_DIV; + bag = int ((p[dir]-bmin[dir]) / dx); + + // (*testout) << "insert, bag = " << bag << endl; + + if (bag < 0) bag = 0; + if (bag >= ADTN_DIV) bag = ADTN_DIV-1; + + double nbmin = bmin[dir] + bag * dx; + double nbmax = bmin[dir] + (bag+1) * dx; + + /* + (*testout) << "bmin, max = " << bmin[dir] << "-" << bmax[dir] + << " p = " << p[dir]; + */ + next = node->childs[bag]; + bmin[dir] = nbmin; + bmax[dir] = nbmax; + + // (*testout) << "new bmin, max = " << bmin[dir] << "-" << bmax[dir] << endl; + + + /* + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + */ + + dir++; + if (dir == 3) + dir = 0; + } + + + next = new ADTreeNode3Div; + memcpy (next->data, p, 3 * sizeof(float)); + next->pi = pi; + + next->minx = bmin[dir]; + next->dist = (bmax[dir] - bmin[dir]) / ADTN_DIV; + // next->sep = (bmin[dir] + bmax[dir]) / 2; + + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = next; + + node->childs[bag] = next; + next -> father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree3Div :: DeleteElement (int pi) + { + ADTreeNode3Div * node = ela.Get(pi); + + node->pi = 0; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + void ADTree3Div :: GetIntersecting (const float * bmin, + const float * bmax, + Array & pis) const + { + static Array stack(1000); + static Array stackdir(1000); + ADTreeNode3Div * node; + int dir, i, stacks; + + stack.SetSize (1000); + stackdir.SetSize(1000); + pis.SetSize(0); + + stack.Elem(1) = root; + stackdir.Elem(1) = 0; + stacks = 1; + + while (stacks) + { + node = stack.Get(stacks); + dir = stackdir.Get(stacks); + stacks--; + + if (node->pi) + { + if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && + node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && + node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) + + pis.Append (node->pi); + } + + + int ndir = dir+1; + if (ndir == 3) + ndir = 0; + + int mini = int ( (bmin[dir] - node->minx) / node->dist ); + int maxi = int ( (bmax[dir] - node->minx) / node->dist ); + + // (*testout) << "get int, mini, maxi = " << mini << ", " << maxi << endl; + if (mini < 0) mini = 0; + if (maxi >= ADTN_DIV) maxi = ADTN_DIV-1; + + for (i = mini; i <= maxi; i++) + if (node->childs[i]) + { + stacks++; + stack.Elem(stacks) = node->childs[i]; + stackdir.Elem(stacks) = ndir; + } + + + /* + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack.Elem(stacks) = node->left; + stackdir.Elem(stacks) = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack.Elem(stacks) = node->right; + stackdir.Elem(stacks) = ndir; + } + */ + } + } + + void ADTree3Div :: PrintRec (ostream & ost, const ADTreeNode3Div * node) const + { + + if (node->data) + { + ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + ost << " from " << node->minx << " - " << node->minx + node->dist*ADTN_DIV << " "; + for (int i = 0; i < 3; i++) + ost << node->data[i] << " "; + ost << endl; + } + int i; + for (i = 0; i < ADTN_DIV; i++) + if (node->childs[i]) + PrintRec (ost, node->childs[i]); + } + + + + + + + + + + + + + /* ******************************* ADTree3M ******************************* */ + + + ADTreeNode3M :: ADTreeNode3M() + { + int i; + for (i = 0; i < ADTN_SIZE; i++) + pi[i] = 0; + + left = NULL; + right = NULL; + father = NULL; + nchilds = 0; + } + + void ADTreeNode3M :: DeleteChilds () + { + if (left) + { + left->DeleteChilds(); + delete left; + left = NULL; + } + if (right) + { + right->DeleteChilds(); + delete right; + right = NULL; + } + } + + + BlockAllocator ADTreeNode3M :: ball(sizeof (ADTreeNode3M)); + + void * ADTreeNode3M :: operator new(size_t) + { + return ball.Alloc(); + } + + void ADTreeNode3M :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + + + ADTree3M :: ADTree3M (const float * acmin, + const float * acmax) + : ela(0) + { + memcpy (cmin, acmin, 3 * sizeof(float)); + memcpy (cmax, acmax, 3 * sizeof(float)); + + root = new ADTreeNode3M; + root->sep = (cmin[0] + cmax[0]) / 2; + } + + ADTree3M :: ~ADTree3M () + { + root->DeleteChilds(); + delete root; + } + + + void ADTree3M :: Insert (const float * p, int pi) + { + ADTreeNode3M *node; + ADTreeNode3M *next; + int dir; + int lr; + int i; + float bmin[3]; + float bmax[3]; + + memcpy (bmin, cmin, 3 * sizeof(float)); + memcpy (bmax, cmax, 3 * sizeof(float)); + + next = root; + dir = 0; + while (next) + { + node = next; + + for (i = 0; i < ADTN_SIZE; i++) + if (!node->pi[i]) + { + memcpy (node->data[i], p, 3 * sizeof(float)); + node->pi[i] = pi; + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = node; + + return; + } + + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + + dir++; + if (dir == 3) + dir = 0; + } + + + next = new ADTreeNode3M; + memcpy (next->data[0], p, 3 * sizeof(float)); + next->pi[0] = pi; + next->sep = (bmin[dir] + bmax[dir]) / 2; + + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = next; + + + if (lr) + node->right = next; + else + node->left = next; + next -> father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree3M :: DeleteElement (int pi) + { + ADTreeNode3M * node = ela.Get(pi); + + int i; + for (i = 0; i < ADTN_SIZE; i++) + if (node->pi[i] == pi) + node->pi[i] = 0; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + void ADTree3M :: GetIntersecting (const float * bmin, + const float * bmax, + Array & pis) const + { + static Array stack(1000); + static Array stackdir(1000); + ADTreeNode3M * node; + int dir, i, stacks; + + stack.SetSize (1000); + stackdir.SetSize(1000); + pis.SetSize(0); + + stack.Elem(1) = root; + stackdir.Elem(1) = 0; + stacks = 1; + + while (stacks) + { + node = stack.Get(stacks); + dir = stackdir.Get(stacks); + stacks--; + + int * hpi = node->pi; + for (i = 0; i < ADTN_SIZE; i++) + if (hpi[i]) + { + float * datai = &node->data[i][0]; + if (datai[0] >= bmin[0] && datai[0] <= bmax[0] && + datai[1] >= bmin[1] && datai[1] <= bmax[1] && + datai[2] >= bmin[2] && datai[2] <= bmax[2]) + + pis.Append (node->pi[i]); + } + + + int ndir = dir+1; + if (ndir == 3) + ndir = 0; + + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack.Elem(stacks) = node->left; + stackdir.Elem(stacks) = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack.Elem(stacks) = node->right; + stackdir.Elem(stacks) = ndir; + } + } + } + + void ADTree3M :: PrintRec (ostream & ost, const ADTreeNode3M * node) const + { + + if (node->data) + { + // ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + for (int i = 0; i < 3; i++) + ost << node->data[i] << " "; + ost << endl; + } + if (node->left) + PrintRec (ost, node->left); + if (node->right) + PrintRec (ost, node->right); + } + + + + + + + + + + + + + /* ******************************* ADTree3F ******************************* */ + + + ADTreeNode3F :: ADTreeNode3F() + { + pi = 0; + father = NULL; + nchilds = 0; + int i; + for (i = 0; i < 8; i++) + childs[i] = NULL; + } + + void ADTreeNode3F :: DeleteChilds () + { + int i; + + for (i = 0; i < 8; i++) + { + if (childs[i]) + childs[i]->DeleteChilds(); + delete childs[i]; + childs[i] = NULL; + } + } + + + BlockAllocator ADTreeNode3F :: ball(sizeof (ADTreeNode3F)); + + void * ADTreeNode3F :: operator new(size_t) + { + return ball.Alloc(); + } + + void ADTreeNode3F :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + + + ADTree3F :: ADTree3F (const float * acmin, + const float * acmax) + : ela(0) + { + memcpy (cmin, acmin, 3 * sizeof(float)); + memcpy (cmax, acmax, 3 * sizeof(float)); + + root = new ADTreeNode3F; + for (int i = 0; i < 3; i++) + root->sep[i] = (cmin[i] + cmax[i]) / 2; + } + + ADTree3F :: ~ADTree3F () + { + root->DeleteChilds(); + delete root; + } + + + void ADTree3F :: Insert (const float * p, int pi) + { + ADTreeNode3F *node; + ADTreeNode3F *next; + int lr; + + float bmin[3]; + float bmax[3]; + int i, dir; + + memcpy (bmin, cmin, 3 * sizeof(float)); + memcpy (bmax, cmax, 3 * sizeof(float)); + + + next = root; + while (next) + { + node = next; + + if (!node->pi) + { + memcpy (node->data, p, 3 * sizeof(float)); + node->pi = pi; + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = node; + + return; + } + + dir = 0; + for (i = 0; i < 3; i++) + { + if (node->sep[i] > p[i]) + { + bmax[i] = node->sep[i]; + } + else + { + bmin[i] = node->sep[i]; + dir += (1 << i); + } + } + next = node->childs[dir]; + + /* + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + */ + } + + + next = new ADTreeNode3F; + memcpy (next->data, p, 3 * sizeof(float)); + next->pi = pi; + + for (i = 0; i < 3; i++) + next->sep[i] = (bmin[i] + bmax[i]) / 2; + + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = next; + + node->childs[dir] = next; + next->father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree3F :: DeleteElement (int pi) + { + ADTreeNode3F * node = ela.Get(pi); + + node->pi = 0; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + void ADTree3F :: GetIntersecting (const float * bmin, + const float * bmax, + Array & pis) const + { + static Array stack(1000); + ADTreeNode3F * node; + int dir, i, stacks; + + stack.SetSize (1000); + pis.SetSize(0); + + stack.Elem(1) = root; + stacks = 1; + + while (stacks) + { + node = stack.Get(stacks); + stacks--; + + if (node->pi) + { + if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && + node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && + node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) + + pis.Append (node->pi); + } + + + int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1; + int i1max = (bmax[0] < node->sep[0]) ? 0 : 1; + int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1; + int i2max = (bmax[1] < node->sep[1]) ? 0 : 1; + int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1; + int i3max = (bmax[2] < node->sep[2]) ? 0 : 1; + + int i1, i2, i3; + for (i1 = i1min; i1 <= i1max; i1++) + for (i2 = i2min; i2 <= i2max; i2++) + for (i3 = i3min; i3 <= i3max; i3++) + { + i = i1+2*i2+4*i3; + if (node->childs[i]) + { + stacks++; + stack.Elem(stacks) = node->childs[i]; + } + } + + /* + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack.Elem(stacks) = node->left; + stackdir.Elem(stacks) = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack.Elem(stacks) = node->right; + stackdir.Elem(stacks) = ndir; + } + */ + } + } + + void ADTree3F :: PrintRec (ostream & ost, const ADTreeNode3F * node) const + { + int i; + if (node->data) + { + ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + for (i = 0; i < 3; i++) + ost << node->data[i] << " "; + ost << endl; + } + + for (i = 0; i < 8; i++) + if (node->childs[i]) + PrintRec (ost, node->childs[i]); + } + + + + + + + + + + + + + + /* ******************************* ADTree3FM ******************************* */ + + + ADTreeNode3FM :: ADTreeNode3FM() + { + father = NULL; + nchilds = 0; + int i; + + for (i = 0; i < ADTN_SIZE; i++) + pi[i] = 0; + + for (i = 0; i < 8; i++) + childs[i] = NULL; + } + + void ADTreeNode3FM :: DeleteChilds () + { + int i; + + for (i = 0; i < 8; i++) + { + if (childs[i]) + childs[i]->DeleteChilds(); + delete childs[i]; + childs[i] = NULL; + } + } + + + BlockAllocator ADTreeNode3FM :: ball(sizeof (ADTreeNode3FM)); + + void * ADTreeNode3FM :: operator new(size_t) + { + return ball.Alloc(); + } + + void ADTreeNode3FM :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + + + ADTree3FM :: ADTree3FM (const float * acmin, + const float * acmax) + : ela(0) + { + memcpy (cmin, acmin, 3 * sizeof(float)); + memcpy (cmax, acmax, 3 * sizeof(float)); + + root = new ADTreeNode3FM; + for (int i = 0; i < 3; i++) + root->sep[i] = (cmin[i] + cmax[i]) / 2; + } + + ADTree3FM :: ~ADTree3FM () + { + root->DeleteChilds(); + delete root; + } + + + void ADTree3FM :: Insert (const float * p, int pi) + { + ADTreeNode3FM *node; + ADTreeNode3FM *next; + int lr; + + float bmin[3]; + float bmax[3]; + int i, dir; + + memcpy (bmin, cmin, 3 * sizeof(float)); + memcpy (bmax, cmax, 3 * sizeof(float)); + + next = root; + while (next) + { + node = next; + + for (i = 0; i < ADTN_SIZE; i++) + if (!node->pi[i]) + { + memcpy (node->data[i], p, 3 * sizeof(float)); + node->pi[i] = pi; + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = node; + + return; + } + + dir = 0; + for (i = 0; i < 3; i++) + { + if (node->sep[i] > p[i]) + { + bmax[i] = node->sep[i]; + } + else + { + bmin[i] = node->sep[i]; + dir += (1 << i); + } + } + next = node->childs[dir]; + + /* + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + */ + } + + + next = new ADTreeNode3FM; + memcpy (next->data[0], p, 3 * sizeof(float)); + next->pi[0] = pi; + + for (i = 0; i < 3; i++) + next->sep[i] = (bmin[i] + bmax[i]) / 2; + + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = next; + + node->childs[dir] = next; + next->father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree3FM :: DeleteElement (int pi) + { + ADTreeNode3FM * node = ela.Get(pi); + + int i; + for (i = 0; i < ADTN_SIZE; i++) + if (node->pi[i] == pi) + node->pi[i] = 0; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + void ADTree3FM :: GetIntersecting (const float * bmin, + const float * bmax, + Array & pis) const + { + static Array stack(1000); + ADTreeNode3FM * node; + int dir, i, stacks; + + stack.SetSize (1000); + pis.SetSize(0); + + stack.Elem(1) = root; + stacks = 1; + + while (stacks) + { + node = stack.Get(stacks); + stacks--; + + int * hpi = node->pi; + for (i = 0; i < ADTN_SIZE; i++) + if (hpi[i]) + { + float * datai = &node->data[i][0]; + if (datai[0] >= bmin[0] && datai[0] <= bmax[0] && + datai[1] >= bmin[1] && datai[1] <= bmax[1] && + datai[2] >= bmin[2] && datai[2] <= bmax[2]) + + pis.Append (node->pi[i]); + } + + /* + if (node->pi) + { + if (node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && + node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && + node->data[2] >= bmin[2] && node->data[2] <= bmax[2]) + + pis.Append (node->pi); + } + */ + + int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1; + int i1max = (bmax[0] < node->sep[0]) ? 0 : 1; + int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1; + int i2max = (bmax[1] < node->sep[1]) ? 0 : 1; + int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1; + int i3max = (bmax[2] < node->sep[2]) ? 0 : 1; + + int i1, i2, i3; + for (i1 = i1min; i1 <= i1max; i1++) + for (i2 = i2min; i2 <= i2max; i2++) + for (i3 = i3min; i3 <= i3max; i3++) + { + i = i1+2*i2+4*i3; + if (node->childs[i]) + { + stacks++; + stack.Elem(stacks) = node->childs[i]; + } + } + + /* + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack.Elem(stacks) = node->left; + stackdir.Elem(stacks) = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack.Elem(stacks) = node->right; + stackdir.Elem(stacks) = ndir; + } + */ + } + } + + void ADTree3FM :: PrintRec (ostream & ost, const ADTreeNode3FM * node) const + { + int i; + if (node->data) + { + ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + for (i = 0; i < 3; i++) + ost << node->data[i] << " "; + ost << endl; + } + + for (i = 0; i < 8; i++) + if (node->childs[i]) + PrintRec (ost, node->childs[i]); + } + + + + +#endif + + + + + + + /* ******************************* ADTree6 ******************************* */ + + + ADTreeNode6 :: ADTreeNode6() + { + pi = -1; + + left = NULL; + right = NULL; + father = NULL; + nchilds = 0; + } + + void ADTreeNode6 :: DeleteChilds () + { + if (left) + { + left->DeleteChilds(); + delete left; + left = NULL; + } + if (right) + { + right->DeleteChilds(); + delete right; + right = NULL; + } + } + + + BlockAllocator ADTreeNode6 :: ball (sizeof (ADTreeNode6)); + void * ADTreeNode6 :: operator new(size_t s) + { + return ball.Alloc(); + } + + void ADTreeNode6 :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + ADTree6 :: ADTree6 (const float * acmin, + const float * acmax) + : ela(0) + { + memcpy (cmin, acmin, 6 * sizeof(float)); + memcpy (cmax, acmax, 6 * sizeof(float)); + + root = new ADTreeNode6; + root->sep = (cmin[0] + cmax[0]) / 2; + } + + ADTree6 :: ~ADTree6 () + { + root->DeleteChilds(); + delete root; + } + + void ADTree6 :: Insert (const float * p, int pi) + { + ADTreeNode6 *node(NULL); + ADTreeNode6 *next; + int dir; + int lr(0); + + float bmin[6]; + float bmax[6]; + + + memcpy (bmin, cmin, 6 * sizeof(float)); + memcpy (bmax, cmax, 6 * sizeof(float)); + + next = root; + dir = 0; + while (next) + { + node = next; + + if (node->pi == -1) + { + memcpy (node->data, p, 6 * sizeof(float)); + node->pi = pi; + + if (ela.Size() < pi+1) + ela.SetSize (pi+1); + ela[pi] = node; + + return; + } + + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + + dir++; + if (dir == 6) dir = 0; + } + + + next = new ADTreeNode6; + memcpy (next->data, p, 6 * sizeof(float)); + next->pi = pi; + next->sep = (bmin[dir] + bmax[dir]) / 2; + + if (ela.Size() < pi+1) + ela.SetSize (pi+1); + ela[pi] = next; + + if (lr) + node->right = next; + else + node->left = next; + next -> father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree6 :: DeleteElement (int pi) + { + ADTreeNode6 * node = ela[pi]; + + node->pi = -1; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + void ADTree6 :: PrintMemInfo (ostream & ost) const + { + ost << Elements() << " elements a " << sizeof(ADTreeNode6) + << " Bytes = " + << Elements() * sizeof(ADTreeNode6) << endl; + ost << "maxind = " << ela.Size() << " = " << sizeof(ADTreeNode6*) * ela.Size() << " Bytes" << endl; + } + + + + class inttn6 { + public: + int dir; + ADTreeNode6 * node; + }; + + + + + void ADTree6 :: GetIntersecting (const float * bmin, + const float * bmax, + Array & pis) const + { + // static Array stack(10000); + // stack.SetSize (10000); + ArrayMem stack(10000); + pis.SetSize(0); + + stack[0].node = root; + stack[0].dir = 0; + int stacks = 0; + + while (stacks >= 0) + { + ADTreeNode6 * node = stack[stacks].node; + int dir = stack[stacks].dir; + + stacks--; + if (node->pi != -1) + { + if (node->data[0] > bmax[0] || + node->data[1] > bmax[1] || + node->data[2] > bmax[2] || + node->data[3] < bmin[3] || + node->data[4] < bmin[4] || + node->data[5] < bmin[5]) + ; + else + { + pis.Append (node->pi); + } + } + + int ndir = (dir+1) % 6; + + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack[stacks].node = node->left; + stack[stacks].dir = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack[stacks].node = node->right; + stack[stacks].dir = ndir; + } + } + } + + void ADTree6 :: PrintRec (ostream & ost, const ADTreeNode6 * node) const + { + + if (node->data) + { + ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + for (int i = 0; i < 6; i++) + ost << node->data[i] << " "; + ost << endl; + } + if (node->left) + PrintRec (ost, node->left); + if (node->right) + PrintRec (ost, node->right); + } + + + int ADTree6 :: DepthRec (const ADTreeNode6 * node) const + { + int ldepth = 0; + int rdepth = 0; + + if (node->left) + ldepth = DepthRec(node->left); + if (node->right) + rdepth = DepthRec(node->right); + return 1 + max2 (ldepth, rdepth); + } + + int ADTree6 :: ElementsRec (const ADTreeNode6 * node) const + { + int els = 1; + if (node->left) + els += ElementsRec(node->left); + if (node->right) + els += ElementsRec(node->right); + return els; + } + + + + + + +#ifdef ABC + + /* ******************************* ADTree6F ******************************* */ + + + ADTreeNode6F :: ADTreeNode6F() + { + pi = 0; + father = NULL; + nchilds = 0; + int i; + for (i = 0; i < 64; i++) + childs[i] = NULL; + } + + void ADTreeNode6F :: DeleteChilds () + { + int i; + + for (i = 0; i < 64; i++) + { + if (childs[i]) + childs[i]->DeleteChilds(); + delete childs[i]; + childs[i] = NULL; + } + } + + + BlockAllocator ADTreeNode6F :: ball(sizeof (ADTreeNode6F)); + + void * ADTreeNode6F :: operator new(size_t) + { + return ball.Alloc(); + } + + void ADTreeNode6F :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + + + ADTree6F :: ADTree6F (const float * acmin, + const float * acmax) + : ela(0) + { + memcpy (cmin, acmin, 6 * sizeof(float)); + memcpy (cmax, acmax, 6 * sizeof(float)); + + root = new ADTreeNode6F; + for (int i = 0; i < 6; i++) + root->sep[i] = (cmin[i] + cmax[i]) / 2; + } + + ADTree6F :: ~ADTree6F () + { + root->DeleteChilds(); + delete root; + } + + + void ADTree6F :: Insert (const float * p, int pi) + { + ADTreeNode6F *node; + ADTreeNode6F *next; + int lr; + + float bmin[6]; + float bmax[6]; + int i, dir; + + memcpy (bmin, cmin, 6 * sizeof(float)); + memcpy (bmax, cmax, 6 * sizeof(float)); + + next = root; + while (next) + { + node = next; + + if (!node->pi) + { + memcpy (node->data, p, 6 * sizeof(float)); + node->pi = pi; + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = node; + + return; + } + + dir = 0; + for (i = 0; i < 6; i++) + { + if (node->sep[i] > p[i]) + { + bmax[i] = node->sep[i]; + } + else + { + bmin[i] = node->sep[i]; + dir += (1 << i); + } + } + next = node->childs[dir]; + + /* + if (node->sep > p[dir]) + { + next = node->left; + bmax[dir] = node->sep; + lr = 0; + } + else + { + next = node->right; + bmin[dir] = node->sep; + lr = 1; + } + */ + } + + + next = new ADTreeNode6F; + memcpy (next->data, p, 6 * sizeof(float)); + next->pi = pi; + + for (i = 0; i < 6; i++) + next->sep[i] = (bmin[i] + bmax[i]) / 2; + + + if (ela.Size() < pi) + ela.SetSize (pi); + ela.Elem(pi) = next; + + node->childs[dir] = next; + next->father = node; + + while (node) + { + node->nchilds++; + node = node->father; + } + } + + void ADTree6F :: DeleteElement (int pi) + { + ADTreeNode6F * node = ela.Get(pi); + + node->pi = 0; + + node = node->father; + while (node) + { + node->nchilds--; + node = node->father; + } + } + + void ADTree6F :: GetIntersecting (const float * bmin, + const float * bmax, + Array & pis) const + { + static Array stack(1000); + ADTreeNode6F * node; + int dir, i, stacks; + + stack.SetSize (1000); + pis.SetSize(0); + + stack.Elem(1) = root; + stacks = 1; + + while (stacks) + { + node = stack.Get(stacks); + stacks--; + + if (node->pi) + { + if ( + node->data[0] >= bmin[0] && node->data[0] <= bmax[0] && + node->data[1] >= bmin[1] && node->data[1] <= bmax[1] && + node->data[2] >= bmin[2] && node->data[2] <= bmax[2] && + node->data[3] >= bmin[3] && node->data[3] <= bmax[3] && + node->data[4] >= bmin[4] && node->data[4] <= bmax[4] && + node->data[5] >= bmin[5] && node->data[5] <= bmax[5] + ) + + pis.Append (node->pi); + } + + + int i1min = (bmin[0] <= node->sep[0]) ? 0 : 1; + int i1max = (bmax[0] < node->sep[0]) ? 0 : 1; + int i2min = (bmin[1] <= node->sep[1]) ? 0 : 1; + int i2max = (bmax[1] < node->sep[1]) ? 0 : 1; + int i3min = (bmin[2] <= node->sep[2]) ? 0 : 1; + int i3max = (bmax[2] < node->sep[2]) ? 0 : 1; + + int i4min = (bmin[3] <= node->sep[3]) ? 0 : 1; + int i4max = (bmax[3] < node->sep[3]) ? 0 : 1; + int i5min = (bmin[4] <= node->sep[4]) ? 0 : 1; + int i5max = (bmax[4] < node->sep[4]) ? 0 : 1; + int i6min = (bmin[5] <= node->sep[5]) ? 0 : 1; + int i6max = (bmax[5] < node->sep[5]) ? 0 : 1; + + int i1, i2, i3, i4, i5, i6; + for (i1 = i1min; i1 <= i1max; i1++) + for (i2 = i2min; i2 <= i2max; i2++) + for (i3 = i3min; i3 <= i3max; i3++) + for (i4 = i4min; i4 <= i4max; i4++) + for (i5 = i5min; i5 <= i5max; i5++) + for (i6 = i6min; i6 <= i6max; i6++) + { + i = i1 + 2*i2 + 4*i3 + 8*i4 + 16*i5 +32*i6; + if (node->childs[i]) + { + stacks++; + stack.Elem(stacks) = node->childs[i]; + } + } + + /* + if (node->left && bmin[dir] <= node->sep) + { + stacks++; + stack.Elem(stacks) = node->left; + stackdir.Elem(stacks) = ndir; + } + if (node->right && bmax[dir] >= node->sep) + { + stacks++; + stack.Elem(stacks) = node->right; + stackdir.Elem(stacks) = ndir; + } + */ + } + } + + void ADTree6F :: PrintRec (ostream & ost, const ADTreeNode6F * node) const + { + int i; + if (node->data) + { + ost << node->pi << ": "; + ost << node->nchilds << " childs, "; + for (i = 0; i < 6; i++) + ost << node->data[i] << " "; + ost << endl; + } + + for (i = 0; i < 64; i++) + if (node->childs[i]) + PrintRec (ost, node->childs[i]); + } + + + +#endif + + + + /* ************************************* Point3dTree ********************** */ + + + + Point3dTree :: Point3dTree (const Point<3> & pmin, const Point<3> & pmax) + { + float pmi[3], pma[3]; + for (int i = 0; i < 3; i++) + { + pmi[i] = pmin(i); + pma[i] = pmax(i); + } + tree = new ADTree3 (pmi, pma); + } + + Point3dTree :: ~Point3dTree () + { + delete tree; + } + + + + void Point3dTree :: Insert (const Point<3> & p, int pi) + { + float pd[3]; + pd[0] = p(0); + pd[1] = p(1); + pd[2] = p(2); + tree->Insert (pd, pi); + } + + void Point3dTree :: GetIntersecting (const Point<3> & pmin, const Point<3> & pmax, + Array & pis) const + { + float pmi[3], pma[3]; + for (int i = 0; i < 3; i++) + { + pmi[i] = pmin(i); + pma[i] = pmax(i); + } + tree->GetIntersecting (pmi, pma, pis); + } + + + + + + + + + + Box3dTree :: Box3dTree (const Box<3> & abox) + { + boxpmin = abox.PMin(); + boxpmax = abox.PMax(); + float tpmin[6], tpmax[6]; + for (int i = 0; i < 3; i++) + { + tpmin[i] = tpmin[i+3] = boxpmin(i); + tpmax[i] = tpmax[i+3] = boxpmax(i); + } + tree = new ADTree6 (tpmin, tpmax); + } + + Box3dTree :: Box3dTree (const Point<3> & apmin, const Point<3> & apmax) + { + boxpmin = apmin; + boxpmax = apmax; + float tpmin[6], tpmax[6]; + for (int i = 0; i < 3; i++) + { + tpmin[i] = tpmin[i+3] = boxpmin(i); + tpmax[i] = tpmax[i+3] = boxpmax(i); + } + tree = new ADTree6 (tpmin, tpmax); + } + + Box3dTree :: ~Box3dTree () + { + delete tree; + } + + void Box3dTree :: Insert (const Point<3> & bmin, const Point<3> & bmax, int pi) + { + float tp[6]; + + for (int i = 0; i < 3; i++) + { + tp[i] = bmin(i); + tp[i+3] = bmax(i); + } + + tree->Insert (tp, pi); + } + + void Box3dTree ::GetIntersecting (const Point<3> & pmin, const Point<3> & pmax, + Array & pis) const + { + float tpmin[6]; + float tpmax[6]; + + for (int i = 0; i < 3; i++) + { + tpmin[i] = boxpmin(i); + tpmax[i] = pmax(i); + + tpmin[i+3] = pmin(i); + tpmax[i+3] = boxpmax(i); + } + + tree->GetIntersecting (tpmin, tpmax, pis); + } + +} diff --git a/libsrc/gprim/adtree.hpp b/libsrc/gprim/adtree.hpp new file mode 100644 index 00000000..e35e6de2 --- /dev/null +++ b/libsrc/gprim/adtree.hpp @@ -0,0 +1,487 @@ +#ifndef FILE_ADTREE +#define FILE_ADTREE + +/* *************************************************************************/ +/* File: adtree.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 16. Feb. 98 */ +/* Redesigned by Wolfram Muehlhuber, May 1998 */ +/* *************************************************************************/ + + +namespace netgen +{ + +/** + Alternating Digital Tree + */ + +// #include "../include/mystdlib.h" +// #include "../include/myadt.hpp" + +class ADTreeNode +{ +public: + ADTreeNode *left, *right, *father; + int dim; + float sep; + float *data; + float *boxmin; + float *boxmax; + int pi; + int nchilds; + + ADTreeNode (int adim); + ~ADTreeNode (); + + friend class ADTree; +}; + + +class ADTreeCriterion +{ +public: + ADTreeCriterion() { } + virtual int Eval (const ADTreeNode * node) const = 0; +}; + + +class ADTree +{ + int dim; + ADTreeNode * root; + float *cmin, *cmax; + Array ela; + const ADTreeCriterion * criterion; + + Array stack; + Array stackdir; + int stackindex; + +public: + ADTree (int adim, const float * acmin, + const float * acmax); + ~ADTree (); + + void Insert (const float * p, int pi); + // void GetIntersecting (const float * bmin, const float * bmax, + // Array & pis) const; + void SetCriterion (ADTreeCriterion & acriterion); + void Reset (); + int Next (); + void GetMatch (Array & matches); + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + + void PrintRec (ostream & ost, const ADTreeNode * node) const; +}; + + + +class ADTreeNode3 +{ +public: + ADTreeNode3 *left, *right, *father; + float sep; + float data[3]; + int pi; + int nchilds; + + ADTreeNode3 (); + void DeleteChilds (); + friend class ADTree3; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); +}; + + +class ADTree3 +{ + ADTreeNode3 * root; + float cmin[3], cmax[3]; + Array ela; + +public: + ADTree3 (const float * acmin, + const float * acmax); + ~ADTree3 (); + + void Insert (const float * p, int pi); + void GetIntersecting (const float * bmin, const float * bmax, + Array & pis) const; + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + + void PrintRec (ostream & ost, const ADTreeNode3 * node) const; +}; + + +/* + +// divide each direction +#define ADTN_DIV 10 +class ADTreeNode3Div +{ +public: + ADTreeNode3Div *father; + ADTreeNode3Div *childs[ADTN_DIV]; + + float minx, dist; + float data[3]; + int pi; + int nchilds; + + ADTreeNode3Div (); + void DeleteChilds (); + friend class ADTree3Div; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); +}; + + +class ADTree3Div +{ + ADTreeNode3Div * root; + float cmin[3], cmax[3]; + Array ela; + +public: + ADTree3Div (const float * acmin, + const float * acmax); + ~ADTree3Div (); + + void Insert (const float * p, int pi); + void GetIntersecting (const float * bmin, const float * bmax, + Array & pis) const; + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + + void PrintRec (ostream & ost, const ADTreeNode3Div * node) const; +}; + + + + +#define ADTN_SIZE 10 + +// multiple entries +class ADTreeNode3M +{ +public: + ADTreeNode3M *left, *right, *father; + float sep; + float data[ADTN_SIZE][3]; + int pi[ADTN_SIZE]; + int nchilds; + + ADTreeNode3M (); + void DeleteChilds (); + friend class ADTree3M; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); +}; + + +class ADTree3M +{ + ADTreeNode3M * root; + float cmin[3], cmax[3]; + Array ela; + +public: + ADTree3M (const float * acmin, + const float * acmax); + ~ADTree3M (); + + void Insert (const float * p, int pi); + void GetIntersecting (const float * bmin, const float * bmax, + Array & pis) const; + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + + void PrintRec (ostream & ost, const ADTreeNode3M * node) const; +}; + + + + + + +class ADTreeNode3F +{ +public: + ADTreeNode3F *father; + ADTreeNode3F *childs[8]; + float sep[3]; + float data[3]; + int pi; + int nchilds; + + ADTreeNode3F (); + void DeleteChilds (); + friend class ADTree3F; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); +}; + +// fat tree +class ADTree3F +{ + ADTreeNode3F * root; + float cmin[3], cmax[3]; + Array ela; + +public: + ADTree3F (const float * acmin, + const float * acmax); + ~ADTree3F (); + + void Insert (const float * p, int pi); + void GetIntersecting (const float * bmin, const float * bmax, + Array & pis) const; + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + + void PrintRec (ostream & ost, const ADTreeNode3F * node) const; +}; + + + + +class ADTreeNode3FM +{ +public: + ADTreeNode3FM *father; + ADTreeNode3FM *childs[8]; + float sep[3]; + float data[ADTN_SIZE][3]; + int pi[ADTN_SIZE]; + int nchilds; + + ADTreeNode3FM (); + void DeleteChilds (); + friend class ADTree3FM; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); +}; + +// fat tree +class ADTree3FM +{ + ADTreeNode3FM * root; + float cmin[3], cmax[3]; + Array ela; + +public: + ADTree3FM (const float * acmin, + const float * acmax); + ~ADTree3FM (); + + void Insert (const float * p, int pi); + void GetIntersecting (const float * bmin, const float * bmax, + Array & pis) const; + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + + void PrintRec (ostream & ost, const ADTreeNode3FM * node) const; +}; + + + +*/ + + + + + +class ADTreeNode6 +{ +public: + ADTreeNode6 *left, *right, *father; + float sep; + float data[6]; + int pi; + int nchilds; + + ADTreeNode6 (); + void DeleteChilds (); + friend class ADTree6; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); +}; + + +class ADTree6 +{ + ADTreeNode6 * root; + float cmin[6], cmax[6]; + Array ela; + +public: + ADTree6 (const float * acmin, + const float * acmax); + ~ADTree6 (); + + void Insert (const float * p, int pi); + void GetIntersecting (const float * bmin, const float * bmax, + Array & pis) const; + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + int Depth () const + { return DepthRec (root); } + int Elements () const + { return ElementsRec (root); } + + void PrintRec (ostream & ost, const ADTreeNode6 * node) const; + int DepthRec (const ADTreeNode6 * node) const; + int ElementsRec (const ADTreeNode6 * node) const; + + void PrintMemInfo (ostream & ost) const; +}; + + + + +/* + +class ADTreeNode6F +{ +public: + ADTreeNode6F * father; + ADTreeNode6F * childs[64]; + + float sep[6]; + float data[6]; + int pi; + int nchilds; + + ADTreeNode6F (); + void DeleteChilds (); + friend class ADTree6F; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); +}; + + +class ADTree6F +{ + ADTreeNode6F * root; + float cmin[6], cmax[6]; + Array ela; + +public: + ADTree6F (const float * acmin, + const float * acmax); + ~ADTree6F (); + + void Insert (const float * p, int pi); + void GetIntersecting (const float * bmin, const float * bmax, + Array & pis) const; + + void DeleteElement (int pi); + + + void Print (ostream & ost) const + { PrintRec (ost, root); } + int Depth () const + { return DepthRec (root); } + + void PrintRec (ostream & ost, const ADTreeNode6F * node) const; + int DepthRec (const ADTreeNode6F * node) const; +}; + + + + + + + +*/ + + + + + +class Point3dTree +{ + ADTree3 * tree; + +public: + DLL_HEADER Point3dTree (const Point<3> & pmin, const Point<3> & pmax); + DLL_HEADER ~Point3dTree (); + DLL_HEADER void Insert (const Point<3> & p, int pi); + void DeleteElement (int pi) + { tree->DeleteElement(pi); } + DLL_HEADER void GetIntersecting (const Point<3> & pmin, const Point<3> & pmax, + Array & pis) const; + const ADTree3 & Tree() const { return *tree; }; +}; + + + +class Box3dTree +{ + ADTree6 * tree; + Point<3> boxpmin, boxpmax; +public: + Box3dTree (const Box<3> & abox); + Box3dTree (const Point<3> & apmin, const Point<3> & apmax); + ~Box3dTree (); + void Insert (const Point<3> & bmin, const Point<3> & bmax, int pi); + void Insert (const Box<3> & box, int pi) + { + Insert (box.PMin(), box.PMax(), pi); + } + void DeleteElement (int pi) + { tree->DeleteElement(pi); } + void GetIntersecting (const Point<3> & pmin, const Point<3> & pmax, + Array & pis) const; + + const ADTree6 & Tree() const { return *tree; }; +}; + +} + +#endif diff --git a/libsrc/gprim/geom2d.cpp b/libsrc/gprim/geom2d.cpp new file mode 100644 index 00000000..34263348 --- /dev/null +++ b/libsrc/gprim/geom2d.cpp @@ -0,0 +1,489 @@ +#include + +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +namespace netgen +{ + +ostream & operator<<(ostream & s, const Point2d & p) +{ + return s << "(" << p.px << ", " << p.py << ")"; +} + +ostream & operator<<(ostream & s, const Vec2d & v) +{ + return s << "(" << v.vx << ", " << v.vy << ")"; +} + +#ifdef none +ostream & operator<<(ostream & s, const Line2d & l) + { + return s << l.p1 << "-" << l.p2; +} + +ostream & operator<<(ostream & s, const TRIANGLE2D & t) +{ + return s << t.p1 << "-" << t.p2 << "-" << t.p3; +} +#endif + + +double Fastatan2 (double x, double y) +{ + if (y > 0) + { + if (x > 0) + return y / (x+y); + else + return 1 - x / (y-x); + } + else if (y < 0) + { + if (x < 0) + return 2 + y / (x+y); + else + return 3 - x / (y-x); + } + else + { + if (x >= 0) + return 0; + else + return 2; + } +} + + +double Angle (const Vec2d & v) +{ + if (v.X() == 0 && v.Y() == 0) + return 0; + + double ang = atan2 (v.Y(), v.X()); + if (ang < 0) ang+= 2 * M_PI; + return ang; +} + +double FastAngle (const Vec2d & v) +{ + return Fastatan2 (v.X(), v.Y()); +} + +double Angle (const Vec2d & v1, const Vec2d & v2) +{ + double ang = Angle(v2) - Angle(v1); + if (ang < 0) ang += 2 * M_PI; + return ang; +} + +double FastAngle (const Vec2d & v1, const Vec2d & v2) +{ + double ang = FastAngle(v2) - FastAngle(v1); + if (ang < 0) ang += 4; + return ang; +} + +/* +int CW (const Point2d & p1,const Point2d & p2,const Point2d & p3) +{ + return Cross (p2 - p1, p3 - p2) < 0; +} + +int CCW (const Point2d & p1,const Point2d & p2,const Point2d & p3) +{ + return Cross (p2 - p1, p3 - p2) > 0; +} +*/ + +double Dist2(const Line2d & g, const Line2d & h ) + { + double dd = 0.0, d1,d2,d3,d4; + Point2d cp = CrossPoint(g,h); + + if ( Parallel(g,h) || !IsOnLine(g,cp) || !IsOnLine(h,cp) ) + { + d1 = Dist2(g.P1(),h.P1()); + d2 = Dist2(g.P1(),h.P2()); + d3 = Dist2(g.P2(),h.P1()); + d4 = Dist2(g.P2(),h.P2()); + if (d1= -heps * len2 && c2 <= heps * len2 && d <= heps * len2; +} + +#ifdef none +int IsOnLine (const PLine2d & l, const Point2d & p, double heps) + { + double c1 = (p - l.P1()) * l.Delta(); + double c2 = (p - l.P2()) * l.Delta(); + double d = fabs (Cross ( (p - l.P1()), l.Delta())); + double len2 = l.Length2(); + + return c1 >= -heps * len2 && c2 <= heps * len2 && d <= heps * len2; +} + +int IsOnLongLine (const Line2d & l, const Point2d & p) + { + double d = fabs (Cross ( (p - l.P1()), l.Delta())); + return d <= EPSGEOM * l.Length(); +} + +int Hit (const Line2d & l1, const Line2d & l2, double heps) + { + double den = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l2.P2())); + double num1 = Cross ( (l2.P1() - l1.P1()), (l2.P1() - l2.P2())); + double num2 = Cross ( (l1.P2() - l1.P1()), (l2.P1() - l1.P1())); + num1 *= sgn (den); + num2 *= sgn (den); + den = fabs (den); + + int ch = (-den * heps <= num1 && num1 <= den * (1 + heps) && + -den * heps <= num2 && num2 <= den * (1 + heps)); + return ch; +} + + +void Line2d :: GetNormal (Line2d & n) const +{ + double ax = P2().X()-P1().X(), + ay = P2().Y()-P1().Y(); + Point2d mid(P1().X()+.5*ax, P1().Y()+.5*ay); + + n=Line2d(mid,Point2d(mid.X()+ay,mid.Y()-ax)) ; +} + +Vec2d Line2d :: NormalDelta () const +{ + Line2d tmp; + GetNormal(tmp); + return tmp.Delta(); +} + +int TRIANGLE2D :: IsOn (const Point2d & p) const + { + return IsOnLine (Line2d (p1, p2), p) || + IsOnLine (Line2d (p1, p3), p) || + IsOnLine (Line2d (p2, p3), p); + } + + +int TRIANGLE2D :: IsIn (const Point2d & p) const +{ + return ::CW(p, p1, p2) == ::CW(p, p2, p3) && + ::CW(p, p1, p2) == ::CW(p, p3, p1); +} + + + +int PTRIANGLE2D :: IsOn (const Point2d & p) const +{ + return IsOnLine (Line2d (*p1, *p2), p) || + IsOnLine (Line2d (*p1, *p3), p) || + IsOnLine (Line2d (*p2, *p3), p); +} + + +int PTRIANGLE2D :: IsIn (const Point2d & p) const +{ + return ::CW(p, *p1, *p2) == ::CW(p, *p2, *p3) && + ::CW(p, *p1, *p2) == ::CW(p, *p3, *p1); +} + +#endif + + + + + + +Polygon2d :: Polygon2d () +{ + ; +} + +Polygon2d :: ~Polygon2d () +{ + ; +} + +void Polygon2d :: AddPoint (const Point2d & p) +{ + points.Append(p); +} + + +double Polygon2d :: HArea () const +{ + int i; + double ar = 0; + for (i = 1; i <= points.Size(); i++) + { + const Point2d & p1 = points.Get(i); + const Point2d & p2 = points.Get(i%points.Size()+1); + ar += + (p2.X()-p1.X()) * p1.Y() - + (p2.Y()-p1.Y()) * p1.X(); + } + return ar/2; + /* + CURSOR c; + double ar = 0; + Point2d * p1, * p2, p0 = Point2d(0, 0); + Vec2d v1, v2 = Vec2d(1, 0); + + p2 = points[points.Last()]; + for (c = points.First(); c != points.Head(); c++) + { + p1 = p2; + p2 = points[c]; + ar += Cross ( (*p2-*p1), (*p1 - p0)); + } + return ar / 2; + */ +} + + +int Polygon2d :: IsOn (const Point2d & p) const +{ + int i; + for (i = 1; i <= points.Size(); i++) + { + const Point2d & p1 = points.Get(i); + const Point2d & p2 = points.Get(i%points.Size()+1); + if (IsOnLine (Line2d(p1, p2), p)) return 1; + } + return 0; + /* + CURSOR c; + Point2d * p1, * p2; + + p2 = points[points.Last()]; + for (c = points.First(); c != points.Head(); c++) + { + p1 = p2; + p2 = points[c]; + if (IsOnLine (Line2d(*p1, *p2), p)) return 1; + } + return 0; + */ +} + + +int Polygon2d :: IsIn (const Point2d & p) const +{ + int i; + double sum = 0, ang; + for (i = 1; i <= points.Size(); i++) + { + const Point2d & p1 = points.Get(i); + const Point2d & p2 = points.Get(i%points.Size()+1); + ang = Angle ( (p1 - p), (p2 - p) ); + if (ang > M_PI) ang -= 2 * M_PI; + sum += ang; + } + return fabs(sum) > M_PI; + /* + CURSOR c; + Point2d * p1, * p2; + double sum = 0, ang; + + p2 = points[points.Last()]; + for (c = points.First(); c != points.Head(); c++) + { + p1 = p2; + p2 = points[c]; + ang = Angle ( (*p1 - p), (*p2 - p) ); + if (ang > M_PI) ang -= 2 * M_PI; + sum += ang; + } + + return fabs(sum) > M_PI; + */ +} + +int Polygon2d :: IsConvex () const + { + /* + Point2d *p, *pold, *pnew; + char cw; + CURSOR c; + + if (points.Length() < 3) return 0; + + c = points.Last(); + p = points[c]; + c--; + pold = points[c]; + pnew = points[points.First()]; + cw = ::CW (*pold, *p, *pnew); + + for (c = points.First(); c != points.Head(); c++) + { + pnew = points[c]; + if (cw != ::CW (*pold, *p, *pnew)) + return 0; + pold = p; + p = pnew; + } + */ + return 0; + } + + +int Polygon2d :: IsStarPoint (const Point2d & p) const + { + /* + Point2d *pnew, *pold; + char cw; + CURSOR c; + + if (points.Length() < 3) return 0; + + pold = points[points.Last()]; + pnew = points[points.First()]; + + cw = ::CW (p, *pold, *pnew); + + for (c = points.First(); c != points.Head(); c++) + { + pnew = points[c]; + if (cw != ::CW (p, *pold, *pnew)) + return 0; + pold = pnew; + } + return 1; + */ + return 0; + } + + +Point2d Polygon2d :: Center () const + { + /* + double ai, a = 0, x = 0, y = 0; + Point2d * p, *p2; + Point2d p0 = Point2d(0, 0); + CURSOR c; + + p2 = points[points.Last()]; + + for (c = points.First(); c != points.Head(); c++) + { + p = points[c]; + ai = Cross (*p2 - p0, *p - p0); + x += ai / 3 * (p2->X() + p->X()); + y += ai / 3 * (p2->Y() + p->Y()); + a+= ai; + p2 = p; + } + if (a != 0) + return Point2d (x / a, y / a); + else + return Point2d (0, 0); + */ + return Point2d (0, 0); + } + + + +Point2d Polygon2d :: EqualAreaPoint () const + { + /* + double a11 = 0, a12 = 0, a21= 0, a22 = 0; + double b1 = 0, b2 = 0, dx, dy; + double det; + Point2d * p, *p2; + CURSOR c; + + p = points[points.Last()]; + + for (c = points.First(); c != points.Head(); c++) + { + p2 = p; + p = points[c]; + + dx = p->X() - p2->X(); + dy = p->Y() - p2->Y(); + + a11 += sqr (dy); + a12 -= dx * dy; + a21 -= dx * dy; + a22 += sqr (dx); + b1 -= dy * (p->X() * p2->Y() - p2->X() * p->Y()); + b2 -= dx * (p->Y() * p2->X() - p2->Y() * p->X()); + } + + det = a11 * a22 - a21 * a12; + + if (det != 0) + return Point2d ( (b1 * a22 - b2 * a12) / det, + (a11 * b2 - a21 * b1) / det); + else + return Point2d (0, 0); +*/ + return Point2d (0, 0); + } + + +} diff --git a/libsrc/gprim/geom2d.hpp b/libsrc/gprim/geom2d.hpp new file mode 100644 index 00000000..334df09c --- /dev/null +++ b/libsrc/gprim/geom2d.hpp @@ -0,0 +1,886 @@ +#ifndef FILE_GEOM2D +#define FILE_GEOM2D + +/* *************************************************************************/ +/* File: geom2d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 5. Aug. 95 */ +/* *************************************************************************/ + +namespace netgen +{ + + /* Geometric Algorithms */ + +#define EPSGEOM 1E-5 + + + // extern void MyError (const char * ch); + + class Point2d; + class Vec2d; + + class LINE2D; + class Line2d; + class PLine2d; + class TRIANGLE2D; + class PTRIANGLE2D; + + + inline Vec2d operator- (const Point2d & p1, const Point2d & p2); + inline Point2d operator- (const Point2d & p1, const Vec2d & v); + inline Point2d operator+ (const Point2d & p1, const Vec2d & v); + inline Point2d Center (const Point2d & p1, const Point2d & p2); + + inline void PpSmV (const Point2d & p1, double s, const Vec2d & v, Point2d & p2); + inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v); + ostream & operator<<(ostream & s, const Point2d & p); + inline Vec2d operator- (const Point2d & p1, const Point2d & p2); + inline Point2d operator- (const Point2d & p1, const Vec2d & v); + inline Point2d operator+ (const Point2d & p1, const Vec2d & v); + inline Vec2d operator- (const Vec2d & p1, const Vec2d & v); + inline Vec2d operator+ (const Vec2d & p1, const Vec2d & v); + inline Vec2d operator* (double scal, const Vec2d & v); + DLL_HEADER double Angle (const Vec2d & v); + DLL_HEADER double FastAngle (const Vec2d & v); + DLL_HEADER double Angle (const Vec2d & v1, const Vec2d & v2); + DLL_HEADER double FastAngle (const Vec2d & v1, const Vec2d & v2); + ostream & operator<<(ostream & s, const Vec2d & v); + double Dist2(const Line2d & g, const Line2d & h ); // GH + int Near (const Point2d & p1, const Point2d & p2, const double eps); + + int Parallel (const Line2d & l1, const Line2d & l2, double peps = EPSGEOM); + int IsOnLine (const Line2d & l, const Point2d & p, double heps = EPSGEOM); + int IsOnLongLine (const Line2d & l, const Point2d & p); + int Hit (const Line2d & l1, const Line2d & l2, double heps = EPSGEOM); + ostream & operator<<(ostream & s, const Line2d & l); + DLL_HEADER Point2d CrossPoint (const PLine2d & l1, const PLine2d & l2); + DLL_HEADER Point2d CrossPoint (const Line2d & l1, const Line2d & l2); + int Parallel (const PLine2d & l1, const PLine2d & l2, double peps = EPSGEOM); + int IsOnLine (const PLine2d & l, const Point2d & p, double heps = EPSGEOM); + int IsOnLongLine (const PLine2d & l, const Point2d & p); + int Hit (const PLine2d & l1, const Line2d & l2, double heps = EPSGEOM); + ostream & operator<<(ostream & s, const Line2d & l); + ostream & operator<<(ostream & s, const TRIANGLE2D & t); + ostream & operator<<(ostream & s, const PTRIANGLE2D & t); + double Dist2 (const Point2d & p1, const Point2d & p2); + + /// + class Point2d + { + /// + friend class Vec2d; + + protected: + /// + double px, py; + + public: + /// + Point2d() { /* px = py = 0; */ } + /// + Point2d(double ax, double ay) { px = ax; py = ay; } + /// + Point2d(const Point2d & p2) { px = p2.px; py = p2.py; } + + Point2d (const Point<2> & p2) + { + px = p2(0); + py = p2(1); + } + /// + Point2d & operator= (const Point2d & p2) + { px = p2.px; py = p2.py; return *this; } + + /// + int operator== (const Point2d & p2) const // GH + { return (px == p2.px && py == p2.py) ; } + + /// + double & X() { return px; } + /// + double & Y() { return py; } + /// + double X() const { return px; } + /// + double Y() const { return py; } + + operator Point<2> () const + { + return Point<2> (px, py); + } + + + /// + friend inline Vec2d operator- (const Point2d & p1, const Point2d & p2); + /// + friend inline Point2d operator- (const Point2d & p1, const Vec2d & v); + /// + friend inline Point2d operator+ (const Point2d & p1, const Vec2d & v); + + /// + friend inline Point2d Center (const Point2d & p1, const Point2d & p2); + + const Point2d & SetToMin (const Point2d & p2) + { + if (p2.px < px) px = p2.px; + if (p2.py < py) py = p2.py; + return *this; + } + + + /// + const Point2d & SetToMax (const Point2d & p2) + { + if (p2.px > px) px = p2.px; + if (p2.py > py) py = p2.py; + return *this; + } + + /// + friend double Dist (const Point2d & p1, const Point2d & p2) + { return sqrt ( (p1.px - p2.px) * (p1.px - p2.px) + + (p1.py - p2.py) * (p1.py - p2.py) ); } + // { return sqrt ( sqr (p1.X()-p2.X()) + sqr (p1.Y()-p2.Y()) ); } + + /// + friend double Dist2 (const Point2d & p1, const Point2d & p2) + { return ( (p1.px - p2.px) * (p1.px - p2.px) + + (p1.py - p2.py) * (p1.py - p2.py) ); } + // { return sqr (p1.X()-p2.X()) + sqr (p1.Y()-p2.Y()) ; } + + + /** + Points clock-wise ? + Are the points (p1, p2, p3) clock-wise ? + */ + friend inline int CW (const Point2d & p1, const Point2d & p2, const Point2d & p3) + { + // return Cross (p2 - p1, p3 - p2) < 0; + return + (p2.px - p1.px) * (p3.py - p2.py) - + (p2.py - p1.py) * (p3.px - p2.px) < 0; + } + /** + Points counter-clock-wise ? + Are the points (p1, p2, p3) counter-clock-wise ? + */ + friend inline bool CCW (const Point2d & p1, const Point2d & p2, const Point2d & p3) + { + // return Cross (p2 - p1, p3 - p2) > 0; + return + (p2.px - p1.px) * (p3.py - p2.py) - + (p2.py - p1.py) * (p3.px - p2.px) > 0; + } /** + Points counter-clock-wise ? + Are the points (p1, p2, p3) counter-clock-wise ? + */ + friend inline bool CCW (const Point2d & p1, const Point2d & p2, const Point2d & p3, double eps) + { + // return Cross (p2 - p1, p3 - p2) > 0; + double ax = p2.px - p1.px; + double ay = p2.py - p1.py; + double bx = p3.px - p2.px; + double by = p3.py - p2.py; + + return ax*by - ay*bx > eps*eps*max2(ax*ax+ay*ay,bx*bx+by*by); + } + + /// + friend inline void PpSmV (const Point2d & p1, double s, const Vec2d & v, Point2d & p2); + /// + friend inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v); + + /// + friend ostream & operator<<(ostream & s, const Point2d & p); + }; + + + inline int Near (const Point2d & p1, const Point2d & p2, + const double eps = 1e-4 ) + { + return Dist2(p1,p2) <= eps*eps; + } + + + + + + + /// + class Vec2d + { + protected: + /// + double vx, vy; + + public: + /// + Vec2d() { /* vx = vy = 0; */ } + /// + Vec2d(double ax, double ay) + { vx = ax; vy = ay; } + /// + Vec2d(const Vec2d & v2) { vx = v2.vx; vy = v2.vy; } + + /// + explicit Vec2d(const Vec<2> & v2) { vx = v2(0); vy = v2(1); } + + /// + Vec2d(const Point2d & p1, const Point2d & p2) + { vx = p2.px - p1.px; vy = p2.py - p1.py; } + + /// + Vec2d & operator= (const Vec2d & p2) + { vx = p2.vx; vy = p2.vy; return *this; } + + /// + double & X() { return vx; } + /// + double & Y() { return vy; } + /// + double X() const { return vx; } + /// + double Y() const { return vy; } + + /// + double Length() const { return sqrt (vx * vx + vy * vy); } + /// + double Length2() const { return vx * vx + vy * vy; } + + void GetNormal (Vec2d & n) const { n.vx=-vy; n.vy=vx; } // GH + + /// + inline Vec2d & operator+= (const Vec2d & v2); + /// + inline Vec2d & operator-= (const Vec2d & v2); + /// + inline Vec2d & operator*= (double s); + /// + inline Vec2d & operator/= (double s); + + /// + friend inline Vec2d operator- (const Point2d & p1, const Point2d & p2); + /// + friend inline Point2d operator- (const Point2d & p1, const Vec2d & v); + /// + friend inline Point2d operator+ (const Point2d & p1, const Vec2d & v); + /// + friend inline Vec2d operator- (const Vec2d & p1, const Vec2d & v); + /// + friend inline Vec2d operator+ (const Vec2d & p1, const Vec2d & v); + /// + friend inline Vec2d operator* (double scal, const Vec2d & v); + + /// + friend double operator* (const Vec2d & v1, const Vec2d & v2) + { return v1.X() * v2.X() + v1.Y() * v2.Y(); } + + + /// + friend double Cross (const Vec2d & v1, const Vec2d & v2) + { return double(v1.X()) * double(v2.Y()) - + double(v1.Y()) * double(v2.X()); } + + /// + friend inline void PpSmV (const Point2d & p1, double s, const Vec2d & v, Point2d & p2); + /// + friend inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v); + + /// Angle in [0,2*PI) + + /// + friend DLL_HEADER double Angle (const Vec2d & v); + /// + friend DLL_HEADER double FastAngle (const Vec2d & v); + /// + friend DLL_HEADER double Angle (const Vec2d & v1, const Vec2d & v2); + /// + friend DLL_HEADER double FastAngle (const Vec2d & v1, const Vec2d & v2); + + /// + friend ostream & operator<<(ostream & s, const Vec2d & v); + }; + + + + /// + class Line2d + { + protected: + /// + Point2d p1, p2; + + public: + /// + Line2d() : p1(), p2() { }; + /// + Line2d(const Point2d & ap1, const Point2d & ap2) + { p1 = ap1; p2 = ap2; } + + /// + Line2d & operator= (const Line2d & l2) + { p1 = l2.p1; p2 = l2.p2; return *this;} + + /// + Point2d & P1() { return p1; } + /// + Point2d & P2() { return p2; } + /// + const Point2d & P1() const { return p1; } + /// + const Point2d & P2() const { return p2; } + + /// + double XMax() const { return max2 (p1.X(), p2.X()); } + /// + double YMax() const { return max2 (p1.Y(), p2.Y()); } + /// + double XMin() const { return min2 (p1.X(), p2.X()); } + /// + double YMin() const { return min2 (p1.Y(), p2.Y()); } + + /// + Vec2d Delta () const { return Vec2d (p2.X()-p1.X(), p2.Y()-p1.Y()); } + /// + double Length () const { return Delta().Length(); } + /// + double Length2 () const + { return sqr (p1.X() - p2.X()) + + sqr (p1.Y() - p2.Y()); } + + void GetNormal (Line2d & n) const; // GH + Vec2d NormalDelta () const; // GH + + /// square of the distance between two 2d-lines. + friend double Dist2(const Line2d & g, const Line2d & h ); // GH + + /// + friend DLL_HEADER Point2d CrossPoint (const Line2d & l1, const Line2d & l2); + /// returns 1 iff parallel + friend int CrossPointBarycentric (const Line2d & l1, const Line2d & l2, + double & lam1, double & lam2); + + /// + friend int Parallel (const Line2d & l1, const Line2d & l2, double peps); + /// + friend int IsOnLine (const Line2d & l, const Point2d & p, double heps); + /// + friend int IsOnLongLine (const Line2d & l, const Point2d & p); + /// + friend int Hit (const Line2d & l1, const Line2d & l2, double heps); + + /// + friend ostream & operator<<(ostream & s, const Line2d & l); + }; + + +#ifdef NONE + /// + class PLine2d + { + protected: + /// + Point2d const * p1, *p2; + + public: + /// + PLine2d() { }; + /// + PLine2d(Point2d const * ap1, Point2d const * ap2) + { p1 = ap1; p2 = ap2; } + + /// + PLine2d & operator= (const PLine2d & l2) + { p1 = l2.p1; p2 = l2.p2; return *this;} + + /// + const Point2d *& P1() { return p1; } + /// + const Point2d *& P2() { return p2; } + /// + const Point2d & P1() const { return *p1; } + /// + const Point2d & P2() const { return *p2; } + + /// + double XMax() const { return max2 (p1->X(), p2->X()); } + /// + double YMax() const { return max2 (p1->Y(), p2->Y()); } + /// + double XMin() const { return min2 (p1->X(), p2->X()); } + /// + double YMin() const { return min2 (p1->Y(), p2->Y()); } + + + /// + Vec2d Delta () const { return Vec2d (p2->X()-p1->X(), p2->Y()-p1->Y()); } + /// + double Length () const { return Delta().Length(); } + /// + double Length2 () const + { return sqr (p1->X() - p2->X()) + + sqr (p1->Y() - p2->Y()); } + + + + /// + friend Point2d CrossPoint (const PLine2d & l1, const PLine2d & l2); + /// + friend int Parallel (const PLine2d & l1, const PLine2d & l2, double peps); + /// + friend int IsOnLine (const PLine2d & l, const Point2d & p, double heps); + /// + friend int IsOnLongLine (const PLine2d & l, const Point2d & p); + /// + friend int Hit (const PLine2d & l1, const Line2d & l2, double heps); + + /// + friend ostream & operator<<(ostream & s, const Line2d & l); + }; + + + + /// + class ILINE + { + /// + INDEX i[2]; + + public: + /// + ILINE() {}; + /// + ILINE(INDEX i1, INDEX i2) { i[0] = i1; i[1] = i2; } + /// + ILINE(const ILINE & l) { i[0] = l.i[0]; i[1] = l.i[1]; } + + /// + ILINE & operator= (const ILINE & l) + { i[0] = l.i[0]; i[1] = l.i[1]; return *this; } + + /// + const INDEX & I(int ai) const { return i[ai-1]; } + /// + const INDEX & X() const { return i[0]; } + /// + const INDEX & Y() const { return i[1]; } + /// + const INDEX & I1() const { return i[0]; } + /// + const INDEX & I2() const { return i[1]; } + + /// + INDEX & I(int ai) { return i[ai-1]; } + /// + INDEX & X() { return i[0]; } + /// + INDEX & Y() { return i[1]; } + /// + INDEX & I1() { return i[0]; } + /// + INDEX & I2() { return i[1]; } + }; + + + + + /// + class TRIANGLE2D + { + private: + /// + Point2d p1, p2, p3; + + public: + /// + TRIANGLE2D() { }; + /// + TRIANGLE2D (const Point2d & ap1, const Point2d & ap2, + const Point2d & ap3) + { p1 = ap1; p2 = ap2; p3 = ap3;} + + /// + TRIANGLE2D & operator= (const TRIANGLE2D & t2) + { p1 = t2.p1; p2 = t2.p2; p3 = t2.p3; return *this; } + + /// + Point2d & P1() { return p1; } + /// + Point2d & P2() { return p2; } + /// + Point2d & P3() { return p3; } + /// + const Point2d & P1() const { return p1; } + /// + const Point2d & P2() const { return p2; } + /// + const Point2d & P3() const { return p3; } + + /// + double XMax() const { return max3 (p1.X(), p2.X(), p3.X()); } + /// + double YMax() const { return max3 (p1.Y(), p2.Y(), p3.Y()); } + /// + double XMin() const { return min3 (p1.X(), p2.X(), p3.X()); } + /// + double YMin() const { return min3 (p1.Y(), p2.Y(), p3.Y()); } + + /// + inline Point2d Center () const + { return Point2d( (p1.X()+p2.X()+p3.X())/3, (p1.Y()+p2.Y()+p3.Y())/3); } + + /// + int Regular() const; + /// + int CW () const; + /// + int CCW () const; + + /// + int IsOn (const Point2d & p) const; + /// + int IsIn (const Point2d & p) const; + /// + friend ostream & operator<<(ostream & s, const TRIANGLE2D & t); + }; + + + /// + class PTRIANGLE2D + { + private: + /// + Point2d const *p1, *p2, *p3; + + public: + /// + PTRIANGLE2D() { }; + /// + PTRIANGLE2D (const Point2d * ap1, const Point2d * ap2, + const Point2d * ap3) + { p1 = ap1; p2 = ap2; p3 = ap3;} + + /// + PTRIANGLE2D & operator= (const PTRIANGLE2D & t2) + { p1 = t2.p1; p2 = t2.p2; p3 = t2.p3; return *this; } + + /// + const Point2d *& P1() { return p1; } + /// + const Point2d *& P2() { return p2; } + /// + const Point2d *& P3() { return p3; } + /// + const Point2d * P1() const { return p1; } + /// + const Point2d * P2() const { return p2; } + /// + const Point2d * P3() const { return p3; } + + /// + double XMax() const { return max3 (p1->X(), p2->X(), p3->X()); } + /// + double YMax() const { return max3 (p1->Y(), p2->Y(), p3->Y()); } + /// + double XMin() const { return min3 (p1->X(), p2->X(), p3->X()); } + /// + double YMin() const { return min3 (p1->Y(), p2->Y(), p3->Y()); } + + /// + Point2d Center () const + { return Point2d( (p1->X()+p2->X()+p3->X())/3, (p1->Y()+p2->Y()+p3->Y())/3); } + + + /// + int Regular() const; + /// + int CW () const; + /// + int CCW () const; + + /// + int IsOn (const Point2d & p) const; + /// + int IsIn (const Point2d & p) const; + /// + friend ostream & operator<<(ostream & s, const PTRIANGLE2D & t); + }; +#endif + + + + class Polygon2d + { + protected: + Array points; + + public: + Polygon2d (); + ~Polygon2d (); + + void AddPoint (const Point2d & p); + int GetNP() const { return points.Size(); } + void GetPoint (int i, Point2d & p) const + { p = points.Get(i); } + void GetLine (int i, Point2d & p1, Point2d & p2) const + { p1 = points.Get(i); p2 = points.Get(i%points.Size()+1); } + + double Area () const { return fabs (HArea()); } + int CW () const { return HArea() > 0; } + int CCW () const { return HArea() < 0; } + + int IsOn (const Point2d & p) const; + int IsIn (const Point2d & p) const; + + int IsConvex () const; + + int IsStarPoint (const Point2d & p) const; + Point2d Center() const; + Point2d EqualAreaPoint () const; + private: + double HArea () const; + }; + + + /** Cheap approximation to atan2. + A monotone function of atan2(x,y) is computed. + */ + extern double Fastatan2 (double x, double y); + + + inline Vec2d & Vec2d :: operator+= (const Vec2d & v2) + { + vx += v2.vx; + vy += v2.vy; + return *this; + } + + inline Vec2d & Vec2d :: operator-= (const Vec2d & v2) + { + vx -= v2.vx; + vy -= v2.vy; + return *this; + } + + inline Vec2d & Vec2d :: operator*= (double s) + { + vx *= s; + vy *= s; + return *this; + } + + + inline Vec2d & Vec2d :: operator/= (double s) + { + if (s != 0) + { + vx /= s; + vy /= s; + } + else + { + MyError ("Vec2d::operator /=: Division by zero"); + } + return *this; + } + + + + inline Vec2d operator- (const Point2d & p1, const Point2d & p2) + { + return Vec2d (p1.X() - p2.X(), p1.Y() - p2.Y()); + } + + + inline Point2d operator- (const Point2d & p1, const Vec2d & v) + { + return Point2d (p1.X() - v.X(), p1.Y() - v.Y()); + } + + + inline Point2d operator+ (const Point2d & p1, const Vec2d & v) + { + return Point2d (p1.X() + v.X(), p1.Y() + v.Y()); + } + + + inline Point2d Center (const Point2d & p1, const Point2d & p2) + { + return Point2d ((p1.X() + p2.X()) / 2, (p1.Y() + p2.Y()) / 2); + } + + + inline Vec2d operator- (const Vec2d & v1, const Vec2d & v2) + { + return Vec2d (v1.X() - v2.X(), v1.Y() - v2.Y()); + } + + + inline Vec2d operator+ (const Vec2d & v1, const Vec2d & v2) + { + return Vec2d (v1.X() + v2.X(), v1.Y() + v2.Y()); + } + + + inline Vec2d operator* (double scal, const Vec2d & v) + { + return Vec2d (scal * v.X(), scal * v.Y()); + } + + + inline void PpSmV (const Point2d & p1, double s, + const Vec2d & v, Point2d & p2) + { + p2.X() = p1.X() + s * v.X(); + p2.Y() = p1.Y() + s * v.Y(); + } + + + inline void PmP (const Point2d & p1, const Point2d & p2, Vec2d & v) + { + v.X() = p1.X() - p2.X(); + v.Y() = p1.Y() - p2.Y(); + } + + + + + +#ifdef none + inline int TRIANGLE2D :: Regular() const + { + return fabs(Cross ( p2 - p1, p3 - p2)) > EPSGEOM; + } + + + inline int TRIANGLE2D :: CW () const + { + return Cross ( p2 - p1, p3 - p2) < 0; + } + + + inline int TRIANGLE2D :: CCW () const + { + return Cross ( p2 - p1, p3 - p2) > 0; + } + + + + + inline int PTRIANGLE2D :: Regular() const + { + return fabs(Cross ( *p2 - *p1, *p3 - *p2)) > EPSGEOM; + } + + + inline int PTRIANGLE2D :: CW () const + { + return Cross ( *p2 - *p1, *p3 - *p2) < 0; + } + + + inline int PTRIANGLE2D :: CCW () const + { + return Cross ( *p2 - *p1, *p3 - *p2) > 0; + } + + +#endif + + + /// + class Mat2d + { + protected: + /// + double coeff[4]; + + public: + /// + Mat2d() { coeff[0] = coeff[1] = coeff[2] = coeff[3] = 0; } + /// + Mat2d(double a11, double a12, double a21, double a22) + { coeff[0] = a11; coeff[1] = a12; coeff[2] = a21; coeff[3] = a22; } + /// + Mat2d(const Mat2d & m2) + { for (int i = 0; i < 4; i++) coeff[i] = m2.Get(i); } + + /// + double & Elem (INDEX i, INDEX j) { return coeff[2*(i-1)+j-1]; } + /// + double & Elem (INDEX i) {return coeff[i]; } + /// + double Get (INDEX i, INDEX j) const { return coeff[2*(i-1)+j-1]; } + /// + double Get (INDEX i) const {return coeff[i]; } + + /// + double Det () const { return coeff[0] * coeff[3] - coeff[1] * coeff[2]; } + + /// + void Mult (const Vec2d & v, Vec2d & prod) const; + /// + void MultTrans (const Vec2d & v , Vec2d & prod) const; + /// + void Solve (const Vec2d & rhs, Vec2d & x) const; + /// Solves mat * x = rhs, but using a positive definite matrix instead of mat + void SolvePositiveDefinite (const Vec2d & rhs, Vec2d & x) const; + /// add a term \alpha * v * v^T + void AddDiadicProduct (double alpha, Vec2d & v); + }; + + + + inline void Mat2d :: Mult (const Vec2d & v, Vec2d & prod) const + { + prod.X() = coeff[0] * v.X() + coeff[1] * v.Y(); + prod.Y() = coeff[2] * v.X() + coeff[3] * v.Y(); + } + + + inline void Mat2d :: MultTrans (const Vec2d & v, Vec2d & prod) const + { + prod.X() = coeff[0] * v.X() + coeff[2] * v.Y(); + prod.Y() = coeff[1] * v.X() + coeff[3] * v.Y(); + } + + + + inline void Mat2d :: Solve (const Vec2d & rhs, Vec2d & x) const + { + double det = Det(); + + if (det == 0) + MyError ("Mat2d::Solve: zero determinant"); + else + { + x.X() = (coeff[3] * rhs.X() - coeff[1] * rhs.Y()) / det; + x.Y() = (-coeff[2] * rhs.X() + coeff[0] * rhs.Y()) / det; + } + } + + + inline void Mat2d :: SolvePositiveDefinite (const Vec2d & rhs, Vec2d & x) const + { + double a = max2(coeff[0], 1e-8); + double b = coeff[1] / a; + double c = coeff[2] / a; + double d = max2(coeff[3] - a *b * c, 1e-8); + + x.X() = (rhs.X() - b * rhs.Y()) / a; + x.Y() = rhs.Y() / d - c * x.X(); + } + + + inline void Mat2d :: AddDiadicProduct (double alpha, Vec2d & v) + { + coeff[0] += alpha * v.X() * v.X(); + coeff[1] += alpha * v.X() * v.Y(); + coeff[2] += alpha * v.Y() * v.X(); + coeff[3] += alpha * v.Y() * v.Y(); + } + +} + +#endif diff --git a/libsrc/gprim/geom3d.cpp b/libsrc/gprim/geom3d.cpp new file mode 100644 index 00000000..04ecd137 --- /dev/null +++ b/libsrc/gprim/geom3d.cpp @@ -0,0 +1,731 @@ +#include +#include + +#include +#include + +namespace netgen +{ +ostream & operator<<(ostream & s, const Point3d & p) + { + return s << "(" << p.x[0] << ", " << p.x[1] << ", " << p.x[2] << ")"; + } + +ostream & operator<<(ostream & s, const Vec3d & v) + { + return s << "(" << v.x[0] << ", " << v.x[1] << ", " << v.x[2] << ")"; + } + +double Angle (const Vec3d & v1, const Vec3d & v2) +{ + double co = (v1 * v2) / (v1.Length() * v2.Length()); + if (co > 1) co = 1; + if (co < -1) co = -1; + return acos ( co ); +} + + +void Vec3d :: GetNormal (Vec3d & n) const + { + if (fabs (X()) > fabs (Z())) + { + n.X() = -Y(); + n.Y() = X(); + n.Z() = 0; + } + else + { + n.X() = 0; + n.Y() = Z(); + n.Z() = -Y(); + } + double len = n.Length(); + if (len == 0) + { + n.X() = 1; + n.Y() = n.Z() = 0; + } + else + n /= len; + } + +/* +ostream & operator<<(ostream & s, const ROTDenseMatrix3D & r) + { + return s << "{ (" << r.txx << ", " << r.txy << ", " << r.txz << ") , (" + << r.tyx << ", " << r.tyy << ", " << r.tyz << ") , (" + << r.tzx << ", " << r.tzy << ", " << r.tzz << ") }"; + } +*/ + +/* +Vec3d operator- (const Point3d & p1, const Point3d & p2) + { + return Vec3d (p1.X() - p2.X(), p1.Y() - p2.Y(),p1.Z() - p2.Z()); + } + +Point3d operator- (const Point3d & p1, const Vec3d & v) + { + return Point3d (p1.X() - v.X(), p1.Y() - v.Y(),p1.Z() - v.Z()); + } + +Point3d operator+ (const Point3d & p1, const Vec3d & v) + { + return Point3d (p1.X() + v.X(), p1.Y() + v.Y(),p1.Z() + v.Z()); + } + +Vec3d operator- (const Vec3d & v1, const Vec3d & v2) + { + return Vec3d (v1.X() - v2.X(), v1.Y() - v2.Y(),v1.Z() - v2.Z()); + } + +Vec3d operator+ (const Vec3d & v1, const Vec3d & v2) + { + return Vec3d (v1.X() + v2.X(), v1.Y() + v2.Y(),v1.Z() + v2.Z()); + } + +Vec3d operator* (double scal, const Vec3d & v) + { + return Vec3d (scal * v.X(), scal * v.Y(), scal * v.Z()); + } +*/ +/* +double operator* (const Vec3d & v1, const Vec3d & v2) + { + return v1.X() * v2.X() + v1.Y() * v2.Y() + v1.Z() * v2.Z(); + } + +double Cross (const Vec3d & v1, const Vec3d & v2) + { + return v1.X() * v2.Y() - v1.Y() * v2.X(); + } +*/ + +/* +void ROTDenseMatrix3D :: CalcRotMat(double ag, double bg, double lg, double size2, Vec3d r) + { + size = size2; + txx=size * ( cos(bg) * cos(lg) ); + txy=size * ( cos(bg) * sin(lg) ); + txz=size * (-sin(bg) ); + + tyx=size * ( sin(ag) * sin(bg) * cos(lg) - cos(ag) * sin(lg) ); + tyy=size * ( sin(ag) * sin(bg) * sin(lg) + cos(ag) * cos(lg) ); + tyz=size * ( sin(ag) * cos(bg) ); + + tzx=size * ( cos(ag) * sin(bg) * cos(lg) + sin(ag) * sin(lg) ); + tzy=size * ( cos(ag) * sin(bg) * sin(lg) - sin(ag) * cos(lg) ); + tzz=size * ( cos(ag) * cos(bg) ); + + deltaR=r; + } +ROTDenseMatrix3D :: ROTDenseMatrix3D(double ag, double bg, double lg, double size2, Vec3d r) + {CalcRotMat(ag, bg, lg, size2, r); } + +ROTDenseMatrix3D :: ROTDenseMatrix3D(Vec3d rot2) + { + Vec3d r2(0,0,0); + CalcRotMat(rot2.X(), rot2.Y(), rot2.Z(), 1, r2); + } + +ROTDenseMatrix3D ROTDenseMatrix3D :: INV() + { + ROTDenseMatrix3D rinv(txx/sqr(size),tyx/sqr(size),tzx/sqr(size), + txy/sqr(size),tyy/sqr(size),tzy/sqr(size), + txz/sqr(size),tyz/sqr(size),tzz/sqr(size), + 1/size,deltaR); + return rinv; + } + +Vec3d operator* (const ROTDenseMatrix3D & r, const Vec3d & v) + { + return Vec3d (r.XX() * v.X() + r.XY() * v.Y() + r.XZ() * v.Z(), + r.YX() * v.X() + r.YY() * v.Y() + r.YZ() * v.Z(), + r.ZX() * v.X() + r.ZY() * v.Y() + r.ZZ() * v.Z() ); + } + +Point3d operator* (const ROTDenseMatrix3D & r, const Point3d & p) + { + return Point3d (r.XX() * p.X() + r.XY() * p.Y() + r.XZ() * p.Z(), + r.YX() * p.X() + r.YY() * p.Y() + r.YZ() * p.Z(), + r.ZX() * p.X() + r.ZY() * p.Y() + r.ZZ() * p.Z() ); + } +*/ + + + + + + + +Box3d :: Box3d ( double aminx, double amaxx, + double aminy, double amaxy, + double aminz, double amaxz ) +{ + minx[0] = aminx; maxx[0] = amaxx; + minx[1] = aminy; maxx[1] = amaxy; + minx[2] = aminz; maxx[2] = amaxz; +} + +Box3d :: Box3d ( const Box3d & b2 ) +{ + for (int i = 0; i < 3; i++) + { + minx[i] = b2.minx[i]; + maxx[i] = b2.maxx[i]; + } +} + +Box3d :: Box3d ( const Box<3> & b2 ) +{ + for (int i = 0; i < 3; i++) + { + minx[i] = b2.PMin()(i); + maxx[i] = b2.PMax()(i); + } +} + + +/* +int Box3d :: Intersect (const Box3d & box2) const +{ + int i; + for (i = 0; i <= 2; i++) + if (minx[i] > box2.maxx[i] || maxx[i] < box2.minx[i]) + return 0; + return 1; +} +*/ + +/* +void Box3d :: SetPoint (const Point3d & p) +{ + minx[0] = maxx[0] = p.X(); + minx[1] = maxx[1] = p.Y(); + minx[2] = maxx[2] = p.Z(); +} + +void Box3d :: AddPoint (const Point3d & p) +{ + if (p.X() < minx[0]) minx[0] = p.X(); + if (p.X() > maxx[0]) maxx[0] = p.X(); + if (p.Y() < minx[1]) minx[1] = p.Y(); + if (p.Y() > maxx[1]) maxx[1] = p.Y(); + if (p.Z() < minx[2]) minx[2] = p.Z(); + if (p.Z() > maxx[2]) maxx[2] = p.Z(); +} +*/ + +void Box3d :: GetPointNr (int i, Point3d & point) const +{ + i--; + point.X() = (i & 1) ? maxx[0] : minx[0]; + point.Y() = (i & 2) ? maxx[1] : minx[1]; + point.Z() = (i & 4) ? maxx[2] : minx[2]; +} + + +void Box3d :: Increase (double d) +{ + for (int i = 0; i <= 2; i++) + { + minx[i] -= d; + maxx[i] += d; + } +} + +void Box3d :: IncreaseRel (double /* rel */) +{ + for (int i = 0; i <= 2; i++) + { + double d = 0.5 * (maxx[i] - minx[i]); + minx[i] -= d; + maxx[i] += d; + } +} + + +Box3d :: Box3d (const Point3d& p1, const Point3d& p2) +{ + minx[0] = min2 (p1.X(), p2.X()); + minx[1] = min2 (p1.Y(), p2.Y()); + minx[2] = min2 (p1.Z(), p2.Z()); + maxx[0] = max2 (p1.X(), p2.X()); + maxx[1] = max2 (p1.Y(), p2.Y()); + maxx[2] = max2 (p1.Z(), p2.Z()); +} + +const Box3d& Box3d :: operator+=(const Box3d& b) +{ + minx[0] = min2 (minx[0], b.minx[0]); + minx[1] = min2 (minx[1], b.minx[1]); + minx[2] = min2 (minx[2], b.minx[2]); + maxx[0] = max2 (maxx[0], b.maxx[0]); + maxx[1] = max2 (maxx[1], b.maxx[1]); + maxx[2] = max2 (maxx[2], b.maxx[2]); + + return *this; +} + +Point3d Box3d :: MaxCoords() const +{ + return Point3d(maxx[0], maxx[1], maxx[2]); +} + +Point3d Box3d :: MinCoords() const +{ + return Point3d(minx[0], minx[1], minx[2]); +} + +/* +void Box3d :: CreateNegMinMaxBox() +{ + minx[0] = MAXDOUBLE; + minx[1] = MAXDOUBLE; + minx[2] = MAXDOUBLE; + maxx[0] = MINDOUBLE; + maxx[1] = MINDOUBLE; + maxx[2] = MINDOUBLE; + +} +*/ + +void Box3d :: WriteData(ofstream& fout) const +{ + for(int i = 0; i < 3; i++) + { + fout << minx[i] << " " << maxx[i] << " "; + } + fout << "\n"; +} + +void Box3d :: ReadData(ifstream& fin) +{ + for(int i = 0; i < 3; i++) + { + fin >> minx[i]; + fin >> maxx[i]; + } +} + + + + +Box3dSphere :: Box3dSphere ( double aminx, double amaxx, + double aminy, double amaxy, + double aminz, double amaxz ) + : Box3d (aminx, amaxx, aminy, amaxy, aminz, amaxz) +{ + CalcDiamCenter (); +} + + +void Box3dSphere :: CalcDiamCenter () +{ + diam = sqrt( sqr (maxx[0] - minx[0]) + + sqr (maxx[1] - minx[1]) + + sqr (maxx[2] - minx[2])); + + c.X() = 0.5 * (minx[0] + maxx[0]); + c.Y() = 0.5 * (minx[1] + maxx[1]); + c.Z() = 0.5 * (minx[2] + maxx[2]); + + inner = min2 ( min2 (maxx[0] - minx[0], maxx[1] - minx[1]), maxx[2] - minx[2]) / 2; +} + + +void Box3dSphere :: GetSubBox (int i, Box3dSphere & sbox) const +{ + i--; + if (i & 1) + { + sbox.minx[0] = c.X(); + sbox.maxx[0] = maxx[0]; + } + else + { + sbox.minx[0] = minx[0]; + sbox.maxx[0] = c.X(); + } + if (i & 2) + { + sbox.minx[1] = c.Y(); + sbox.maxx[1] = maxx[1]; + } + else + { + sbox.minx[1] = minx[1]; + sbox.maxx[1] = c.Y(); + } + if (i & 4) + { + sbox.minx[2] = c.Z(); + sbox.maxx[2] = maxx[2]; + } + else + { + sbox.minx[2] = minx[2]; + sbox.maxx[2] = c.Z(); + } + + // sbox.CalcDiamCenter (); + + sbox.c.X() = 0.5 * (sbox.minx[0] + sbox.maxx[0]); + sbox.c.Y() = 0.5 * (sbox.minx[1] + sbox.maxx[1]); + sbox.c.Z() = 0.5 * (sbox.minx[2] + sbox.maxx[2]); + sbox.diam = 0.5 * diam; + sbox.inner = 0.5 * inner; +} + + + + +/* +double Determinant (const Vec3d & col1, + const Vec3d & col2, + const Vec3d & col3) +{ + return + col1.x[0] * ( col2.x[1] * col3.x[2] - col2.x[2] * col3.x[1]) + + col1.x[1] * ( col2.x[2] * col3.x[0] - col2.x[0] * col3.x[2]) + + col1.x[2] * ( col2.x[0] * col3.x[1] - col2.x[1] * col3.x[0]); +} +*/ + +void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3) +{ + Swap (v1.Y(), v2.X()); + Swap (v1.Z(), v3.X()); + Swap (v2.Z(), v3.Y()); +} + + +int SolveLinearSystem (const Vec3d & col1, const Vec3d & col2, + const Vec3d & col3, const Vec3d & rhs, + Vec3d & sol) +{ + // changed by MW + double matrix[3][3]; + double locrhs[3]; + int retval = 0; + + for(int i=0; i<3; i++) + { + matrix[i][0] = col1.X(i+1); + matrix[i][1] = col2.X(i+1); + matrix[i][2] = col3.X(i+1); + locrhs[i] = rhs.X(i+1); + } + + for(int i=0; i<2; i++) + { + int pivot = i; + double maxv = fabs(matrix[i][i]); + for(int j=i+1; j<3; j++) + if(fabs(matrix[j][i]) > maxv) + { + maxv = fabs(matrix[j][i]); + pivot = j; + } + + if(fabs(maxv) > 1e-40) + { + if(pivot != i) + { + swap(matrix[i][0],matrix[pivot][0]); + swap(matrix[i][1],matrix[pivot][1]); + swap(matrix[i][2],matrix[pivot][2]); + swap(locrhs[i],locrhs[pivot]); + } + for(int j=i+1; j<3; j++) + { + double fac = matrix[j][i] / matrix[i][i]; + + for(int k=i+1; k<3; k++) + matrix[j][k] -= fac*matrix[i][k]; + locrhs[j] -= fac*locrhs[i]; + } + } + else + retval = 1; + } + + if(fabs(matrix[2][2]) < 1e-40) + retval = 1; + + if(retval != 0) + return retval; + + + for(int i=2; i>=0; i--) + { + double sum = locrhs[i]; + for(int j=2; j>i; j--) + sum -= matrix[i][j]*sol.X(j+1); + + sol.X(i+1) = sum/matrix[i][i]; + } + + return 0; + + + + + + /* + double det = Determinant (col1, col2, col3); + if (fabs (det) < 1e-40) + return 1; + + sol.X() = Determinant (rhs, col2, col3) / det; + sol.Y() = Determinant (col1, rhs, col3) / det; + sol.Z() = Determinant (col1, col2, rhs) / det; + + return 0; + */ + /* + Vec3d cr; + Cross (col1, col2, cr); + double det = cr * col3; + + if (fabs (det) < 1e-40) + return 1; + + if (fabs(cr.Z()) > 1e-12) + { + // solve for 3. component + sol.Z() = (cr * rhs) / det; + + // 2x2 system for 1. and 2. component + double res1 = rhs.X() - sol.Z() * col3.X(); + double res2 = rhs.Y() - sol.Z() * col3.Y(); + + sol.X() = (col2.Y() * res1 - col2.X() * res2) / cr.Z(); + sol.Y() = (col1.X() * res2 - col1.Y() * res1) / cr.Z(); + + } + else + { + det = Determinant (col1, col2, col3); + if (fabs (det) < 1e-40) + return 1; + + sol.X() = Determinant (rhs, col2, col3) / det; + sol.Y() = Determinant (col1, rhs, col3) / det; + sol.Z() = Determinant (col1, col2, rhs) / det; + } + + return 0; + */ +} + + +int SolveLinearSystemLS (const Vec3d & col1, + const Vec3d & col2, + const Vec2d & rhs, + Vec3d & sol) +{ + double a11 = col1 * col1; + double a12 = col1 * col2; + double a22 = col2 * col2; + + double det = a11 * a22 - a12 * a12; + + if (det*det <= 1e-24 * a11 * a22) + { + sol = Vec3d (0, 0, 0); + return 1; + } + + Vec2d invrhs; + invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det; + invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det; + + sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X(); + sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y(); + sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z(); + + return 0; + + /* + Vec3d inv1, inv2; + int err = + PseudoInverse (col1, col2, inv1, inv2); + + sol = rhs.X() * inv1 + rhs.Y() * inv2; + return err; + */ +} + +int SolveLinearSystemLS2 (const Vec3d & col1, + const Vec3d & col2, + const Vec2d & rhs, + Vec3d & sol, double & x, double & y) +{ + double a11 = col1 * col1; + double a12 = col1 * col2; + double a22 = col2 * col2; + + double det = a11 * a22 - a12 * a12; + + if (fabs (det) <= 1e-12 * col1.Length() * col2.Length() || + col1.Length2() == 0 || col2.Length2() == 0) + { + sol = Vec3d (0, 0, 0); + x = 0; y = 0; + return 1; + } + + Vec2d invrhs; + invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det; + invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det; + + sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X(); + sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y(); + sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z(); + + x = invrhs.X(); + y = invrhs.Y(); + + return 0; + + /* + Vec3d inv1, inv2; + int err = + PseudoInverse (col1, col2, inv1, inv2); + + sol = rhs.X() * inv1 + rhs.Y() * inv2; + return err; + */ +} + +int PseudoInverse (const Vec3d & col1, + const Vec3d & col2, + Vec3d & inv1, + Vec3d & inv2) +{ + double a11 = col1 * col1; + double a12 = col1 * col2; + double a22 = col2 * col2; + + double det = a11 * a22 - a12 * a12; + + if (fabs (det) < 1e-12 * col1.Length() * col2.Length()) + { + inv1 = Vec3d (0, 0, 0); + inv2 = Vec3d (0, 0, 0); + return 1; + } + + double ia11 = a22 / det; + double ia12 = -a12 / det; + double ia22 = a11 / det; + + inv1 = ia11 * col1 + ia12 * col2; + inv2 = ia12 * col1 + ia22 * col2; + + return 0; +} + + + + +QuadraticFunction3d :: +QuadraticFunction3d (const Point3d & p, const Vec3d & v) +{ + Vec3d hv(v); + hv /= (hv.Length() + 1e-12); + Vec3d t1, t2; + hv.GetNormal (t1); + Cross (hv, t1, t2); + + double t1p = t1.X() * p.X() + t1.Y() * p.Y() + t1.Z() * p.Z(); + double t2p = t2.X() * p.X() + t2.Y() * p.Y() + t2.Z() * p.Z(); + c0 = sqr (t1p) + sqr (t2p); + cx = -2 * (t1p * t1.X() + t2p * t2.X()); + cy = -2 * (t1p * t1.Y() + t2p * t2.Y()); + cz = -2 * (t1p * t1.Z() + t2p * t2.Z()); + + cxx = t1.X() * t1.X() + t2.X() * t2.X(); + cyy = t1.Y() * t1.Y() + t2.Y() * t2.Y(); + czz = t1.Z() * t1.Z() + t2.Z() * t2.Z(); + + cxy = 2 * t1.X() * t1.Y() + 2 * t2.X() * t2.Y(); + cxz = 2 * t1.X() * t1.Z() + 2 * t2.X() * t2.Z(); + cyz = 2 * t1.Y() * t1.Z() + 2 * t2.Y() * t2.Z(); + + /* + (*testout) << "c0 = " << c0 + << " clin = " << cx << " " << cy << " " << cz + << " cq = " << cxx << " " << cyy << " " << czz + << cxy << " " << cyz << " " << cyz << endl; + */ +} + +// QuadraticFunction3d gqf (Point3d (0,0,0), Vec3d (1, 0, 0)); + + + + + +void referencetransform :: Set (const Point3d & p1, const Point3d & p2, + const Point3d & p3, double ah) +{ + ex = p2 - p1; + ex /= ex.Length(); + ey = p3 - p1; + ey -= (ex * ey) * ex; + ey /= ey.Length(); + ez = Cross (ex, ey); + rp = p1; + h = ah; + + exh = ah * ex; + eyh = ah * ey; + ezh = ah * ez; + ah = 1 / ah; + ex_h = ah * ex; + ey_h = ah * ey; + ez_h = ah * ez; +} + +void referencetransform :: ToPlain (const Point3d & p, Point3d & pp) const +{ + Vec3d v; + v = p - rp; + pp.X() = (ex_h * v); + pp.Y() = (ey_h * v); + pp.Z() = (ez_h * v); +} + +void referencetransform :: ToPlain (const Array & p, + Array & pp) const +{ + Vec3d v; + int i; + + pp.SetSize (p.Size()); + for (i = 1; i <= p.Size(); i++) + { + v = p.Get(i) - rp; + pp.Elem(i).X() = (ex_h * v); + pp.Elem(i).Y() = (ey_h * v); + pp.Elem(i).Z() = (ez_h * v); + } +} + +void referencetransform :: FromPlain (const Point3d & pp, Point3d & p) const +{ + Vec3d v; + // v = (h * pp.X()) * ex + (h * pp.Y()) * ey + (h * pp.Z()) * ez; + // p = rp + v; + v.X() = pp.X() * exh.X() + pp.Y() * eyh.X() + pp.Z() * ezh.X(); + v.Y() = pp.X() * exh.Y() + pp.Y() * eyh.Y() + pp.Z() * ezh.Y(); + v.Z() = pp.X() * exh.Z() + pp.Y() * eyh.Z() + pp.Z() * ezh.Z(); + p.X() = rp.X() + v.X(); + p.Y() = rp.Y() + v.Y(); + p.Z() = rp.Z() + v.Z(); +} + + +} diff --git a/libsrc/gprim/geom3d.hpp b/libsrc/gprim/geom3d.hpp new file mode 100644 index 00000000..05216d8f --- /dev/null +++ b/libsrc/gprim/geom3d.hpp @@ -0,0 +1,746 @@ +#ifndef FILE_GEOM3D +#define FILE_GEOM3D + +/* *************************************************************************/ +/* File: geom3d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 5. Aug. 95 */ +/* *************************************************************************/ + +namespace netgen +{ + + + extern DLL_HEADER void MyError (const char * ch); + + class Point3d; + class Vec3d; + + inline Vec3d operator- (const Point3d & p1, const Point3d & p2); + inline Point3d operator- (const Point3d & p1, const Vec3d & v); + inline Point3d operator+ (const Point3d & p1, const Vec3d & v); + Point3d & Add (double d, const Vec3d & v); + Point3d & Add2 (double d, const Vec3d & v, + double d2, const Vec3d & v2); + inline Point3d Center (const Point3d & p1, const Point3d & p2); + inline Point3d Center (const Point3d & p1, const Point3d & p2, const Point3d & p3); + inline Point3d Center (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4); + ostream & operator<<(ostream & s, const Point3d & p); + inline Vec3d operator- (const Vec3d & p1, const Vec3d & v); + inline Vec3d operator+ (const Vec3d & p1, const Vec3d & v); + inline Vec3d operator* (double scal, const Vec3d & v); + inline double operator* (const Vec3d & v1, const Vec3d & v2); + inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2); + inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod); + double Angle (const Vec3d & v); + double FastAngle (const Vec3d & v); + double Angle (const Vec3d & v1, const Vec3d & v2); + double FastAngle (const Vec3d & v1, const Vec3d & v2); + ostream & operator<<(ostream & s, const Vec3d & v); + void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3); + int SolveLinearSystem (const Vec3d & col1, + const Vec3d & col2, + const Vec3d & col3, + const Vec3d & rhs, + Vec3d & sol); + int SolveLinearSystemLS (const Vec3d & col1, + const Vec3d & col2, + const Vec2d & rhs, + Vec3d & sol); + int SolveLinearSystemLS2 (const Vec3d & col1, + const Vec3d & col2, + const Vec2d & rhs, + Vec3d & sol, + double & x, double & y); + int PseudoInverse (const Vec3d & col1, + const Vec3d & col2, + Vec3d & inv1, + Vec3d & inv2); + double Determinant (const Vec3d & col1, + const Vec3d & col2, + const Vec3d & col3); + + inline double Dist2 (const Point3d & p1, const Point3d & p2); + + /// Point in R3 + class Point3d + { + protected: + /// + double x[3]; + + public: + /// + Point3d () { x[0] = x[1] = x[2] = 0; } + /// + Point3d(double ax, double ay, double az) + { x[0] = ax; x[1] = ay; x[2] = az; } + /// + Point3d(double ax[3]) + { x[0] = ax[0]; x[1] = ax[1]; x[2] = ax[2]; } + + /// + Point3d(const Point3d & p2) + { x[0] = p2.x[0]; x[1] = p2.x[1]; x[2] = p2.x[2]; } + + Point3d (const Point<3> & p2) + { + for (int i = 0; i < 3; i++) + x[i] = p2(i); + } + + /// + Point3d & operator= (const Point3d & p2) + { x[0] = p2.x[0]; x[1] = p2.x[1]; x[2] = p2.x[2]; return *this; } + + /// + int operator== (const Point3d& p) const + { return (x[0] == p.x[0] && x[1] == p.x[1] && x[2] == p.x[2]); } + + /// + double & X() { return x[0]; } + /// + double & Y() { return x[1]; } + /// + double & Z() { return x[2]; } + /// + double X() const { return x[0]; } + /// + double Y() const { return x[1]; } + /// + double Z() const { return x[2]; } + /// + double & X(int i) { return x[i-1]; } + /// + double X(int i) const { return x[i-1]; } + /// + const Point3d & SetToMin (const Point3d & p2) + { + if (p2.x[0] < x[0]) x[0] = p2.x[0]; + if (p2.x[1] < x[1]) x[1] = p2.x[1]; + if (p2.x[2] < x[2]) x[2] = p2.x[2]; + return *this; + } + + /// + const Point3d & SetToMax (const Point3d & p2) + { + if (p2.x[0] > x[0]) x[0] = p2.x[0]; + if (p2.x[1] > x[1]) x[1] = p2.x[1]; + if (p2.x[2] > x[2]) x[2] = p2.x[2]; + return *this; + } + + /// + friend inline Vec3d operator- (const Point3d & p1, const Point3d & p2); + /// + friend inline Point3d operator- (const Point3d & p1, const Vec3d & v); + /// + friend inline Point3d operator+ (const Point3d & p1, const Vec3d & v); + /// + inline Point3d & operator+= (const Vec3d & v); + inline Point3d & operator-= (const Vec3d & v); + /// + inline Point3d & Add (double d, const Vec3d & v); + /// + inline Point3d & Add2 (double d, const Vec3d & v, + double d2, const Vec3d & v2); + /// + friend inline double Dist (const Point3d & p1, const Point3d & p2) + { return sqrt ( (p1.x[0]-p2.x[0]) * (p1.x[0]-p2.x[0]) + + (p1.x[1]-p2.x[1]) * (p1.x[1]-p2.x[1]) + + (p1.x[2]-p2.x[2]) * (p1.x[2]-p2.x[2])); } + /// + inline friend double Dist2 (const Point3d & p1, const Point3d & p2) + { return ( (p1.x[0]-p2.x[0]) * (p1.x[0]-p2.x[0]) + + (p1.x[1]-p2.x[1]) * (p1.x[1]-p2.x[1]) + + (p1.x[2]-p2.x[2]) * (p1.x[2]-p2.x[2])); } + + /// + friend inline Point3d Center (const Point3d & p1, const Point3d & p2); + /// + friend inline Point3d Center (const Point3d & p1, const Point3d & p2, const Point3d & p3); + /// + friend inline Point3d Center (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4); + /// + friend ostream & operator<<(ostream & s, const Point3d & p); + + /// + friend class Vec3d; + /// + friend class Box3d; + + + operator Point<3> () const + { + return Point<3> (x[0], x[1], x[2]); + } + }; + + + /// + class Vec3d + { + protected: + /// + double x[3]; + + public: + /// + inline Vec3d() { x[0] = x[1] = x[2] = 0; } + /// + inline Vec3d(double ax, double ay, double az) + { x[0] = ax; x[1] = ay; x[2] = az; } + /// + Vec3d(double ax[3]) + { x[0] = ax[0]; x[1] = ax[1]; x[2] = ax[2]; } + /// + inline Vec3d(const Vec3d & v2) + { x[0] = v2.x[0]; x[1] = v2.x[1]; x[2] = v2.x[2]; } + /// + inline Vec3d(const Point3d & p1, const Point3d & p2) + { + x[0] = p2.x[0] - p1.x[0]; + x[1] = p2.x[1] - p1.x[1]; + x[2] = p2.x[2] - p1.x[2]; + } + /// + inline Vec3d(const Point3d & p1) + { + x[0] = p1.x[0]; + x[1] = p1.x[1]; + x[2] = p1.x[2]; + } + + Vec3d (const Vec<3> & v2) + { + for (int i = 0; i < 3; i++) + x[i] = v2(i); + } + + operator Vec<3> () const + { + return Vec<3> (x[0], x[1], x[2]); + } + + + Vec3d & operator= (const Vec3d & v2) + { x[0] = v2.x[0]; x[1] = v2.x[1]; x[2] = v2.x[2]; return *this; } + /// + Vec3d & operator= (double val) + { x[0] = x[1] = x[2] = val; return *this; } + /// + double & X() { return x[0]; } + /// + double & Y() { return x[1]; } + /// + double & Z() { return x[2]; } + /// + double & X(int i) { return x[i-1]; } + + /// + double X() const { return x[0]; } + /// + double Y() const { return x[1]; } + /// + double Z() const { return x[2]; } + /// + double X(int i) const { return x[i-1]; } + + /// + double Length() const + { return sqrt (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); } + /// + double Length2() const + { return x[0] * x[0] + x[1] * x[1] + x[2] * x[2]; } + + /// + inline friend double Dist (const Vec3d & v1, const Vec3d & v2) + { return sqrt ( (v1.x[0]-v2.x[0]) * (v1.x[0]-v2.x[0]) + + (v1.x[1]-v2.x[1]) * (v1.x[1]-v2.x[1]) + + (v1.x[2]-v2.x[2]) * (v1.x[2]-v2.x[2])); } + /// + inline friend double Dist2 (const Vec3d & v1, const Vec3d & v2) + { return ( (v1.x[0]-v2.x[0]) * (v1.x[0]-v2.x[0]) + + (v1.x[1]-v2.x[1]) * (v1.x[1]-v2.x[1]) + + (v1.x[2]-v2.x[2]) * (v1.x[2]-v2.x[2])); } + + /// + Vec3d & operator+= (const Vec3d & v2); + /// + Vec3d & operator-= (const Vec3d & v2); + /// + Vec3d & operator*= (double s); + /// + Vec3d & operator/= (double s); + /// + inline Vec3d & Add (double d, const Vec3d & v); + /// + inline Vec3d & Add2 (double d, const Vec3d & v, + double d2, const Vec3d & v2); + + /// + friend inline Vec3d operator- (const Point3d & p1, const Point3d & p2); + /// + friend inline Point3d operator- (const Point3d & p1, const Vec3d & v); + /// + friend inline Point3d operator+ (const Point3d & p1, const Vec3d & v); + /// + friend inline Vec3d operator- (const Vec3d & p1, const Vec3d & v); + /// + friend inline Vec3d operator+ (const Vec3d & p1, const Vec3d & v); + /// + friend inline Vec3d operator* (double scal, const Vec3d & v); + + /// + friend inline double operator* (const Vec3d & v1, const Vec3d & v2); + /// + friend inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2); + /// + friend inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod); + + /// Returns one normal-vector to n + void GetNormal (Vec3d & n) const; + /// + friend double Angle (const Vec3d & v); + /// + friend double FastAngle (const Vec3d & v); + /// + friend double Angle (const Vec3d & v1, const Vec3d & v2); + /// + friend double FastAngle (const Vec3d & v1, const Vec3d & v2); + + void Normalize() + { + double len = (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); + if (len == 0) return; + len = sqrt (len); + x[0] /= len; x[1] /= len; x[2] /= len; + } + + /// + friend ostream & operator<<(ostream & s, const Vec3d & v); + + /// + friend class Point3d; + friend void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3); + friend int SolveLinearSystem (const Vec3d & col1, + const Vec3d & col2, + const Vec3d & col3, + const Vec3d & rhs, + Vec3d & sol); + friend int SolveLinearSystemLS (const Vec3d & col1, + const Vec3d & col2, + const Vec2d & rhs, + Vec3d & sol); + friend int SolveLinearSystemLS2 (const Vec3d & col1, + const Vec3d & col2, + const Vec2d & rhs, + Vec3d & sol, + double & x, double & y); + friend int PseudoInverse (const Vec3d & col1, + const Vec3d & col2, + Vec3d & inv1, + Vec3d & inv2); + friend double Determinant (const Vec3d & col1, + const Vec3d & col2, + const Vec3d & col3); + }; + + + + class QuadraticFunction3d + { + double c0, cx, cy, cz; + double cxx, cyy, czz, cxy, cxz, cyz; + + public: + QuadraticFunction3d (const Point3d & p, const Vec3d & v); + double Eval (const Point3d & p) + { + return + c0 + + p.X() * (cx + cxx * p.X() + cxy * p.Y() + cxz * p.Z()) + + p.Y() * (cy + cyy * p.Y() + cyz * p.Z()) + + p.Z() * (cz + czz * p.Z()); + } + }; + + + + inline Point3d Center (const Point3d & p1, const Point3d & p2) + { + return Point3d (0.5 * (p1.x[0] + p2.x[0]), + 0.5 * (p1.x[1] + p2.x[1]), + 0.5 * (p1.x[2] + p2.x[2])); + } + + + inline Point3d Center (const Point3d & p1, const Point3d & p2, + const Point3d & p3) + { + return Point3d (1.0/3.0 * (p1.x[0] + p2.x[0] + p3.x[0]), + 1.0/3.0 * (p1.x[1] + p2.x[1] + p3.x[1]), + 1.0/3.0 * (p1.x[2] + p2.x[2] + p3.x[2])); + } + + inline Point3d Center (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4) + { + return Point3d (0.25 * (p1.x[0] + p2.x[0] + p3.x[0] + p4.x[0]), + 0.25 * (p1.x[1] + p2.x[1] + p3.x[1] + p4.x[1]), + 0.25 * (p1.x[2] + p2.x[2] + p3.x[2] + p4.x[2])); + } + + + + inline Vec3d & Vec3d :: operator+= (const Vec3d & v2) + { + x[0] += v2.x[0]; + x[1] += v2.x[1]; + x[2] += v2.x[2]; + return *this; + } + + inline Vec3d & Vec3d :: operator-= (const Vec3d & v2) + { + x[0] -= v2.x[0]; + x[1] -= v2.x[1]; + x[2] -= v2.x[2]; + return *this; + } + + + inline Vec3d & Vec3d :: operator*= (double s) + { + x[0] *= s; + x[1] *= s; + x[2] *= s; + return *this; + } + + + inline Vec3d & Vec3d :: operator/= (double s) + { + if (s != 0) + { + x[0] /= s; + x[1] /= s; + x[2] /= s; + } +#ifdef DEBUG + else + { + cerr << "Vec div by 0, v = " << (*this) << endl; + // MyError ("Vec3d::operator /=: Divisioin by zero"); + } +#endif + return *this; + } + + inline Vec3d & Vec3d::Add (double d, const Vec3d & v) + { + x[0] += d * v.x[0]; + x[1] += d * v.x[1]; + x[2] += d * v.x[2]; + return *this; + } + + inline Vec3d & Vec3d::Add2 (double d, const Vec3d & v, + double d2, const Vec3d & v2) + { + x[0] += d * v.x[0] + d2 * v2.x[0]; + x[1] += d * v.x[1] + d2 * v2.x[1]; + x[2] += d * v.x[2] + d2 * v2.x[2]; + return *this; + } + + + + + + + + + inline Vec3d operator- (const Point3d & p1, const Point3d & p2) + { + return Vec3d (p1.x[0] - p2.x[0], p1.x[1] - p2.x[1],p1.x[2] - p2.x[2]); + } + + + inline Point3d operator- (const Point3d & p1, const Vec3d & v) + { + return Point3d (p1.x[0] - v.x[0], p1.x[1] - v.x[1],p1.x[2] - v.x[2]); + } + + + inline Point3d operator+ (const Point3d & p1, const Vec3d & v) + { + return Point3d (p1.x[0] + v.x[0], p1.x[1] + v.x[1],p1.x[2] + v.x[2]); + } + + inline Point3d & Point3d::operator+= (const Vec3d & v) + { + x[0] += v.x[0]; + x[1] += v.x[1]; + x[2] += v.x[2]; + return *this; + } + + inline Point3d & Point3d::operator-= (const Vec3d & v) + { + x[0] -= v.x[0]; + x[1] -= v.x[1]; + x[2] -= v.x[2]; + return *this; + } + + inline Point3d & Point3d::Add (double d, const Vec3d & v) + { + x[0] += d * v.x[0]; + x[1] += d * v.x[1]; + x[2] += d * v.x[2]; + return *this; + } + + inline Point3d & Point3d::Add2 (double d, const Vec3d & v, + double d2, const Vec3d & v2) + { + x[0] += d * v.x[0] + d2 * v2.x[0]; + x[1] += d * v.x[1] + d2 * v2.x[1]; + x[2] += d * v.x[2] + d2 * v2.x[2]; + return *this; + } + + + inline Vec3d operator- (const Vec3d & v1, const Vec3d & v2) + { + return Vec3d (v1.x[0] - v2.x[0], v1.x[1] - v2.x[1],v1.x[2] - v2.x[2]); + } + + + inline Vec3d operator+ (const Vec3d & v1, const Vec3d & v2) + { + return Vec3d (v1.x[0] + v2.x[0], v1.x[1] + v2.x[1],v1.x[2] + v2.x[2]); + } + + + inline Vec3d operator* (double scal, const Vec3d & v) + { + return Vec3d (scal * v.x[0], scal * v.x[1], scal * v.x[2]); + } + + + + inline double operator* (const Vec3d & v1, const Vec3d & v2) + { + return v1.x[0] * v2.x[0] + v1.x[1] * v2.x[1] + v1.x[2] * v2.x[2]; + } + + + + inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2) + { + return Vec3d + ( v1.x[1] * v2.x[2] - v1.x[2] * v2.x[1], + v1.x[2] * v2.x[0] - v1.x[0] * v2.x[2], + v1.x[0] * v2.x[1] - v1.x[1] * v2.x[0]); + } + + inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod) + { + prod.x[0] = v1.x[1] * v2.x[2] - v1.x[2] * v2.x[1]; + prod.x[1] = v1.x[2] * v2.x[0] - v1.x[0] * v2.x[2]; + prod.x[2] = v1.x[0] * v2.x[1] - v1.x[1] * v2.x[0]; + } + + inline double Determinant (const Vec3d & col1, + const Vec3d & col2, + const Vec3d & col3) + { + return + col1.x[0] * ( col2.x[1] * col3.x[2] - col2.x[2] * col3.x[1]) + + col1.x[1] * ( col2.x[2] * col3.x[0] - col2.x[0] * col3.x[2]) + + col1.x[2] * ( col2.x[0] * col3.x[1] - col2.x[1] * col3.x[0]); + } + + + /// + class Box3d + { + protected: + /// + double minx[3], maxx[3]; + + public: + /// + Box3d () { }; + /// + Box3d ( double aminx, double amaxx, + double aminy, double amaxy, + double aminz, double amaxz ); + /// + Box3d ( const Box3d & b2 ); + /// + Box3d (const Point3d& p1, const Point3d& p2); + /// + Box3d (const Box<3> & b2); + /// + double MinX () const { return minx[0]; } + /// + double MaxX () const { return maxx[0]; } + /// + double MinY () const { return minx[1]; } + /// + double MaxY () const { return maxx[1]; } + /// + double MinZ () const { return minx[2]; } + /// + double MaxZ () const { return maxx[2]; } + + /// + double Mini (int i) const { return minx[i-1]; } + /// + double Maxi (int i) const { return maxx[i-1]; } + + /// + Point3d PMin () const { return Point3d(minx[0], minx[1], minx[2]); } + /// + Point3d PMax () const { return Point3d(maxx[0], maxx[1], maxx[2]); } + + /// + void GetPointNr (int i, Point3d & point) const; + /// increase Box at each side with dist + void Increase (double dist); + /// increase Box by factor rel + void IncreaseRel (double rel); + /// return 1 if closures are intersecting + int Intersect (const Box3d & box2) const + { + if (minx[0] > box2.maxx[0] || maxx[0] < box2.minx[0] || + minx[1] > box2.maxx[1] || maxx[1] < box2.minx[1] || + minx[2] > box2.maxx[2] || maxx[2] < box2.minx[2]) + return 0; + return 1; + } + /// return 1 if point p in closure + int IsIn (const Point3d & p) const + { + if (minx[0] <= p.x[0] && maxx[0] >= p.x[0] && + minx[1] <= p.x[1] && maxx[1] >= p.x[1] && + minx[2] <= p.x[2] && maxx[2] >= p.x[2]) + return 1; + return 0; + } + /// + inline void SetPoint (const Point3d & p) + { + minx[0] = maxx[0] = p.X(); + minx[1] = maxx[1] = p.Y(); + minx[2] = maxx[2] = p.Z(); + } + + /// + inline void AddPoint (const Point3d & p) + { + if (p.x[0] < minx[0]) minx[0] = p.x[0]; + if (p.x[0] > maxx[0]) maxx[0] = p.x[0]; + if (p.x[1] < minx[1]) minx[1] = p.x[1]; + if (p.x[1] > maxx[1]) maxx[1] = p.x[1]; + if (p.x[2] < minx[2]) minx[2] = p.x[2]; + if (p.x[2] > maxx[2]) maxx[2] = p.x[2]; + } + + /// + const Box3d& operator+=(const Box3d& b); + + /// + Point3d MaxCoords() const; + /// + Point3d MinCoords() const; + + /// Make a negative sized box; + // void CreateNegMinMaxBox(); + + /// + Point3d CalcCenter () const { return Point3d(0.5*(minx[0] + maxx[0]), + 0.5*(minx[1] + maxx[1]), + 0.5*(minx[2] + maxx[2])); } + /// + double CalcDiam () const { return sqrt(sqr(maxx[0]-minx[0])+ + sqr(maxx[1]-minx[1])+ + sqr(maxx[2]-minx[2])); } + + /// + void WriteData(ofstream& fout) const; + /// + void ReadData(ifstream& fin); + }; + + + class Box3dSphere : public Box3d + { + protected: + /// + double diam, inner; + /// + Point3d c; + public: + /// + Box3dSphere () { }; + /// + Box3dSphere ( double aminx, double amaxx, + double aminy, double amaxy, + double aminz, double amaxz); + /// + const Point3d & Center () const { return c; } + + /// + double Diam () const { return diam; } + /// + double Inner () const { return inner; } + /// + void GetSubBox (int i, Box3dSphere & sbox) const; + + // private: + /// + void CalcDiamCenter (); + }; + + + + + /// + class referencetransform + { + /// + Vec3d ex, ey, ez; + /// + Vec3d exh, eyh, ezh; + /// + Vec3d ex_h, ey_h, ez_h; + /// + Point3d rp; + /// + double h; + + public: + + /// + void Set (const Point3d & p1, const Point3d & p2, + const Point3d & p3, double ah); + + /// + void ToPlain (const Point3d & p, Point3d & pp) const; + /// + void ToPlain (const Array & p, Array & pp) const; + /// + void FromPlain (const Point3d & pp, Point3d & p) const; + }; + +} + + +#endif diff --git a/libsrc/gprim/geomfuncs.cpp b/libsrc/gprim/geomfuncs.cpp new file mode 100644 index 00000000..b2ac8382 --- /dev/null +++ b/libsrc/gprim/geomfuncs.cpp @@ -0,0 +1,111 @@ +#include + +#include +#include + +namespace netgen +{ + + /* + // template <> +inline void CalcInverse (const Mat<2,2> & m, Mat<2,2> & inv) +{ + double det = m(0,0) * m(1,1) - m(0,1) * m(1,0); + if (det == 0) + { + inv = 0; + return; + } + + double idet = 1.0 / det; + inv(0,0) = idet * m(1,1); + inv(0,1) = -idet * m(0,1); + inv(1,0) = -idet * m(1,0); + inv(1,1) = idet * m(0,0); +} + */ + + + + // template <> +void CalcInverse (const Mat<3,3> & m, Mat<3,3> & inv) +{ + double det = Det (m); + if (det == 0) + { + inv = 0; + return; + } + + double idet = 1.0 / det; + inv(0,0) = idet * (m(1,1) * m(2,2) - m(1,2) * m(2,1)); + inv(1,0) = -idet * (m(1,0) * m(2,2) - m(1,2) * m(2,0)); + inv(2,0) = idet * (m(1,0) * m(2,1) - m(1,1) * m(2,0)); + + inv(0,1) = -idet * (m(0,1) * m(2,2) - m(0,2) * m(2,1)); + inv(1,1) = idet * (m(0,0) * m(2,2) - m(0,2) * m(2,0)); + inv(2,1) = -idet * (m(0,0) * m(2,1) - m(0,1) * m(2,0)); + + inv(0,2) = idet * (m(0,1) * m(1,2) - m(0,2) * m(1,1)); + inv(1,2) = -idet * (m(0,0) * m(1,2) - m(0,2) * m(1,0)); + inv(2,2) = idet * (m(0,0) * m(1,1) - m(0,1) * m(1,0)); +} + +/* +// template <> +void CalcInverse (const Mat<2,3> & m, Mat<3,2> & inv) +{ + Mat<2,2> a = m * Trans (m); + Mat<2,2> ainv; + CalcInverse (a, ainv); + inv = Trans (m) * ainv; +} +*/ + + + +double Det (const Mat<2,2> & m) +{ + return m(0,0) * m(1,1) - m(0,1) * m(1,0); +} + +double Det (const Mat<3,3> & m) +{ + return + m(0,0) * m(1,1) * m(2,2) + + m(1,0) * m(2,1) * m(0,2) + + m(2,0) * m(0,1) * m(1,2) + - m(0,0) * m(2,1) * m(1,2) + - m(1,0) * m(0,1) * m(2,2) + - m(2,0) * m(1,1) * m(0,2); +} + + +void EigenValues (const Mat<3,3> & m, Vec<3> & ev) +{ + const double pi = 3.141592; + double a, b, c, d; + double p, q; + double arg; + + a = -1.; + b = m(0,0) + m(1,1) + m(2,2); + c = -( m(0,0)*m(2,2) + m(1,1)*m(2,2) + m(0,0)*m(1,1) - sqr(m(0,1)) - sqr(m(0,2)) - sqr(m(1,2)) ); + d = Det (m); + p = 3.*a*c - sqr(b); + q = 27.*sqr(a)*d - 9.*a*b*c + 2.*sqr(b)*b; + + + arg = acos((-q/2)/sqrt(-(p*p*p))); + + + ev(0) = (2. * sqrt(-p) * cos(arg/3.) - b) / 3.*a; + ev(1) = (-2. * sqrt(-p) * cos(arg/3.+pi/3) - b) / 3.*a; + ev(2) = (-2. * sqrt(-p) * cos(arg/3.-pi/3)- b) / 3.*a; + + + +} + + +} diff --git a/libsrc/gprim/geomfuncs.hpp b/libsrc/gprim/geomfuncs.hpp new file mode 100644 index 00000000..66cbca81 --- /dev/null +++ b/libsrc/gprim/geomfuncs.hpp @@ -0,0 +1,170 @@ +#ifndef FILE_GEOMFUNCS +#define FILE_GEOMFUNCS + +/* *************************************************************************/ +/* File: geomfuncs.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + +namespace netgen +{ + + template + inline double Abs (const Vec & v) + { + double sum = 0; + for (int i = 0; i < D; i++) + sum += v(i) * v(i); + return sqrt (sum); + } + + + template + inline double Abs2 (const Vec & v) + { + double sum = 0; + for (int i = 0; i < D; i++) + sum += v(i) * v(i); + return sum; + } + + + + template + inline double Dist (const Point & a, const Point & b) + { + return Abs (a-b); + } + + template + inline double Dist2 (const Point & a, const Point & b) + { + return Abs2 (a-b); + } + + + template + inline Point Center (const Point & a, const Point & b) + { + Point res; + for (int i = 0; i < D; i++) + res(i) = 0.5 * (a(i) + b(i)); + return res; + } + + template + inline Point Center (const Point & a, const Point & b, const Point & c) + { + Point res; + for (int i = 0; i < D; i++) + res(i) = (1.0/3.0) * (a(i) + b(i) + c(i)); + return res; + } + + template + inline Point Center (const Point & a, const Point & b, const Point & c, const Point & d) + { + Point res; + for (int i = 0; i < D; i++) + res(i) = (1.0/4.0) * (a(i) + b(i) + c(i) + d(i)); + return res; + } + + + + + /* + new wrong code problem with MSVC2010: + using Cross ( & , & ) computes wrong cross-product, problem arises in + Surface::DefineTangentialPlane, e.g. with example boxcyl.geo + */ + // inline Vec<3> Cross (const Vec<3> & v1, const Vec<3> & v2) + + inline Vec<3> Cross (Vec<3> v1, Vec<3> v2) + { + return Vec<3> + ( v1(1) * v2(2) - v1(2) * v2(1), + v1(2) * v2(0) - v1(0) * v2(2), + v1(0) * v2(1) - v1(1) * v2(0) ); + } + + + inline double Determinant (const Vec<3> & col1, + const Vec<3> & col2, + const Vec<3> & col3) + { + return + col1(0) * ( col2(1) * col3(2) - col2(2) * col3(1)) + + col1(1) * ( col2(2) * col3(0) - col2(0) * col3(2)) + + col1(2) * ( col2(0) * col3(1) - col2(1) * col3(0)); + } + + + + template <> + inline Vec<2> Vec<2> :: GetNormal () const + { + return Vec<2> (-x[1], x[0]); + } + + template <> + inline Vec<3> Vec<3> :: GetNormal () const + { + if (fabs (x[0]) > fabs (x[2])) + return Vec<3> (-x[1], x[0], 0); + else + return Vec<3> (0, x[2], -x[1]); + } + + + + // template + inline void CalcInverse (const Mat<2,2> & m, Mat<2,2> & inv) + { + double det = m(0,0) * m(1,1) - m(0,1) * m(1,0); + if (det == 0) + { + inv = 0; + return; + } + + double idet = 1.0 / det; + inv(0,0) = idet * m(1,1); + inv(0,1) = -idet * m(0,1); + inv(1,0) = -idet * m(1,0); + inv(1,1) = idet * m(0,0); + } + + void CalcInverse (const Mat<3,3> & m, Mat<3,3> & inv); + + inline void CalcInverse (const Mat<2,3> & m, Mat<3,2> & inv) + { + Mat<2,2> a = m * Trans (m); + Mat<2,2> ainv; + CalcInverse (a, ainv); + inv = Trans (m) * ainv; + } + + void CalcInverse (const Mat<3,2> & m, Mat<2,3> & inv); + + inline void CalcInverse (const Mat<3,2> & m, Mat<2,3> & inv) + { + Mat<2,2> a = Trans (m) * m; + Mat<2,2> ainv; + CalcInverse (a, ainv); + inv = ainv * Trans (m); + } + + + double Det (const Mat<2,2> & m); + double Det (const Mat<3,3> & m); + + // eigenvalues of a symmetric matrix + void EigenValues (const Mat<3,3> & m, Vec<3> & ev); + void EigenValues (const Mat<2,2> & m, Vec<3> & ev); + +} + +#endif diff --git a/libsrc/gprim/geomobjects.hpp b/libsrc/gprim/geomobjects.hpp new file mode 100644 index 00000000..c4e72aef --- /dev/null +++ b/libsrc/gprim/geomobjects.hpp @@ -0,0 +1,386 @@ +#ifndef FILE_OBJECTS +#define FILE_OBJECTS + +/* *************************************************************************/ +/* File: geomobjects.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + +namespace netgen +{ + + + template class Vec; + template class Point; + + + template + class Point + { + + protected: + double x[D]; + + public: + Point () { ; } + Point (double ax) { for (int i = 0; i < D; i++) x[i] = ax; } + Point (double ax, double ay) { x[0] = ax; x[1] = ay; } + Point (double ax, double ay, double az) + { x[0] = ax; x[1] = ay; x[2] = az; } + Point (double ax, double ay, double az, double au) + { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au;} + + Point (const Point & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Point (const Vec & v) + { for (int i = 0; i < D; i++) x[i] = v(i); } + + + Point & operator= (const Point & p2) + { + for (int i = 0; i < D; i++) x[i] = p2.x[i]; + return *this; + } + + Point & operator= (double val) + { + for (int i = 0; i < D; i++) x[i] = val; + return *this; + } + + double & operator() (int i) { return x[i]; } + const double & operator() (int i) const { return x[i]; } + + operator const double* () const { return x; } + }; + + + + + + template + class Vec + { + + protected: + double x[D]; + + public: + Vec () { ; } // for (int i = 0; i < D; i++) x[i] = 0; } + Vec (double ax) { for (int i = 0; i < D; i++) x[i] = ax; } + Vec (double ax, double ay) { x[0] = ax; x[1] = ay; } + Vec (double ax, double ay, double az) + { x[0] = ax; x[1] = ay; x[2] = az; } + Vec (double ax, double ay, double az, double au) + { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au; } + + Vec (const Vec & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Vec (const Point & p) + { for (int i = 0; i < D; i++) x[i] = p(i); } + + Vec (const Vec & p1, const Vec & p2) + { for(int i=0; i & p2) + { + for (int i = 0; i < D; i++) x[i] = p2.x[i]; + return *this; + } + + Vec & operator= (double s) + { + for (int i = 0; i < D; i++) x[i] = s; + return *this; + } + + double & operator() (int i) { return x[i]; } + const double & operator() (int i) const { return x[i]; } + + operator const double* () const { return x; } + + double Length () const + { + double l = 0; + for (int i = 0; i < D; i++) + l += x[i] * x[i]; + return sqrt (l); + } + + double Length2 () const + { + double l = 0; + for (int i = 0; i < D; i++) + l += x[i] * x[i]; + return l; + } + + const Vec & Normalize () + { + double l = Length(); + if (l != 0) + for (int i = 0; i < D; i++) + x[i] /= l; + return *this; + } + + Vec GetNormal () const; + }; + + + + + + template + class Mat + { + + protected: + double x[H*W]; + + public: + Mat () { ; } + Mat (const Mat & b) + { for (int i = 0; i < H*W; i++) x[i] = b.x[i]; } + + Mat & operator= (double s) + { + for (int i = 0; i < H*W; i++) x[i] = s; + return *this; + } + + Mat & operator= (const Mat & b) + { + for (int i = 0; i < H*W; i++) x[i] = b.x[i]; + return *this; + } + + double & operator() (int i, int j) { return x[i*W+j]; } + const double & operator() (int i, int j) const { return x[i*W+j]; } + double & operator() (int i) { return x[i]; } + const double & operator() (int i) const { return x[i]; } + + Vec Col (int i) const + { + Vec hv; + for (int j = 0; j < H; j++) + hv(j) = x[j*W+i]; + return hv; + } + + Vec Row (int i) const + { + Vec hv; + for (int j = 0; j < W; j++) + hv(j) = x[i*W+j]; + return hv; + } + + void Solve (const Vec & rhs, Vec & sol) const + { + Mat inv; + CalcInverse (*this, inv); + sol = inv * rhs; + } + }; + + + + + template + class Box + { + protected: + Point pmin, pmax; + public: + Box () { ; } + + Box ( const Point & p1) + { + for (int i = 0; i < D; i++) + pmin(i) = pmax(i) = p1(i); + } + + + Box ( const Point & p1, const Point & p2) + { + for (int i = 0; i < D; i++) + { + pmin(i) = min2(p1(i), p2(i)); + pmax(i) = max2(p1(i), p2(i)); + } + } + + enum EB_TYPE { EMPTY_BOX = 1 }; + Box ( EB_TYPE et ) + { + pmin = Point<3> (1e99, 1e99, 1e99); + pmax = Point<3> (-1e99, -1e99, -1e99); + } + + const Point & PMin () const { return pmin; } + const Point & PMax () const { return pmax; } + + void Set (const Point & p) + { pmin = pmax = p; } + + void Add (const Point & p) + { + for (int i = 0; i < D; i++) + { + if (p(i) < pmin(i)) pmin(i) = p(i); + else if (p(i) > pmax(i)) pmax(i) = p(i); + } + } + + template + void Set (const IndirectArray & points) + { + Set (points[points.Begin()]); + for (int i = points.Begin()+1; i < points.End(); i++) + Add (points[i]); + } + + template + void Add (const IndirectArray & points) + { + for (int i = points.Begin(); i < points.End(); i++) + Add (points[i]); + } + + + Point Center () const + { + Point c; + for (int i = 0; i < D; i++) + c(i) = 0.5 * (pmin(i)+pmax(i)); + return c; + } + double Diam () const { return Abs (pmax-pmin); } + + Point GetPointNr (int nr) const + { + Point p; + for (int i = 0; i < D; i++) + { + p(i) = (nr & 1) ? pmax(i) : pmin(i); + nr >>= 1; + } + return p; + } + + + bool Intersect (const Box & box2) const + { + for (int i = 0; i < D; i++) + if (pmin(i) > box2.pmax(i) || + pmax(i) < box2.pmin(i)) return 0; + return 1; + } + + + bool IsIn (const Point & p) const + { + for (int i = 0; i < D; i++) + if (p(i) < pmin(i) || p(i) > pmax(i)) return 0; + return 1; + } + + + void Increase (double dist) + { + for (int i = 0; i < D; i++) + { + pmin(i) -= dist; + pmax(i) += dist; + } + } + }; + + + + + template + class BoxSphere : public Box + { + protected: + /// + Point c; + /// + double diam; + /// + double inner; + public: + /// + BoxSphere () { }; + /// + BoxSphere (const Box & box) + : Box (box) + { + CalcDiamCenter(); + }; + + /// + BoxSphere ( Point apmin, Point apmax ) + : Box (apmin, apmax) + { + CalcDiamCenter(); + } + + /// + const Point & Center () const { return c; } + /// + double Diam () const { return diam; } + /// + double Inner () const { return inner; } + + + /// + void GetSubBox (int nr, BoxSphere & sbox) const + { + for (int i = 0; i < D; i++) + { + if (nr & 1) + { + sbox.pmin(i) = c(i); + sbox.pmax(i) = this->pmax(i); + } + else + { + sbox.pmin(i) = this->pmin(i); + sbox.pmax(i) = c(i); + } + sbox.c(i) = 0.5 * (sbox.pmin(i) + sbox.pmax(i)); + nr >>= 1; + } + sbox.diam = 0.5 * diam; + sbox.inner = 0.5 * inner; + } + + + /// + void CalcDiamCenter () + { + c = Box::Center (); + diam = Dist (this->pmin, this->pmax); + + inner = this->pmax(0) - this->pmin(0); + for (int i = 1; i < D; i++) + if (this->pmax(i) - this->pmin(i) < inner) + inner = this->pmax(i) - this->pmin(i); + } + + }; + + + +} + + +#endif diff --git a/libsrc/gprim/geomobjects2.hpp b/libsrc/gprim/geomobjects2.hpp new file mode 100644 index 00000000..014a3852 --- /dev/null +++ b/libsrc/gprim/geomobjects2.hpp @@ -0,0 +1,366 @@ +#ifndef FILE_OBJECTS +#define FILE_OBJECTS + +/* *************************************************************************/ +/* File: geomobjects.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + +template +class VecExpr +{ +public: + VecExpr () { ; } + double operator() (int i) const { return static_cast (*this) (i); } +}; + + +template class Vec; +template class Point; + + +template +class Point : public VecExpr > +{ + +protected: + double x[D]; + +public: + Point () { ; } + Point (double ax) { x[0] = ax; } + Point (double ax, double ay) { x[0] = ax; x[1] = ay; } + Point (double ax, double ay, double az) + { x[0] = ax; x[1] = ay; x[2] = az; } + Point (double ax, double ay, double az, double au) + { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au;} + + Point (const Point & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Point (const Vec & v) + { for (int i = 0; i < D; i++) x[i] = v(i); } + + + template + explicit Point (const VecExpr & expr) + { + for (int i = 0; i < D; i++) x[i] = expr(i); + } + + Point & operator= (const Point & p2) + { + for (int i = 0; i < D; i++) x[i] = p2.x[i]; + return *this; + } + + template + Point & operator= (const VecExpr & expr) + { + for (int i = 0; i < D; i++) x[i] = expr(i); + return *this; + } + + double & operator() (int i) { return x[i]; } + const double & operator() (int i) const { return x[i]; } + + operator const double* () const { return x; } +}; + + + + + +template +class Vec : public VecExpr > +{ + +protected: + double x[D]; + +public: + Vec () { ; } + Vec (double ax) { for (int i = 0; i < D; i++) x[i] = ax; } + Vec (double ax, double ay) { x[0] = ax; x[1] = ay; } + Vec (double ax, double ay, double az) + { x[0] = ax; x[1] = ay; x[2] = az; } + Vec (double ax, double ay, double az, double au) + { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au; } + + Vec (const Vec & p2) + { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } + + explicit Vec (const Point & p) + { for (int i = 0; i < D; i++) x[i] = p(i); } + + template + explicit Vec (const VecExpr & expr) + { + for (int i = 0; i < D; i++) x[i] = expr(i); + } + + + Vec & operator= (const Vec & p2) + { + for (int i = 0; i < D; i++) x[i] = p2.x[i]; + return *this; + } + + template + Vec & operator= (const VecExpr & expr) + { + for (int i = 0; i < D; i++) x[i] = expr(i); + return *this; + } + + Vec & operator= (double s) + { + for (int i = 0; i < D; i++) x[i] = s; + return *this; + } + + double & operator() (int i) { return x[i]; } + const double & operator() (int i) const { return x[i]; } + + operator const double* () const { return x; } + + double Length () const + { + double l = 0; + for (int i = 0; i < D; i++) + l += x[i] * x[i]; + return sqrt (l); + } + + double Length2 () const + { + double l = 0; + for (int i = 0; i < D; i++) + l += x[i] * x[i]; + return l; + } + + const Vec & Normalize () + { + double l = Length(); + if (l != 0) + for (int i = 0; i < D; i++) + x[i] /= l; + return *this; + } + + Vec GetNormal () const; +}; + + + + + +template +class Mat +{ + +protected: + double x[H*W]; + +public: + Mat () { ; } + Mat (const Mat & b) + { for (int i = 0; i < H*W; i++) x[i] = b.x[i]; } + + Mat & operator= (double s) + { + for (int i = 0; i < H*W; i++) x[i] = s; + return *this; + } + + Mat & operator= (const Mat & b) + { + for (int i = 0; i < H*W; i++) x[i] = b.x[i]; + return *this; + } + + double & operator() (int i, int j) { return x[i*W+j]; } + const double & operator() (int i, int j) const { return x[i*W+j]; } + + Vec Col (int i) const + { + Vec hv; + for (int j = 0; j < H; j++) + hv(j) = x[j*W+i]; + return hv; + } + + Vec Row (int i) const + { + Vec hv; + for (int j = 0; j < W; j++) + hv(j) = x[i*W+j]; + return hv; + } + + void Solve (const Vec & rhs, Vec & sol) const + { + Mat inv; + CalcInverse (*this, inv); + sol = inv * rhs; + } +}; + + + + +template +class Box +{ +protected: + Point pmin, pmax; +public: + Box () { ; } + Box ( const Point & p1, const Point & p2) + { + for (int i = 0; i < D; i++) + { + pmin(i) = min2(p1(i), p2(i)); + pmax(i) = max2(p1(i), p2(i)); + } + } + + const Point & PMin () const { return pmin; } + const Point & PMax () const { return pmax; } + + void Set (const Point & p) + { pmin = pmax = p; } + + void Add (const Point & p) + { + for (int i = 0; i < D; i++) + { + if (p(i) < pmin(i)) pmin(i) = p(i); + else if (p(i) > pmax(i)) pmax(i) = p(i); + } + } + + Point Center () const + { + Point c; + for (int i = 0; i < D; i++) + c(i) = 0.5 * (pmin(i)+pmax(i)); + return c; + } + double Diam () const { return Abs (pmax-pmin); } + + Point GetPointNr (int nr) const + { + Point p; + for (int i = 0; i < D; i++) + { + p(i) = (nr & 1) ? pmax(i) : pmin(i); + nr >>= 1; + } + return p; + } + + + bool Intersect (const Box & box2) const + { + for (int i = 0; i < D; i++) + if (pmin(i) > box2.pmax(i) || + pmax(i) < box2.pmin(i)) return 0; + return 1; + } + + + bool IsIn (const Point & p) const + { + for (int i = 0; i < D; i++) + if (p(i) < pmin(i) || p(i) > pmax(i)) return 0; + return 1; + } + + + void Increase (double dist) + { + for (int i = 0; i < D; i++) + { + pmin(i) -= dist; + pmax(i) += dist; + } + } +}; + + + + +template +class BoxSphere : public Box +{ +protected: + /// + Point c; + /// + double diam; + /// + double inner; +public: + /// + BoxSphere () { }; + /// + BoxSphere ( Point pmin, Point pmax ) + : Box (pmin, pmax) + { + CalcDiamCenter(); + } + + /// + const Point & Center () const { return c; } + /// + double Diam () const { return diam; } + /// + double Inner () const { return inner; } + + + /// + void GetSubBox (int nr, BoxSphere & sbox) const + { + for (int i = 0; i < D; i++) + { + if (nr & 1) + { + sbox.pmin(i) = c(i); + sbox.pmax(i) = this->pmax(i); + } + else + { + sbox.pmin(i) = this->pmin(i); + sbox.pmax(i) = c(i); + } + sbox.c(i) = 0.5 * (sbox.pmin(i) + sbox.pmax(i)); + nr >>= 1; + } + sbox.diam = 0.5 * diam; + sbox.inner = 0.5 * inner; + } + + + /// + void CalcDiamCenter () + { + c = Box::Center (); + diam = Dist (this->pmin, this->pmax); + + inner = this->pmax(0) - this->pmin(0); + for (int i = 1; i < D; i++) + if (this->pmax(i) - this->pmin(i) < inner) + inner = this->pmax(i) - this->pmin(i); + } + +}; + + + + + + +#endif diff --git a/libsrc/gprim/geomops.hpp b/libsrc/gprim/geomops.hpp new file mode 100644 index 00000000..90c3cb6b --- /dev/null +++ b/libsrc/gprim/geomops.hpp @@ -0,0 +1,394 @@ +#ifndef FILE_GEOMOPS +#define FILE_GEOMOPS + +/* *************************************************************************/ +/* File: geomops.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + +namespace netgen +{ + + /* + + Point - Vector operations + + */ + + + template + inline Vec operator+ (const Vec & a, const Vec & b) + { + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; + } + + + + template + inline Point operator+ (const Point & a, const Vec & b) + { + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; + } + + + + template + inline Vec operator- (const Point & a, const Point & b) + { + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; + } + + template + inline Point operator- (const Point & a, const Vec & b) + { + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; + } + + template + inline Vec operator- (const Vec & a, const Vec & b) + { + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; + } + + + + template + inline Vec operator* (double s, const Vec & b) + { + Vec res; + for (int i = 0; i < D; i++) + res(i) = s * b(i); + return res; + } + + + template + inline double operator* (const Vec & a, const Vec & b) + { + double sum = 0; + for (int i = 0; i < D; i++) + sum += a(i) * b(i); + return sum; + } + + + + template + inline Vec operator- (const Vec & b) + { + Vec res; + for (int i = 0; i < D; i++) + res(i) = -b(i); + return res; + } + + + template + inline Point & operator+= (Point & a, const Vec & b) + { + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; + } + + template + inline Vec & operator+= (Vec & a, const Vec & b) + { + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; + } + + + template + inline Point & operator-= (Point & a, const Vec & b) + { + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; + } + + template + inline Vec & operator-= (Vec & a, const Vec & b) + { + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; + } + + + + template + inline Vec & operator*= (Vec & a, double s) + { + for (int i = 0; i < D; i++) + a(i) *= s; + return a; + } + + + template + inline Vec & operator/= (Vec & a, double s) + { + for (int i = 0; i < D; i++) + a(i) /= s; + return a; + } + + + + + // Matrix - Vector operations + + /* + template + inline Vec operator* (const Mat & m, const Vec & v) + { + Vec res; + for (int i = 0; i < H; i++) + { + res(i) = 0; + for (int j = 0; j < W; j++) + res(i) += m(i,j) * v(j); + } + return res; + } + */ + + // thanks to VC60 partial template specialization features !!! + + inline Vec<2> operator* (const Mat<2,2> & m, const Vec<2> & v) + { + Vec<2> res; + for (int i = 0; i < 2; i++) + { + res(i) = 0; + for (int j = 0; j < 2; j++) + res(i) += m(i,j) * v(j); + } + return res; + } + + inline Vec<2> operator* (const Mat<2,3> & m, const Vec<3> & v) + { + Vec<2> res; + for (int i = 0; i < 2; i++) + { + res(i) = 0; + for (int j = 0; j < 3; j++) + res(i) += m(i,j) * v(j); + } + return res; + } + + + inline Vec<3> operator* (const Mat<3,2> & m, const Vec<2> & v) + { + Vec<3> res; + for (int i = 0; i < 3; i++) + { + res(i) = 0; + for (int j = 0; j < 2; j++) + res(i) += m(i,j) * v(j); + } + return res; + } + + + inline Vec<3> operator* (const Mat<3,3> & m, const Vec<3> & v) + { + Vec<3> res; + for (int i = 0; i < 3; i++) + { + res(i) = 0; + for (int j = 0; j < 3; j++) + res(i) += m(i,j) * v(j); + } + return res; + } + + + + + + + + /* + template + inline Mat operator* (const Mat & a, const Mat & b) + { + Mat m; + for (int i = 0; i < H1; i++) + for (int j = 0; j < W2; j++) + { + double sum = 0; + for (int k = 0; k < W1; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; + } + */ + + inline Mat<2,2> operator* (const Mat<2,2> & a, const Mat<2,2> & b) + { + Mat<2,2> m; + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + { + double sum = 0; + for (int k = 0; k < 2; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; + } + + inline Mat<2,2> operator* (const Mat<2,3> & a, const Mat<3,2> & b) + { + Mat<2,2> m; + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + { + double sum = 0; + for (int k = 0; k < 3; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; + } + + + inline Mat<3,2> operator* (const Mat<3,2> & a, const Mat<2,2> & b) + { + Mat<3,2> m; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 2; j++) + { + double sum = 0; + for (int k = 0; k < 2; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; + } + + + + inline Mat<2,3> operator* (const Mat<2,2> & a, const Mat<2,3> & b) + { + Mat<2,3> m; + for (int i = 0; i < 2; i++) + for (int j = 0; j < 3; j++) + { + double sum = 0; + for (int k = 0; k < 2; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; + } + + + inline Mat<3,3> operator* (const Mat<3,3> & a, const Mat<3,3> & b) + { + Mat<3,3> m; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + { + double sum = 0; + for (int k = 0; k < 3; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; + } + + + + + + + + + template + inline Mat Trans (const Mat & m) + { + Mat res; + for (int i = 0; i < H; i++) + for (int j = 0; j < W; j++) + res(j,i) = m(i,j); + return res; + } + + + + + + + + + + + + template + inline ostream & operator<< (ostream & ost, const Vec & a) + { + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; + } + + template + inline ostream & operator<< (ostream & ost, const Point & a) + { + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; + } + + template + inline ostream & operator<< (ostream & ost, const Box & b) + { + ost << b.PMin() << " - " << b.PMax(); + return ost; + } + + template + inline ostream & operator<< (ostream & ost, const Mat & m) + { + ost << "("; + for (int i = 0; i < H; i++) + { + for (int j = 0; j < W; j++) + ost << m(i,j) << " "; + ost << endl; + } + return ost; + } + + +} + +#endif diff --git a/libsrc/gprim/geomops2.hpp b/libsrc/gprim/geomops2.hpp new file mode 100644 index 00000000..c615da14 --- /dev/null +++ b/libsrc/gprim/geomops2.hpp @@ -0,0 +1,428 @@ +#ifndef FILE_GEOMOPS +#define FILE_GEOMOPS + +/* *************************************************************************/ +/* File: geomops.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Jul. 02 */ +/* *************************************************************************/ + + +/* + +Point - Vector operations + + */ + + + + +template +class SumExpr : public VecExpr > +{ + const TA a; + const TB b; +public: + SumExpr (const TA aa, const TB ab) : a(aa), b(ab) { ; } + double operator() (int i) const { return a(i) + b(i); } +}; + +template +inline SumExpr +operator+ (const VecExpr & a, const VecExpr & b) +{ + return SumExpr (static_cast (a), static_cast (b)); +} + +/* +template +inline SumExpr&, const Vec&> +operator+ (const Vec & a, const Vec & b) +{ + return SumExpr&, const Vec&> (a, b); +} +*/ + + + + + +/* +template +inline Vec operator+ (const Vec & a, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; +} +*/ + +template +inline Point operator+ (const Point & a, const Vec & b) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) + b(i); + return res; +} + + +template +inline Vec operator- (const Point & a, const Point & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + +template +inline Point operator- (const Point & a, const Vec & b) +{ + Point res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + +template +inline Vec operator- (const Vec & a, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = a(i) - b(i); + return res; +} + + +template +inline Vec operator* (double s, const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = s * b(i); + return res; +} + + +template +inline double operator* (const Vec & a, const Vec & b) +{ + double sum = 0; + for (int i = 0; i < D; i++) + sum += a(i) * b(i); + return sum; +} + + + +template +inline Vec operator- (const Vec & b) +{ + Vec res; + for (int i = 0; i < D; i++) + res(i) = -b(i); + return res; +} + + +template +inline Point & operator+= (Point & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + + +template +inline Point & operator+= (Point & a, const VecExpr & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + +template +inline Vec & operator+= (Vec & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) += b(i); + return a; +} + + + + + +template +inline Point & operator-= (Point & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + +template +inline Point & operator-= (Point & a, const VecExpr & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + + + + + +template +inline Vec & operator-= (Vec & a, const Vec & b) +{ + for (int i = 0; i < D; i++) + a(i) -= b(i); + return a; +} + + + +template +inline Vec & operator*= (Vec & a, double s) +{ + for (int i = 0; i < D; i++) + a(i) *= s; + return a; +} + + +template +inline Vec & operator/= (Vec & a, double s) +{ + for (int i = 0; i < D; i++) + a(i) /= s; + return a; +} + + + + +// Matrix - Vector operations + +/* +template +inline Vec operator* (const Mat & m, const Vec & v) +{ + Vec res; + for (int i = 0; i < H; i++) + { + res(i) = 0; + for (int j = 0; j < W; j++) + res(i) += m(i,j) * v(j); + } + return res; +} +*/ + +// thanks to VC60 partial template specialization features !!! + +inline Vec<2> operator* (const Mat<2,2> & m, const Vec<2> & v) +{ + Vec<2> res; + for (int i = 0; i < 2; i++) + { + res(i) = 0; + for (int j = 0; j < 2; j++) + res(i) += m(i,j) * v(j); + } + return res; +} + +inline Vec<2> operator* (const Mat<2,3> & m, const Vec<3> & v) +{ + Vec<2> res; + for (int i = 0; i < 2; i++) + { + res(i) = 0; + for (int j = 0; j < 3; j++) + res(i) += m(i,j) * v(j); + } + return res; +} + + +inline Vec<3> operator* (const Mat<3,2> & m, const Vec<2> & v) +{ + Vec<3> res; + for (int i = 0; i < 3; i++) + { + res(i) = 0; + for (int j = 0; j < 2; j++) + res(i) += m(i,j) * v(j); + } + return res; +} + + +inline Vec<3> operator* (const Mat<3,3> & m, const Vec<3> & v) +{ + Vec<3> res; + for (int i = 0; i < 3; i++) + { + res(i) = 0; + for (int j = 0; j < 3; j++) + res(i) += m(i,j) * v(j); + } + return res; +} + + + + + + + +/* +template +inline Mat operator* (const Mat & a, const Mat & b) +{ + Mat m; + for (int i = 0; i < H1; i++) + for (int j = 0; j < W2; j++) + { + double sum = 0; + for (int k = 0; k < W1; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; +} +*/ + +inline Mat<2,2> operator* (const Mat<2,2> & a, const Mat<2,2> & b) +{ + Mat<2,2> m; + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + { + double sum = 0; + for (int k = 0; k < 2; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; +} + +inline Mat<2,2> operator* (const Mat<2,3> & a, const Mat<3,2> & b) +{ + Mat<2,2> m; + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + { + double sum = 0; + for (int k = 0; k < 3; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; +} + + +inline Mat<3,2> operator* (const Mat<3,2> & a, const Mat<2,2> & b) +{ + Mat<3,2> m; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 2; j++) + { + double sum = 0; + for (int k = 0; k < 2; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; +} + +inline Mat<3,3> operator* (const Mat<3,3> & a, const Mat<3,3> & b) +{ + Mat<3,3> m; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + { + double sum = 0; + for (int k = 0; k < 3; k++) + sum += a(i,k) * b(k, j); + m(i,j) = sum; + } + return m; +} + + + + + + + + +template +inline Mat Trans (const Mat & m) +{ + Mat res; + for (int i = 0; i < H; i++) + for (int j = 0; j < W; j++) + res(j,i) = m(i,j); + return res; +} + + + + + + + + + + + +template +inline ostream & operator<< (ostream & ost, const Vec & a) +{ + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Point & a) +{ + ost << "("; + for (int i = 0; i < D-1; i++) + ost << a(i) << ", "; + ost << a(D-1) << ")"; + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Box & b) +{ + ost << b.PMin() << " - " << b.PMax(); + return ost; +} + +template +inline ostream & operator<< (ostream & ost, const Mat & m) +{ + ost << "("; + for (int i = 0; i < H; i++) + { + for (int j = 0; j < W; j++) + ost << m(i,j) << " "; + ost << endl; + } + return ost; +} + + + + +#endif diff --git a/libsrc/gprim/geomtest3d.cpp b/libsrc/gprim/geomtest3d.cpp new file mode 100644 index 00000000..5036d2a7 --- /dev/null +++ b/libsrc/gprim/geomtest3d.cpp @@ -0,0 +1,1155 @@ +#include +#include + +#include +#include + +namespace netgen +{ + +int +IntersectTriangleLine (const Point<3> ** tri, const Point<3> ** line) +{ + Vec3d vl(*line[0], *line[1]); + Vec3d vt1(*tri[0], *tri[1]); + Vec3d vt2(*tri[0], *tri[2]); + Vec3d vrs(*tri[0], *line[0]); + + // static DenseMatrix a(3), ainv(3); + // static Vector rs(3), lami(3); + Mat<3,3> a, ainv; + Vec<3> rs, lami; + int i; + + /* + (*testout) << "Tri-Line inters: " << endl + << "tri = " << *tri[0] << ", " << *tri[1] << ", " << *tri[2] << endl + << "line = " << *line[0] << ", " << *line[1] << endl; + */ + for (i = 0; i < 3; i++) + { + a(i, 0) = -vl.X(i+1); + a(i, 1) = vt1.X(i+1); + a(i, 2) = vt2.X(i+1); + rs(i) = vrs.X(i+1); + } + + // double det = a.Det(); + double det = Det(a); + + double arel = vl.Length() * vt1.Length() * vt2.Length(); + /* + double amax = 0; + for (i = 1; i <= 9; i++) + if (fabs (a.Get(i)) > amax) + amax = fabs(a.Get(i)); + */ + // new !!!! + if (fabs (det) <= 1e-10 * arel) + { +#ifdef DEVELOP + // line parallel to triangle ! + // cout << "ERROR: IntersectTriangleLine degenerated" << endl; + // (*testout) << "WARNING: IntersectTriangleLine degenerated\n"; + /* + (*testout) << "lin-tri intersection: " << endl + << "line = " << *line[0] << " - " << *line[1] << endl + << "tri = " << *tri[0] << " - " << *tri[1] << " - " << *tri[2] << endl + << "lami = " << lami << endl + << "pc = " << ( *line[0] + lami.Get(1) * vl ) << endl + << " = " << ( *tri[0] + lami.Get(2) * vt1 + lami.Get(3) * vt2) << endl + << " a = " << a << endl + << " ainv = " << ainv << endl + << " det(a) = " << det << endl + << " rs = " << rs << endl; + */ +#endif + return 0; + } + + CalcInverse (a, ainv); + // ainv.Mult (rs, lami); + lami = ainv * rs; + + // (*testout) << "lami = " << lami << endl; + + double eps = 1e-6; + if ( + (lami(0) >= -eps && lami(0) <= 1+eps && + lami(1) >= -eps && lami(2) >= -eps && + lami(1) + lami(2) <= 1+eps) && ! + (lami(0) >= eps && lami(0) <= 1-eps && + lami(1) >= eps && lami(2) >= eps && + lami(1) + lami(2) <= 1-eps) ) + + + { +#ifdef DEVELOP + // cout << "WARNING: IntersectTriangleLine degenerated" << endl; + (*testout) << "WARNING: IntersectTriangleLine numerical inexact" << endl; + + (*testout) << "lin-tri intersection: " << endl + << "line = " << *line[0] << " - " << *line[1] << endl + << "tri = " << *tri[0] << " - " << *tri[1] << " - " << *tri[2] << endl + << "lami = " << lami << endl + << "pc = " << ( *line[0] + lami.Get(1) * vl ) << endl + << " = " << ( *tri[0] + lami.Get(2) * vt1 + lami.Get(3) * vt2) << endl + << " a = " << a << endl + << " ainv = " << ainv << endl + << " det(a) = " << det << endl + << " rs = " << rs << endl; +#endif + } + + + if (lami(0) >= 0 && lami(0) <= 1 && + lami(1) >= 0 && lami(2) >= 0 && lami(1) + lami(2) <= 1) + { + + return 1; + } + + return 0; +} + + + + + +int IntersectTetTriangle (const Point<3> ** tet, const Point<3> ** tri, + const int * tetpi, const int * tripi) +{ + int i, j; + double diam = Dist (*tri[0], *tri[1]); + double epsrel = 1e-8; + double eps = diam * epsrel; + + double eps2 = eps * eps; + int cnt = 0; + + int tetp1 = -1, tetp2 = -1; + int trip1 = -1, trip2 = -1; + int tetp3, tetp4, trip3; + + /* + for (i = 0; i < 4; i++) + loctetpi[i] = -1; + */ + + + if (!tetpi) + { + for (i = 0; i <= 2; i++) + { + // loctripi[i] = -1; + for (j = 0; j <= 3; j++) + { + if (Dist2 (*tet[j], *tri[i]) < eps2) + { + // loctripi[i] = j; + // loctetpi[j] = i; + cnt++; + tetp2 = tetp1; + tetp1 = j; + trip2 = trip1; + trip1 = i; + break; + } + } + } + } + else + { + for (i = 0; i <= 2; i++) + { + // loctripi[i] = -1; + for (j = 0; j <= 3; j++) + { + if (tetpi[j] == tripi[i]) + { + // loctripi[i] = j; + // loctetpi[j] = i; + cnt++; + tetp2 = tetp1; + tetp1 = j; + trip2 = trip1; + trip1 = i; + break; + } + } + } + } + + // (*testout) << "cnt = " << cnt << endl; + + + // (*testout) << "tet-trig inters, cnt = " << cnt << endl; + + // cnt .. number of common points + switch (cnt) + { + case 0: + { + Vec3d no, n; + int inpi[3]; + + // check, if some trigpoint is in tet: + + for (j = 0; j < 3; j++) + inpi[j] = 1; + + for (i = 1; i <= 4; i++) + { + int pi1 = i % 4; + int pi2 = (i+1) % 4; + int pi3 = (i+2) % 4; + int pi4 = (i+3) % 4; + + Vec3d v1 (*tet[pi1], *tet[pi2]); + Vec3d v2 (*tet[pi1], *tet[pi3]); + Vec3d v3 (*tet[pi1], *tet[pi4]); + Cross (v1, v2, n); + + // n /= n.Length(); + double nl = n.Length(); + + if (v3 * n > 0) + n *= -1; + + int outeri = 1; + for (j = 0; j < 3; j++) + { + Vec3d v(*tet[pi1], *tri[j]); + if ( v * n < eps * nl) + outeri = 0; + else + inpi[j] = 0; + } + + if (outeri) + return 0; + } + + if (inpi[0] || inpi[1] || inpi[2]) + { + return 1; + } + + + // check, if some tet edge intersects triangle: + const Point<3> * line[2], *tetf[3]; + for (i = 0; i <= 2; i++) + for (j = i+1; j <= 3; j++) + { + line[0] = tet[i]; + line[1] = tet[j]; + + if (IntersectTriangleLine (tri, &line[0])) + return 1; + } + + // check, if triangle line intersects tet face: + for (i = 0; i <= 3; i++) + { + for (j = 0; j <= 2; j++) + tetf[j] = tet[(i+j) % 4]; + + for (j = 0; j <= 2; j++) + { + line[0] = tri[j]; + line[1] = tri[(j+1) % 3]; + + if (IntersectTriangleLine (&tetf[0], &line[0])) + return 1; + } + } + + + return 0; +//GH break; + } + case 1: + { + trip2 = 0; + while (trip2 == trip1) + trip2++; + trip3 = 3 - trip1 - trip2; + + tetp2 = 0; + while (tetp2 == tetp1) + tetp2++; + tetp3 = 0; + while (tetp3 == tetp1 || tetp3 == tetp2) + tetp3++; + tetp4 = 6 - tetp1 - tetp2 - tetp3; + + Vec3d vtri1 = *tri[trip2] - *tri[trip1]; + Vec3d vtri2 = *tri[trip3] - *tri[trip1]; + Vec3d ntri; + Cross (vtri1, vtri2, ntri); + + // tri durch tet ? + // fehlt noch + + + // test 3 tet-faces: + for (i = 1; i <= 3; i++) + { + Vec3d vtet1, vtet2; + switch (i) + { + case 1: + { + vtet1 = *tet[tetp2] - *tet[tetp1]; + vtet2 = *tet[tetp3] - *tet[tetp1]; + break; + } + case 2: + { + vtet1 = *tet[tetp3] - *tet[tetp1]; + vtet2 = *tet[tetp4] - *tet[tetp1]; + break; + } + case 3: + { + vtet1 = *tet[tetp4] - *tet[tetp1]; + vtet2 = *tet[tetp2] - *tet[tetp1]; + break; + } + } + + Vec3d ntet; + Cross (vtet1, vtet2, ntet); + + Vec3d crline = Cross (ntri, ntet); + + double lcrline = crline.Length(); + + if (lcrline < eps * eps * eps * eps) // new change ! + continue; + + if (vtri1 * crline + vtri2 * crline < 0) + crline *= -1; + + crline /= lcrline; + + double lam1, lam2, lam3, lam4; + LocalCoordinates (vtri1, vtri2, crline, lam1, lam2); + LocalCoordinates (vtet1, vtet2, crline, lam3, lam4); + + if (lam1 > -epsrel && lam2 > -epsrel && + lam3 > -epsrel && lam4 > -epsrel) + { + + /* + (*testout) << "lcrline = " << lcrline + << " eps = " << eps << " diam = " << diam << endl; + + (*testout) << "hit, cnt == 1 " + << "lam1,2,3,4 = " << lam1 << ", " + << lam2 << ", " << lam3 << ", " << lam4 + << "\n"; + */ + return 1; + } + } + return 0; +//GH break; + } + case 2: + { + // common edge + tetp3 = 0; + while (tetp3 == tetp1 || tetp3 == tetp2) + tetp3++; + tetp4 = 6 - tetp1 - tetp2 - tetp3; + trip3 = 3 - trip1 - trip2; + + // (*testout) << "trip1,2,3 = " << trip1 << ", " << trip2 << ", " << trip3 << endl; + // (*testout) << "tetp1,2,3,4 = " << tetp1 << ", " << tetp2 + // << ", " << tetp3 << ", " << tetp4 << endl; + + Vec3d vtri = *tri[trip3] - *tri[trip1]; + Vec3d vtet1 = *tet[tetp3] - *tri[trip1]; + Vec3d vtet2 = *tet[tetp4] - *tri[trip1]; + + Vec3d n = *tri[trip2] - *tri[trip1]; + n /= n.Length(); + + vtet1 -= (n * vtet1) * n; + vtet2 -= (n * vtet2) * n; + + + double lam1, lam2; + LocalCoordinates (vtet1, vtet2, vtri, lam1, lam2); + + if (lam1 < -epsrel || lam2 < -epsrel) + return 0; + else + { + /* + + (*testout) << "vtet1 = " << vtet1 << endl; + (*testout) << "vtet2 = " << vtet2 << endl; + (*testout) << "vtri = " << vtri << endl; + (*testout) << "lam1 = " << lam1 << " lam2 = " << lam2 << endl; + (*testout) << (lam1 * (vtet1 * vtet1) + lam2 * (vtet1 * vtet2)) + << " = " << (vtet1 * vtri) << endl; + (*testout) << (lam1 * (vtet1 * vtet2) + lam2 * (vtet2 * vtet2)) + << " = " << (vtet2 * vtri) << endl; + + (*testout) << "tet = "; + for (j = 0; j < 4; j++) + (*testout) << (*tet[j]) << " "; + (*testout) << endl; + (*testout) << "tri = "; + for (j = 0; j < 3; j++) + (*testout) << (*tri[j]) << " "; + (*testout) << endl; + + (*testout) << "hit, cnt == 2" << endl; + */ + + return 1; + } + + break; + } + case 3: + { + // common face + return 0; + } + } + + (*testout) << "hit, cnt = " << cnt << endl; + return 1; +} + + + + + +int IntersectTetTriangleRef (const Point<3> ** tri, const int * tripi) +{ + int i, j; + double eps = 1e-8; + // double eps2 = eps * eps; + + static Point<3> rtetp1(0, 0, 0); + static Point<3> rtetp2(1, 0, 0); + static Point<3> rtetp3(0, 1, 0); + static Point<3> rtetp4(0, 0, 1); + + static const Point<3> * tet[] = { &rtetp1, &rtetp2, &rtetp3, &rtetp4 }; + static int tetpi[] = { 1, 2, 3, 4 }; + + + // return IntersectTetTriangle (tet, tri, tetpi, tripi); + + + int cnt = 0; + + int tetp1 = -1, tetp2 = -1; + int trip1 = -1, trip2 = -1; + int tetp3, tetp4, trip3; + + /* + if (!tetpi) + { + for (i = 0; i <= 2; i++) + { + for (j = 0; j <= 3; j++) + { + if (Dist2 (*tet[j], *tri[i]) < eps2) + { + cnt++; + tetp2 = tetp1; + tetp1 = j; + trip2 = trip1; + trip1 = i; + break; + } + } + } + } + else + */ + { + for (i = 0; i <= 2; i++) + { + for (j = 0; j <= 3; j++) + { + if (tetpi[j] == tripi[i]) + { + cnt++; + tetp2 = tetp1; + tetp1 = j; + trip2 = trip1; + trip1 = i; + break; + } + } + } + } + + // (*testout) << "cnt = " << cnt << endl; + + + switch (cnt) + { + case 0: + { + Vec3d no, n; + // int inpi[3]; + int pside[3][4]; + + for (j = 0; j < 3; j++) + { + pside[j][0] = (*tri[j])(0) > -eps; + pside[j][1] = (*tri[j])(1) > -eps; + pside[j][2] = (*tri[j])(2) > -eps; + pside[j][3] = (*tri[j])(0) + (*tri[j])(1) + (*tri[j])(2) < 1+eps; + } + + + for (j = 0; j < 4; j++) + { + if (!pside[0][j] && !pside[1][j] && !pside[2][j]) + return 0; + } + + for (j = 0; j < 3; j++) + { + if (pside[j][0] && pside[j][1] && pside[j][2] && pside[j][3]) + return 1; + } + + + const Point<3> * line[2], *tetf[3]; + for (i = 0; i <= 2; i++) + for (j = i+1; j <= 3; j++) + { + line[0] = tet[i]; + line[1] = tet[j]; + + if (IntersectTriangleLine (tri, &line[0])) + return 1; + } + + for (i = 0; i <= 3; i++) + { + for (j = 0; j <= 2; j++) + tetf[j] = tet[(i+j) % 4]; + + for (j = 0; j <= 2; j++) + { + line[0] = tri[j]; + line[1] = tri[(j+1) % 3]; + + if (IntersectTriangleLine (&tetf[0], &line[0])) + return 1; + } + } + + + return 0; + break; + } + case 1: + { + trip2 = 0; + if (trip2 == trip1) + trip2++; + trip3 = 3 - trip1 - trip2; + + tetp2 = 0; + while (tetp2 == tetp1) + tetp2++; + tetp3 = 0; + while (tetp3 == tetp1 || tetp3 == tetp2) + tetp3++; + tetp4 = 6 - tetp1 - tetp2 - tetp3; + + Vec3d vtri1 = *tri[trip2] - *tri[trip1]; + Vec3d vtri2 = *tri[trip3] - *tri[trip1]; + Vec3d ntri; + Cross (vtri1, vtri2, ntri); + + // tri durch tet ? + + /* + Vec3d vtet1(*tet[tetp1], *tet[tetp2]); + Vec3d vtet2(*tet[tetp1], *tet[tetp3]); + Vec3d vtet3(*tet[tetp1], *tet[tetp4]); + Vec3d sol; + + SolveLinearSystem (vtet1, vtet2, vtet3, vtri1, sol); + if (sol.X() > 0 && sol.Y() > 0 && sol.Z() > 0) + return 1; + + SolveLinearSystem (vtet1, vtet2, vtet3, vtri2, sol); + if (sol.X() > 0 && sol.Y() > 0 && sol.Z() > 0) + return 1; + */ + + // test 3 tet-faces: + for (i = 1; i <= 3; i++) + { + Vec3d vtet1, vtet2; + switch (i) + { + case 1: + { + vtet1 = *tet[tetp2] - *tet[tetp1]; + vtet2 = *tet[tetp3] - *tet[tetp1]; + break; + } + case 2: + { + vtet1 = *tet[tetp3] - *tet[tetp1]; + vtet2 = *tet[tetp4] - *tet[tetp1]; + break; + } + case 3: + { + vtet1 = *tet[tetp4] - *tet[tetp1]; + vtet2 = *tet[tetp2] - *tet[tetp1]; + break; + } + } + + Vec3d ntet; + Cross (vtet1, vtet2, ntet); + + Vec3d crline = Cross (ntri, ntet); + + double lcrline = crline.Length(); + if (lcrline < eps * eps) + continue; + + + if (vtri1 * crline + vtri2 * crline < 0) + crline *= -1; + + double lam1, lam2, lam3, lam4; + LocalCoordinates (vtri1, vtri2, crline, lam1, lam2); + LocalCoordinates (vtet1, vtet2, crline, lam3, lam4); + + if (lam1 > -eps && lam2 > -eps && + lam3 > -eps && lam4 > -eps) + { + // (*testout) << "hit, cnt == 1" << "\n"; + return 1; + } + } + + return 0; + break; + } + case 2: + { + // common edge + tetp3 = 0; + while (tetp3 == tetp1 || tetp3 == tetp2) + tetp3++; + tetp4 = 6 - tetp1 - tetp2 - tetp3; + trip3 = 3 - trip1 - trip2; + + // (*testout) << "trip1,2,3 = " << trip1 << ", " << trip2 << ", " << trip3 << endl; + // (*testout) << "tetp1,2,3,4 = " << tetp1 << ", " << tetp2 + // << ", " << tetp3 << ", " << tetp4 << endl; + + Vec3d vtri = *tri[trip3] - *tri[trip1]; + Vec3d vtet1 = *tet[tetp3] - *tri[trip1]; + Vec3d vtet2 = *tet[tetp4] - *tri[trip1]; + + Vec3d n = *tri[trip2] - *tri[trip1]; + n /= n.Length(); + + vtet1 -= (n * vtet1) * n; + vtet2 -= (n * vtet2) * n; + + + double lam1, lam2; + LocalCoordinates (vtet1, vtet2, vtri, lam1, lam2); + + if (lam1 < -eps || lam2 < -eps) + return 0; + else + { + +// (*testout) << "vtet1 = " << vtet1 << endl; +// (*testout) << "vtet2 = " << vtet2 << endl; +// (*testout) << "vtri = " << vtri << endl; +// (*testout) << "lam1 = " << lam1 << " lam2 = " << lam2 << endl; + +// (*testout) << (lam1 * (vtet1 * vtet1) + lam2 * (vtet1 * vtet2)) +// << " = " << (vtet1 * vtri) << endl; +// (*testout) << (lam1 * (vtet1 * vtet2) + lam2 * (vtet2 * vtet2)) +// << " = " << (vtet2 * vtri) << endl; + +// (*testout) << "tet = "; +// for (j = 0; j < 4; j++) +// (*testout) << (*tet[j]) << " "; +// (*testout) << endl; +// (*testout) << "tri = "; +// for (j = 0; j < 3; j++) +// (*testout) << (*tri[j]) << " "; +// (*testout) << endl; + +// (*testout) << "hit, cnt == 2" << endl; + + return 1; + } + + break; + } + case 3: + { + // common face + return 0; + } + } + + (*testout) << "hit, cnt = " << cnt << endl; + return 1; +} + + + + + + + + + + + +int IntersectTriangleTriangle (const Point<3> ** tri1, const Point<3> ** tri2) +{ + int i, j; + double diam = Dist (*tri1[0], *tri1[1]); + double epsrel = 1e-8; + double eps = diam * epsrel; + double eps2 = eps * eps; + + + + int cnt = 0; + /* + int tri1pi[3]; + int tri2pi[3]; + */ + + // int tri1p1 = -1; + /// int tri1p2 = -1; + // int tri2p1 = -1; + // int tri2p2 = -1; + // int tri1p3, tri2p3; + + /* + for (i = 0; i < 3; i++) + tri1pi[i] = -1; + */ + for (i = 0; i <= 2; i++) + { + // tri2pi[i] = -1; + for (j = 0; j <= 2; j++) + { + if (Dist2 (*tri1[j], *tri2[i]) < eps2) + { + // tri2pi[i] = j; + // tri1pi[j] = i; + cnt++; + // tri1p2 = tri1p1; + // tri1p1 = j; + // tri2p2 = tri2p1; + // tri2p1 = i; + break; + } + } + } + + switch (cnt) + { + case 0: + { + const Point<3> * line[2]; + + for (i = 0; i <= 2; i++) + { + line[0] = tri2[i]; + line[1] = tri2[(i+1)%3]; + + if (IntersectTriangleLine (tri1, &line[0])) + { + (*testout) << "int1, line = " << *line[0] << " - " << *line[1] << endl; + return 1; + } + } + + for (i = 0; i <= 2; i++) + { + line[0] = tri1[i]; + line[1] = tri1[(i+1)%3]; + + if (IntersectTriangleLine (tri2, &line[0])) + { + (*testout) << "int2, line = " << *line[0] << " - " << *line[1] << endl; + return 1; + } + } + break; + } + default: + return 0; + } + + return 0; +} + + + +void +LocalCoordinates (const Vec3d & e1, const Vec3d & e2, + const Vec3d & v, double & lam1, double & lam2) +{ + double m11 = e1 * e1; + double m12 = e1 * e2; + double m22 = e2 * e2; + double rs1 = v * e1; + double rs2 = v * e2; + + double det = m11 * m22 - m12 * m12; + lam1 = (rs1 * m22 - rs2 * m12)/det; + lam2 = (m11 * rs2 - m12 * rs1)/det; +} + + + + + +int CalcSphereCenter (const Point<3> ** pts, Point<3> & c) +{ + Vec3d row1 (*pts[0], *pts[1]); + Vec3d row2 (*pts[0], *pts[2]); + Vec3d row3 (*pts[0], *pts[3]); + + Vec3d rhs(0.5 * (row1*row1), + 0.5 * (row2*row2), + 0.5 * (row3*row3)); + Transpose (row1, row2, row3); + + Vec3d sol; + if (SolveLinearSystem (row1, row2, row3, rhs, sol)) + { + (*testout) << "CalcSphereCenter: degenerated" << endl; + return 1; + } + + c = *pts[0] + sol; + return 0; +} + + + + + +int CalcTriangleCenter (const Point3d ** pts, Point3d & c) +{ + static DenseMatrix a(2), inva(2); + static Vector rs(2), sol(2); + double h = Dist(*pts[0], *pts[1]); + + Vec3d v1(*pts[0], *pts[1]); + Vec3d v2(*pts[0], *pts[2]); + + rs(0) = v1 * v1; + rs(1) = v2 * v2; + + a(0,0) = 2 * rs(0); + a(0,1) = a(1,0) = 2 * (v1 * v2); + a(1,1) = 2 * rs(1); + + if (fabs (a.Det()) <= 1e-12 * h * h) + { + (*testout) << "CalcTriangleCenter: degenerated" << endl; + return 1; + } + + CalcInverse (a, inva); + inva.Mult (rs, sol); + + c = *pts[0]; + v1 *= sol(0); + v2 *= sol(1); + + c += v1; + c += v2; + + return 0; +} + + + +double ComputeCylinderRadius (const Point3d & p1, + const Point3d & p2, + const Point3d & p3, + const Point3d & p4) +{ + Vec3d v12(p1, p2); + Vec3d v13(p1, p3); + Vec3d v14(p1, p4); + + Vec3d n1 = Cross (v12, v13); + Vec3d n2 = Cross (v14, v12); + + double n1l = n1.Length(); + double n2l = n2.Length(); + n1 /= n1l; + n2 /= n2l; + + double v12len = v12.Length(); + double h1 = n1l / v12len; + double h2 = n2l / v12len; + + /* + (*testout) << "n1 = " << n1 << " n2 = " << n2 + << "h1 = " << h1 << " h2 = " << h2 << endl; + */ + return ComputeCylinderRadius (n1, n2, h1, h2); +} + + + + +/* + Two triangles T1 and T2 have normals n1 and n2. + The height over the common edge is h1, and h2. + */ +double ComputeCylinderRadius (const Vec3d & n1, const Vec3d & n2, + double h1, double h2) +{ + Vec3d t1, t2; + double n11 = n1 * n1; + double n12 = n1 * n2; + double n22 = n2 * n2; + double det = n11 * n22 - n12 * n12; + + if (fabs (det) < 1e-14 * n11 * n22) + return 1e20; + + // a biorthogonal bases (ti * nj) = delta_ij: + t1 = (n22/det) * n1 + (-n12/det) * n2; + t2 = (-n12/det) * n1 + (n11/det) * n2; + + // normalize: + t1 /= t1.Length(); + t2 /= t2.Length(); + + /* + vector to center point has form + v = lam1 n1 + lam2 n2 + and fulfills + t2 v = h1/2 + t1 v = h2/2 + */ + + double lam1 = 0.5 * h2 / (n1 * t1); + double lam2 = 0.5 * h1 / (n2 * t2); + + double rad = (lam1 * n1 + lam2 * n2).Length(); + /* + (*testout) << "n1 = " << n1 + << " n2 = " << n2 + << " t1 = " << t1 + << " t2 = " << t2 + << " rad = " << rad << endl; + */ + return rad; +} + + + + + + +double MinDistLP2 (const Point2d & lp1, const Point2d & lp2, const Point2d & p) +{ + Vec2d v(lp1, lp2); + Vec2d vlp(lp1, p); + + // dist(lam) = \| vlp \|^2 - 2 lam (v1p, v) + lam^2 \| v \|^2 + + // lam = (v * vlp) / (v * v); + // if (lam < 0) lam = 0; + // if (lam > 1) lam = 1; + + double num = v*vlp; + double den = v*v; + + if (num <= 0) + return Dist2 (lp1, p); + + if (num >= den) + return Dist2 (lp2, p); + + if (den > 0) + { + return vlp.Length2() - num * num /den; + } + else + return vlp.Length2(); +} + + + + +double MinDistLP2 (const Point3d & lp1, const Point3d & lp2, const Point3d & p) +{ + Vec3d v(lp1, lp2); + Vec3d vlp(lp1, p); + + // dist(lam) = \| vlp \|^2 - 2 lam (v1p, v) + lam^2 \| v \|^2 + + // lam = (v * vlp) / (v * v); + // if (lam < 0) lam = 0; + // if (lam > 1) lam = 1; + + double num = v*vlp; + double den = v*v; + + if (num <= 0) + return Dist2 (lp1, p); + + if (num >= den) + return Dist2 (lp2, p); + + if (den > 0) + { + return vlp.Length2() - num * num /den; + } + else + return vlp.Length2(); +} + + + +double MinDistTP2 (const Point3d & tp1, const Point3d & tp2, + const Point3d & tp3, const Point3d & p) +{ + double lam1, lam2; + double res; + + LocalCoordinates (Vec3d (tp1, tp2), Vec3d (tp1, tp3), + Vec3d (tp1, p), lam1, lam2); + int in1 = lam1 >= 0; + int in2 = lam2 >= 0; + int in3 = lam1+lam2 <= 1; + + if (in1 && in2 && in3) + { + Point3d pp = tp1 + lam1 * Vec3d(tp1, tp2) + lam2 * Vec3d (tp1, tp3); + res = Dist2 (p, pp); + } + else + { + res = Dist2 (tp1, p); + if (!in1) + { + double hv = MinDistLP2 (tp1, tp3, p); + if (hv < res) res = hv; + } + if (!in2) + { + double hv = MinDistLP2 (tp1, tp2, p); + if (hv < res) res = hv; + } + if (!in3) + { + double hv = MinDistLP2 (tp2, tp3, p); + if (hv < res) res = hv; + } + /* + double d1 = MinDistLP2 (tp1, tp2, p); + double d2 = MinDistLP2 (tp1, tp3, p); + double d3 = MinDistLP2 (tp2, tp3, p); + res = min3 (d1, d2, d3); + */ + } + + return res; + + Vec3d pp1(tp1, p); + Vec3d v1(tp1, tp2), v2(tp1, tp3); + + double c = pp1.Length2(); + double cx = -2 * (pp1 * v1); + double cy = -2 * (pp1 * v2); + double cxx = v1.Length2(); + double cxy = 2 * (v1 * v2); + double cyy = v2.Length2(); + + QuadraticPolynomial2V pol (-c, -cx, -cy, -cxx, -cxy, -cyy); + double res2 = - pol.MaxUnitTriangle (); + + if (fabs (res - res2) > 1e-8) + cout << "res and res2 differ: " << res << " != " << res2 << endl; + return res2; +} + + +// 0 checks !!! +double MinDistLL2 (const Point3d & l1p1, const Point3d & l1p2, + const Point3d & l2p1, const Point3d & l2p2) +{ + // dist(lam1,lam2) = \| l2p1+lam2v2 - (l1p1+lam1 v1) \| + // min ! + + Vec3d l1l2 (l1p1, l2p1); + Vec3d v1 (l1p1, l1p2); + Vec3d v2 (l2p1, l2p2); + + double a11, a12, a22, rs1, rs2; + double lam1, lam2, det; + + a11 = v1*v1; + a12 = -(v1*v2); + a22 = v2*v2; + rs1 = l1l2 * v1; + rs2 = - (l1l2 * v2); + + det = a11 * a22 - a12 * a12; + if (det < 1e-14 * a11 * a22) + det = 1e-14 * a11 * a22; // regularization should be stable + + if (det < 1e-20) + det = 1e-20; + + + lam1 = (a22 * rs1 - a12 * rs2) / det; + lam2 = (-a12 * rs1 + a11 * rs2) / det; + + if (lam1 >= 0 && lam2 >= 0 && lam1 <= 1 && lam2 <= 1) + { + Vec3d v = l1l2 + (-lam1) * v1 + lam2 * v2; + return v.Length2(); + } + + double minv, hv; + minv = MinDistLP2 (l1p1, l1p2, l2p1); + hv = MinDistLP2 (l1p1, l1p2, l2p2); + if (hv < minv) minv = hv; + + hv = MinDistLP2 (l2p1, l2p2, l1p1); + if (hv < minv) minv = hv; + hv = MinDistLP2 (l2p1, l2p2, l1p2); + if (hv < minv) minv = hv; + + return minv; +} + +} + + diff --git a/libsrc/gprim/geomtest3d.hpp b/libsrc/gprim/geomtest3d.hpp new file mode 100644 index 00000000..05387da0 --- /dev/null +++ b/libsrc/gprim/geomtest3d.hpp @@ -0,0 +1,87 @@ +#ifndef FILE_GEOMTEST3D +#define FILE_GEOMTEST3D + +/* *************************************************************************/ +/* File: geomtest3d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 13. Feb. 98 */ +/* *************************************************************************/ + + +namespace netgen +{ + + +extern int +IntersectTriangleLine (const Point<3> ** tri, const Point<3> ** line); + + + +/** + Returns 0, iff + closure (tet) cup closure (tri) is empty, one corner point of tet, + one edge of tet or one face of tet + */ +extern int +IntersectTetTriangle (const Point<3> ** tet, const Point<3> ** tri, + const int * tetpi = NULL, const int * tripi = NULL); + +/** + Same test as above, but tet int reference position (0, ex, ey, ez), + tetpi = 1, 2, 4, 5 + */ +extern int +IntersectTetTriangleRef (const Point3d ** tri, const int * tripi = NULL); + + +// 1, iff not regular triangulation +extern int +IntersectTriangleTriangle (const Point<3> ** tri1, const Point<3> ** tri2); + + +extern void +LocalCoordinates (const Vec3d & e1, const Vec3d & e2, + const Vec3d & v, double & lam1, double & lam2); + +/// return 1 = degenerated sphere +extern int +CalcSphereCenter (const Point<3> ** pts, Point<3> & c); + +/// return 1 = degenerated triangle +extern int +CalcTriangleCenter (const Point3d ** pts, Point3d & c); + + + +/* + Compute radius of cylinder fitting 4 points. + cylinder axis is in the direction of p1-p2 +*/ +extern double ComputeCylinderRadius (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4); + +/* + Two triangles T1 and T2 have normals n1 and n2. + The height over the common edge is h1, and h2. + Radius of cylinder fitting both triangles +*/ +extern double ComputeCylinderRadius (const Vec3d & n1, const Vec3d & n2, + double h1, double h2); + +/// Minimal distance of point p to the line segment [lp1,lp2] +extern double MinDistLP2 (const Point2d & lp1, const Point2d & lp2, const Point2d & p); + +/// Minimal distance of point p to the line segment [lp1,lp2] +extern double MinDistLP2 (const Point3d & lp1, const Point3d & lp2, const Point3d & p); + +/// Minimal distance of point p to the triangle segment [tp1,tp2,pt3] +extern double MinDistTP2 (const Point3d & tp1, const Point3d & tp2, + const Point3d & tp3, const Point3d & p); + +/// Minimal distance of the 2 lines [l1p1,l1p2] and [l2p1,l2p2] +extern double MinDistLL2 (const Point3d & l1p1, const Point3d & l1p2, + const Point3d & l2p1, const Point3d & l2p2); + +} + +#endif diff --git a/libsrc/gprim/gprim.hpp b/libsrc/gprim/gprim.hpp new file mode 100644 index 00000000..016b1280 --- /dev/null +++ b/libsrc/gprim/gprim.hpp @@ -0,0 +1,33 @@ +#ifndef FILE_GPRIM +#define FILE_GPRIM + +/* *************************************************************************/ +/* File: gprim.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 14. Aug. 97 */ +/* *************************************************************************/ + + +#include +#include + + + + +#include "geomobjects.hpp" +#include "geomops.hpp" +#include "geomfuncs.hpp" + +#include "geom2d.hpp" +#include "geom3d.hpp" + +#include "geomtest3d.hpp" +#include "transform3d.hpp" + +#include "adtree.hpp" + +#include "spline.hpp" +#include "splinegeometry.hpp" + + +#endif diff --git a/libsrc/gprim/spline.cpp b/libsrc/gprim/spline.cpp new file mode 100644 index 00000000..b6789913 --- /dev/null +++ b/libsrc/gprim/spline.cpp @@ -0,0 +1,497 @@ +/* + +Spline curve for Mesh generator + +*/ + +#include +#include +#include +#include "spline.hpp" + +namespace netgen +{ + + // just for testing (JS) + template + void ProjectTrivial (const SplineSeg3 & seg, + const Point point, Point & point_on_curve, double & t) + { + double mindist = -1; + for (int i = 0; i <= 1000; i++) + { + double ht = double(i)/1000; + Point p = seg.GetPoint(ht); + double dist = Dist2 (p, point); + if (i == 0 || dist < mindist) + { + mindist = dist; + t = ht; + } + } + point_on_curve = seg.GetPoint(t); + } + + + template <> + void CircleSeg<3> :: LineIntersections (const double a, const double b, const double c, + Array < Point<3> > & points, const double eps) const + { + cerr << "CircleSeg<3>::LineIntersections not implemented" << endl; + } + + template <> + void CircleSeg<2> :: LineIntersections (const double a, const double b, const double c, + Array < Point<2> > & points, const double eps) const + { + points.SetSize(0); + + double px=0,py=0; + + if(fabs(b) > 1e-20) + py = -c/b; + else + px = -c/a; + + const double c1 = a*a + b*b; + const double c2 = 2. * ( a*(py-pm(1)) - b*(px-pm(0))); + const double c3 = pow(px-pm(0),2) + pow(py-pm(1),2) - pow(Radius(),2); + + const double discr = c2*c2 - 4*c1*c3; + + if(discr < 0) + return; + + Array t; + + if(fabs(discr) < 1e-20) + t.Append(-0.5*c2/c1); + else + { + t.Append((-c2+sqrt(discr))/(2.*c1)); + t.Append((-c2-sqrt(discr))/(2.*c1)); + } + + for(int i=0; i p (px-t[i]*b,py+t[i]*a); + + double angle = atan2(p(1),p(0))+M_PI; + + if(angle > StartAngle()-eps && angle < EndAngle()+eps) + points.Append(p); + } + } + + + + + template + SplineSeg3 :: SplineSeg3 (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3) + : p1(ap1), p2(ap2), p3(ap3) + { + weight = Dist (p1, p3) / sqrt (0.5 * (Dist2 (p1, p2) + Dist2 (p2, p3))); + // weight = sqrt(2); + // cout << "weight = " << weight << endl; + proj_latest_t = 0.5; + } + + template + inline Point SplineSeg3 :: GetPoint (double t) const + { + double x, y, w; + double b1, b2, b3; + + b1 = (1-t)*(1-t); + b2 = weight * t * (1-t); + b3 = t * t; + + x = p1(0) * b1 + p2(0) * b2 + p3(0) * b3; + y = p1(1) * b1 + p2(1) * b2 + p3(1) * b3; + w = b1 + b2 + b3; + + if(D==3) + { + double z = p1(2) * b1 + p2(2) * b2 + p3(2) * b3; + return Point (x/w, y/w, z/w); + } + else + return Point (x/w, y/w); + } + + + + + template + Vec SplineSeg3 :: GetTangent (const double t) const + { + const double b1 = (1.-t)*((weight-2.)*t-weight); + const double b2 = weight*(1.-2.*t); + const double b3 = t*((weight-2)*t+2.); + + + Vec retval; + for(int i=0; i + void SplineSeg3 :: GetCoeff (Vector & u) const + { + DenseMatrix a(6, 6); + DenseMatrix ata(6, 6); + Vector f(6); + + u.SetSize(6); + + // ata.SetSymmetric(1); + + double t = 0; + for (int i = 0; i < 5; i++, t += 0.25) + { + Point p = GetPoint (t); + a(i, 0) = p(0) * p(0); + a(i, 1) = p(1) * p(1); + a(i, 2) = p(0) * p(1); + a(i, 3) = p(0); + a(i, 4) = p(1); + a(i, 5) = 1; + } + a(5, 0) = 1; + + CalcAtA (a, ata); + + u = 0; + u(5) = 1; + a.MultTrans (u, f); + ata.Solve (f, u); + + // the sign + Point p0 = GetPoint(0); + Vec ht = GetTangent(0); + Vec<2> tang(ht(0), ht(1)); + + double gradx = 2.*u(0)*p0(0) + u(2)*p0(1) + u(3); + double grady = 2.*u(1)*p0(1) + u(2)*p0(0) + u(4); + Vec<2> gradn (grady, -gradx); + + if (tang * gradn < 0) u *= -1; + } + + + + + template + void SplineSeg3 :: Project (const Point point, Point & point_on_curve, double & t) const + { + double t_old = -1; + + if(proj_latest_t > 0. && proj_latest_t < 1.) + t = proj_latest_t; + else + t = 0.5; + + Point phi; + Vec phip,phipp,phimp; + + int i=0; + + while(t > -0.5 && t < 1.5 && i<20 && fabs(t-t_old) > 1e-15 ) + { + GetDerivatives(t,phi,phip,phipp); + + t_old = t; + + phimp = phi-point; + + //t = min2(max2(t-(phip*phimp)/(phipp*phimp + phip*phip),0.),1.); + t -= (phip*phimp)/(phipp*phimp + phip*phip); + + i++; + } + + //if(i<10 && t > 0. && t < 1.) + if(i<20 && t > -0.4 && t < 1.4) + { + if(t < 0) + { + t = 0.; + } + if(t > 1) + { + t = 1.; + } + + point_on_curve = SplineSeg3::GetPoint(t); + + double dist = Dist(point,point_on_curve); + + phi = SplineSeg3 ::GetPoint(0); + double auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 0.; + point_on_curve = phi; + dist = auxdist; + } + phi = SplineSeg3 ::GetPoint(1); + auxdist = Dist(phi,point); + if(auxdist < dist) + { + t = 1.; + point_on_curve = phi; + dist = auxdist; + } + } + else + { + double t0 = 0; + double t1 = 0.5; + double t2 = 1.; + + double d0,d1,d2; + + + //(*testout) << "newtonersatz" << endl; + while(t2-t0 > 1e-8) + { + + phi = SplineSeg3 ::GetPoint(t0); d0 = Dist(phi,point); + phi = SplineSeg3 ::GetPoint(t1); d1 = Dist(phi,point); + phi = SplineSeg3 ::GetPoint(t2); d2 = Dist(phi,point); + + double a = (2.*d0 - 4.*d1 +2.*d2)/pow(t2-t0,2); + + if(a <= 0) + { + if(d0 < d2) + t2 -= 0.3*(t2-t0); + else + t0 += 0.3*(t2-t0); + + t1 = 0.5*(t2+t0); + } + else + { + double b = (d1-d0-a*(t1*t1-t0*t0))/(t1-t0); + + double auxt1 = -0.5*b/a; + + if(auxt1 < t0) + { + t2 -= 0.4*(t2-t0); + t0 = max2(0.,t0-0.1*(t2-t0)); + } + else if (auxt1 > t2) + { + t0 += 0.4*(t2-t0); + t2 = min2(1.,t2+0.1*(t2-t0)); + } + else + { + t1 = auxt1; + auxt1 = 0.25*(t2-t0); + t0 = max2(0.,t1-auxt1); + t2 = min2(1.,t1+auxt1); + } + + t1 = 0.5*(t2+t0); + } + + } + + + phi = SplineSeg3 ::GetPoint(t0); d0 = Dist(phi,point); + phi = SplineSeg3 ::GetPoint(t1); d1 = Dist(phi,point); + phi = SplineSeg3 ::GetPoint(t2); d2 = Dist(phi,point); + + double mind = d0; + t = t0; + if(d1 < mind) + { + t = t1; + mind = d1; + } + if(d2 < mind) + { + t = t2; + mind = d2; + } + + point_on_curve = SplineSeg3 ::GetPoint(t); + } + //(*testout) << " latest_t " << proj_latest_t << " t " << t << endl; + + proj_latest_t = t; + + /* + // test it by trivial sampling + double ht; + Point hp; + ProjectTrivial (*this, point, hp, ht); + if (fabs (t-ht) > 1e-3) + { + // if (Dist2 (point, hp) < Dist2 (point, point_on_curve)) + cout << "project is wrong" << endl; + cout << "t = " << t << ", ht = " << ht << endl; + cout << "dist org = " << Dist(point, point_on_curve) << endl; + cout << "dist trivial = " << Dist(point, hp) << endl; + } + */ + } + + + + + + + template + void SplineSeg3 :: GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const + { + Vec v1(p1), v2(p2), v3(p3); + + double b1 = (1.-t)*(1.-t); + double b2 = weight*t*(1.-t); + double b3 = t*t; + double w = b1+b2+b3; + b1 *= 1./w; b2 *= 1./w; b3 *= 1./w; + + double b1p = 2.*(t-1.); + double b2p = weight*(1.-2.*t); + double b3p = 2.*t; + const double wp = b1p+b2p+b3p; + const double fac1 = wp/w; + b1p *= 1./w; b2p *= 1./w; b3p *= 1./w; + + const double b1pp = 2.; + const double b2pp = -2.*weight; + const double b3pp = 2.; + const double wpp = b1pp+b2pp+b3pp; + const double fac2 = (wpp*w-2.*wp*wp)/(w*w); + + for(int i=0; i + double SplineSeg3<2> :: MaxCurvature(void) const + { + Vec<2> v1 = p1-p2; + Vec<2> v2 = p3-p2; + double l1 = v1.Length(); + double l2 = v2.Length(); + + double cosalpha = (v1*v2)/(l1*l2); + + + return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha)); + } + + template<> + double SplineSeg3<3> :: MaxCurvature(void) const + { + Vec<3> v1 = p1-p2; + Vec<3> v2 = p3-p2; + double l1 = v1.Length(); + double l2 = v2.Length(); + + double cosalpha = v1*v2/(l1*l2); + + + return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha)); + } + + + template + void SplineSeg3 :: LineIntersections (const double a, const double b, const double c, + Array < Point > & points, const double eps) const + { + points.SetSize(0); + + double t; + + const double c1 = a*p1(0) - weight*a*p2(0) + a*p3(0) + + b*p1(1) - weight*b*p2(1) + b*p3(1) + + (2.-weight)*c; + const double c2 = -2.*a*p1(0) + weight*a*p2(0) -2.*b*p1(1) + weight*b*p2(1) + (weight-2.)*c; + const double c3 = a*p1(0) + b*p1(1) + c; + + if(fabs(c1) < 1e-20) + { + if(fabs(c2) < 1e-20) + return; + + t = -c3/c2; + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + return; + } + + const double discr = c2*c2-4.*c1*c3; + + if(discr < 0) + return; + + if(fabs(discr/(c1*c1)) < 1e-14) + { + t = -0.5*c2/c1; + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + return; + } + + t = (-c2 + sqrt(discr))/(2.*c1); + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + + t = (-c2 - sqrt(discr))/(2.*c1); + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + } + + + template < int D > + void SplineSeg3 :: GetRawData (Array & data) const + { + data.Append(3); + for(int i=0; i; + template class SplineSeg3<3>; + + + + + + + + +} diff --git a/libsrc/gprim/spline.hpp b/libsrc/gprim/spline.hpp new file mode 100644 index 00000000..10a6f9a1 --- /dev/null +++ b/libsrc/gprim/spline.hpp @@ -0,0 +1,661 @@ +#ifndef FILE_SPLINE_HPP +#define FILE_SPLINE_HPP + +/**************************************************************************/ +/* File: spline.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 24. Jul. 96 */ +/**************************************************************************/ + +namespace netgen +{ + + + + /* + Spline curves for 2D mesh generation + */ + + + /// Geometry point + template < int D > + class GeomPoint : public Point + { + public: + /// refinement factor at point + double refatpoint; + /// max mesh-size at point + double hmax; + /// hp-refinement + bool hpref; + + /// + GeomPoint () { ; } + + /// + GeomPoint (const Point & ap, double aref = 1, bool ahpref=false) + : Point(ap), refatpoint(aref), hmax(1e99), hpref(ahpref) { ; } + }; + + + + + /// base class for 2d - segment + template < int D > + class SplineSeg + { + public: + SplineSeg () { ; } + /// + virtual ~SplineSeg() { ; } + /// calculates length of curve + virtual double Length () const; + /// returns point at curve, 0 <= t <= 1 + virtual Point GetPoint (double t) const = 0; + /// returns a (not necessarily unit-length) tangent vector for 0 <= t <= 1 + virtual Vec GetTangent (const double t) const + { + cerr << "GetTangent not implemented for spline base-class" << endl; + Vec dummy; return dummy; + } + + virtual void GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const + { + double eps = 1e-6; + point = GetPoint (t); + Point pl = GetPoint (t-eps); + Point pr = GetPoint (t+eps); + first = 1.0/(2*eps) * (pr-pl); + second = 1.0/sqr(eps) * ( (pr-point)+(pl-point)); + } + + + /// returns initial point on curve + virtual const GeomPoint & StartPI () const = 0; + /// returns terminal point on curve + virtual const GeomPoint & EndPI () const = 0; + /** writes curve description for fepp: + for implicitly given quadratic curves, the 6 coefficients of + the polynomial + $$ a x^2 + b y^2 + c x y + d x + e y + f = 0 $$ + are written to ost */ + void PrintCoeff (ostream & ost) const; + + virtual void GetCoeff (Vector & coeffs) const = 0; + + virtual void GetPoints (int n, Array > & points) const; + + /** calculates (2D) lineintersections: + for lines $$ a x + b y + c = 0 $$ the interecting points are calculated + and stored in points */ + virtual void LineIntersections (const double a, const double b, const double c, + Array < Point > & points, const double eps) const + {points.SetSize(0);} + + virtual double MaxCurvature(void) const = 0; + + virtual string GetType(void) const {return "splinebase";} + + virtual void Project (const Point point, Point & point_on_curve, double & t) const + { cerr << "Project not implemented for spline base-class" << endl;} + + virtual void GetRawData (Array & data) const + { cerr << "GetRawData not implemented for spline base-class" << endl;} + + }; + + + /// Straight line form p1 to p2 + template< int D > + class LineSeg : public SplineSeg + { + /// + GeomPoint p1, p2; + public: + /// + LineSeg (const GeomPoint & ap1, const GeomPoint & ap2); + /// + virtual double Length () const; + /// + inline virtual Point GetPoint (double t) const; + /// + virtual Vec GetTangent (const double t) const; + + + virtual void GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const; + /// + virtual const GeomPoint & StartPI () const { return p1; }; + /// + virtual const GeomPoint & EndPI () const { return p2; } + /// + virtual void GetCoeff (Vector & coeffs) const; + + virtual string GetType(void) const {return "line";} + + virtual void LineIntersections (const double a, const double b, const double c, + Array < Point > & points, const double eps) const; + + virtual double MaxCurvature(void) const {return 0;} + + virtual void Project (const Point point, Point & point_on_curve, double & t) const; + + virtual void GetRawData (Array & data) const; + }; + + + /// curve given by a rational, quadratic spline (including ellipses) + template< int D > + class SplineSeg3 : public SplineSeg + { + /// + GeomPoint p1, p2, p3; + double weight; + mutable double proj_latest_t; + public: + /// + SplineSeg3 (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3); + /// + inline virtual Point GetPoint (double t) const; + /// + virtual Vec GetTangent (const double t) const; + + + DLL_HEADER virtual void GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const; + /// + virtual const GeomPoint & StartPI () const { return p1; }; + /// + virtual const GeomPoint & EndPI () const { return p3; } + /// + virtual void GetCoeff (Vector & coeffs) const; + + virtual string GetType(void) const {return "spline3";} + + const GeomPoint & TangentPoint (void) const { return p2; } + + DLL_HEADER virtual void LineIntersections (const double a, const double b, const double c, + Array < Point > & points, const double eps) const; + + DLL_HEADER virtual double MaxCurvature(void) const; + + DLL_HEADER virtual void Project (const Point point, Point & point_on_curve, double & t) const; + + DLL_HEADER virtual void GetRawData (Array & data) const; + }; + + + // Gundolf Haase 8/26/97 + /// A circle + template < int D > + class CircleSeg : public SplineSeg + { + /// + private: + GeomPoint p1, p2, p3; + //const GeomPoint &p1, &p2, &p3; + Point pm; + double radius, w1,w3; + public: + /// + CircleSeg (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3); + /// + virtual Point GetPoint (double t) const; + /// + virtual const GeomPoint & StartPI () const { return p1; } + /// + virtual const GeomPoint & EndPI () const { return p3; } + /// + virtual void GetCoeff (Vector & coeffs) const; + /// + double Radius() const { return radius; } + /// + double StartAngle() const { return w1; } + /// + double EndAngle() const { return w3; } + /// + const Point & MidPoint(void) const {return pm; } + + virtual string GetType(void) const {return "circle";} + + virtual void LineIntersections (const double a, const double b, const double c, + Array < Point > & points, const double eps) const; + + virtual double MaxCurvature(void) const {return 1./radius;} + }; + + + + + + + /// + template + class DiscretePointsSeg : public SplineSeg + { + Array > pts; + GeomPoint p1n, p2n; + public: + /// + DiscretePointsSeg (const Array > & apts); + /// + virtual ~DiscretePointsSeg (); + /// + virtual Point GetPoint (double t) const; + /// + virtual const GeomPoint & StartPI () const { return p1n; }; + /// + virtual const GeomPoint & EndPI () const { return p2n; } + /// + virtual void GetCoeff (Vector & coeffs) const {;} + + virtual double MaxCurvature(void) const {return 1;} + }; + + + + + + + // calculates length of spline-curve + template + double SplineSeg :: Length () const + { + int n = 100; + double dt = 1.0 / n; + + Point pold = GetPoint (0); + + double l = 0; + for (int i = 1; i <= n; i++) + { + Point p = GetPoint (i * dt); + l += Dist (p, pold); + pold = p; + } + + return l; + } + + + template + void SplineSeg :: GetPoints (int n, Array > & points) const + { + points.SetSize (n); + if (n >= 2) + for (int i = 0; i < n; i++) + points[i] = GetPoint(double(i) / (n-1)); + } + + + template + void SplineSeg :: PrintCoeff (ostream & ost) const + { + Vector u(6); + + GetCoeff(u); + + for ( int i=0; i<6; i++) + ost << u[i] << " "; + ost << endl; + } + + + + /* + Implementation of line-segment from p1 to p2 + */ + + + template + LineSeg :: LineSeg (const GeomPoint & ap1, + const GeomPoint & ap2) + : p1(ap1), p2(ap2) + { + ; + } + + + template + inline Point LineSeg :: GetPoint (double t) const + { + return p1 + t * (p2 - p1); + } + + template + Vec LineSeg :: GetTangent (const double t) const + { + return p2-p1; + } + + template + void LineSeg :: GetDerivatives (const double t, + Point & point, + Vec & first, + Vec & second) const + { + first = p2 - p1; + point = p1 + t * first; + second = 0; + } + + + template + double LineSeg :: Length () const + { + return Dist (p1, p2); + } + + + template + void LineSeg :: GetCoeff (Vector & coeffs) const + { + coeffs.SetSize(6); + + double dx = p2(0) - p1(0); + double dy = p2(1) - p1(1); + + coeffs[0] = coeffs[1] = coeffs[2] = 0; + coeffs[3] = -dy; + coeffs[4] = dx; + coeffs[5] = -dx * p1(1) + dy * p1(0); + } + + + + template + void LineSeg :: LineIntersections (const double a, const double b, const double c, + Array < Point > & points, const double eps) const + { + points.SetSize(0); + + double denom = -a*p2(0)+a*p1(0)-b*p2(1)+b*p1(1); + if(fabs(denom) < 1e-20) + return; + + double t = (a*p1(0)+b*p1(1)+c)/denom; + if((t > -eps) && (t < 1.+eps)) + points.Append(GetPoint(t)); + } + + + + template + void LineSeg :: Project (const Point point, Point & point_on_curve, double & t) const + { + Vec v = p2-p1; + double l = v.Length(); + v *= 1./l; + t = (point-p1)*v; + + if(t<0) t = 0; + if(t>l) t = l; + + point_on_curve = p1+t*v; + + t *= 1./l; + } + + + template + void LineSeg :: GetRawData (Array & data) const + { + data.Append(2); + for(int i=0; i + double SplineSeg3 :: MaxCurvature(void) const + { + Vec v1 = p1-p2; + Vec v2 = p3-p2; + double l1 = v1.Length(); + double l2 = v2.Length(); + (*testout) << "v1 " << v1 << " v2 " << v2 << endl; + + double cosalpha = v1*v2/(l1*l2); + + (*testout) << "cosalpha " << cosalpha << endl; + + return sqrt(cosalpha + 1.)/(min2(l1,l2)*(1.-cosalpha)); + } + */ + + + + //######################################################################## + // circlesegment + + template + CircleSeg :: CircleSeg (const GeomPoint & ap1, + const GeomPoint & ap2, + const GeomPoint & ap3) + : p1(ap1), p2(ap2), p3(ap3) + { + Vec v1,v2; + + v1 = p1 - p2; + v2 = p3 - p2; + + Point p1t(p1+v1); + Point p2t(p3+v2); + + // works only in 2D!!!!!!!!! + + Line2d g1t,g2t; + + g1t.P1() = Point<2>(p1(0),p1(1)); + g1t.P2() = Point<2>(p1t(0),p1t(1)); + g2t.P1() = Point<2>(p3(0),p3(1)); + g2t.P2() = Point<2>(p2t(0),p2t(1)); + + Point<2> mp = CrossPoint (g1t,g2t); + + pm(0) = mp(0); pm(1) = mp(1); + radius = Dist(pm,StartPI()); + Vec2d auxv; + auxv.X() = p1(0)-pm(0); auxv.Y() = p1(1)-pm(1); + w1 = Angle(auxv); + auxv.X() = p3(0)-pm(0); auxv.Y() = p3(1)-pm(1); + w3 = Angle(auxv); + if ( fabs(w3-w1) > M_PI ) + { + if ( w3>M_PI ) w3 -= 2*M_PI; + if ( w1>M_PI ) w1 -= 2*M_PI; + } + } + + + template + Point CircleSeg :: GetPoint (double t) const + { + if (t >= 1.0) { return p3; } + + double phi = StartAngle() + t*(EndAngle()-StartAngle()); + Vec tmp(cos(phi),sin(phi)); + + return pm + Radius()*tmp; + } + + template + void CircleSeg :: GetCoeff (Vector & coeff) const + { + coeff[0] = coeff[1] = 1.0; + coeff[2] = 0.0; + coeff[3] = -2.0 * pm[0]; + coeff[4] = -2.0 * pm[1]; + coeff[5] = sqr(pm[0]) + sqr(pm[1]) - sqr(Radius()); + } + + + + + + template + DiscretePointsSeg :: DiscretePointsSeg (const Array > & apts) + : pts (apts) + { + for(int i=0; i + DiscretePointsSeg :: ~DiscretePointsSeg () + { ; } + + template + Point DiscretePointsSeg :: GetPoint (double t) const + { + double t1 = t * (pts.Size()-1); + int segnr = int(t1); + if (segnr < 0) segnr = 0; + if (segnr >= pts.Size()) segnr = pts.Size()-1; + + double rest = t1 - segnr; + + return pts[segnr] + rest*Vec(pts[segnr+1]-pts[segnr]); + } + + + + + + + + + + // ************************************* + // Template for B-Splines of order ORDER + // thx to Gerhard Kitzler + // ************************************* + + template + class BSplineSeg : public SplineSeg + { + Array > pts; + GeomPoint p1n, p2n; + Array ti; + + public: + /// + BSplineSeg (const Array > & apts); + /// + virtual ~BSplineSeg(); + /// + virtual Point GetPoint (double t) const; + /// + virtual const GeomPoint & StartPI () const { return p1n; }; + /// + virtual const GeomPoint & EndPI () const { return p2n; } + /// + virtual void GetCoeff (Vector & coeffs) const {;} + + virtual double MaxCurvature(void) const {return 1;} + }; + + // Constructor + template + BSplineSeg :: BSplineSeg (const Array > & apts) + : pts (apts) + { + /* + for(int i=0; i + BSplineSeg :: ~BSplineSeg () + { ; } + + + // GetPoint Method...(evaluation of BSpline Curve) + template + Point BSplineSeg :: GetPoint (double t_in) const + { + int m=pts.Size()+ORDER; + + double t = t_in * (m-2*ORDER+1); + + double b[ORDER]; + + int interval_nr = int(t)+ORDER-1; + if (interval_nr < ORDER-1) interval_nr = ORDER-1; + if (interval_nr > m-ORDER-1) interval_nr = m-ORDER-1; + + b[ORDER-1] = 1.0; + + for(int degree=1;degree p = 0.0; + for(int i=0; i < ORDER; i++) + p += b[i] * Vec (pts[i+interval_nr-ORDER+1]); + return p; + } + + + +} + + +#endif diff --git a/libsrc/gprim/splinegeometry.cpp b/libsrc/gprim/splinegeometry.cpp new file mode 100644 index 00000000..7cb75cb0 --- /dev/null +++ b/libsrc/gprim/splinegeometry.cpp @@ -0,0 +1,134 @@ +/* + +2d Spline curve for Mesh generator + +*/ + + +#include +#include +#include +#include "splinegeometry.hpp" + +namespace netgen +{ + + + template + SplineGeometry :: ~SplineGeometry() + { + for(int i = 0; i < splines.Size(); i++) + delete splines[i]; + } + + + template + void SplineGeometry :: GetRawData (Array & raw_data) const + { + raw_data.Append(D); + // raw_data.Append(elto0); + + raw_data.Append(splines.Size()); + for(int i=0; iGetRawData(raw_data); + } + + + + template + int SplineGeometry :: Load (const Array & raw_data, const int startpos) + { + int pos = startpos; + if(raw_data[pos] != D) + throw NgException("wrong dimension of spline raw_data"); + + pos++; + + // elto0 = raw_data[pos]; pos++; + + splines.SetSize(int(raw_data[pos])); + pos++; + + Array< Point > pts(3); + + for(int i=0; i(GeomPoint(pts[0],1), + GeomPoint(pts[1],1)); + } + else if (type == 3) + { + splines[i] = new SplineSeg3(GeomPoint(pts[0],1), + GeomPoint(pts[1],1), + GeomPoint(pts[2],1)); + } + else + throw NgException("something wrong with spline raw data"); + + } + return pos; + } + + + + + + + + + + template + void SplineGeometry :: GetBoundingBox (Box & box) const + { + if (!splines.Size()) + { + Point auxp = 0.; + box.Set (auxp); + return; + } + + Array > points; + for (int i = 0; i < splines.Size(); i++) + { + splines[i]->GetPoints (20, points); + + if (i == 0) box.Set(points[0]); + for (int j = 0; j < points.Size(); j++) + box.Add (points[j]); + } + } + + /* + template + void SplineGeometry :: SetGrading (const double grading) + { + elto0 = grading; + } + */ + + template + void SplineGeometry :: AppendPoint (const Point & p, const double reffac, const bool hpref) + { + geompoints.Append (GeomPoint(p, reffac)); + geompoints.Last().hpref = hpref; + } + + + + template class SplineGeometry<2>; + template class SplineGeometry<3>; +} + + diff --git a/libsrc/gprim/splinegeometry.hpp b/libsrc/gprim/splinegeometry.hpp new file mode 100644 index 00000000..d29adbc4 --- /dev/null +++ b/libsrc/gprim/splinegeometry.hpp @@ -0,0 +1,68 @@ +/* + + +JS, Nov 2007 + + +The 2D/3D template-base classes should go into the libsrc/gprim directory + +in geom2d only 2D - Geometry classes (with material properties etc.) + + +*/ + +#include "spline.hpp" + + +#ifndef _FILE_SPLINEGEOMETRY +#define _FILE_SPLINEGEOMETRY + +namespace netgen +{ + + + template < int D > + class SplineGeometry + { + // protected: + public: + Array < GeomPoint > geompoints; + Array < SplineSeg* > splines; + + DLL_HEADER ~SplineGeometry(); + + DLL_HEADER int Load (const Array & raw_data, const int startpos = 0); + + DLL_HEADER void GetRawData (Array & raw_data) const; + + + const Array*> & GetSplines () const + { return splines; } + + int GetNSplines (void) const { return splines.Size(); } + string GetSplineType (const int i) const { return splines[i]->GetType(); } + SplineSeg & GetSpline (const int i) {return *splines[i];} + const SplineSeg & GetSpline (const int i) const {return *splines[i];} + + DLL_HEADER void GetBoundingBox (Box & box) const; + Box GetBoundingBox () const + { Box box; GetBoundingBox (box); return box; } + + int GetNP () const { return geompoints.Size(); } + const GeomPoint & GetPoint(int i) const { return geompoints[i]; } + + // void SetGrading (const double grading); + DLL_HEADER void AppendPoint (const Point & p, const double reffac = 1., const bool hpref = false); + + + void AppendSegment(SplineSeg * spline) + { + splines.Append (spline); + } + }; + + + +} + +#endif // _FILE_SPLINEGEOMETRY diff --git a/libsrc/gprim/transform3d.cpp b/libsrc/gprim/transform3d.cpp new file mode 100644 index 00000000..dcc4cef1 --- /dev/null +++ b/libsrc/gprim/transform3d.cpp @@ -0,0 +1,165 @@ +#include + +#include +#include +#include + +namespace netgen +{ + +Transformation3d :: Transformation3d () +{ + for (int i = 0; i < 3; i++) + { + offset[i] = 0; + for (int j = 0; j < 3; j++) + lin[i][j] = 0; + } +} + +Transformation3d :: Transformation3d (const Vec3d & translate) +{ + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + lin[i][j] = 0; + for (int i = 0; i < 3; i++) + { + offset[i] = translate.X(i+1); + lin[i][i] = 1; + } +} + + +Transformation3d :: +Transformation3d (const Point3d & c, double alpha, + double beta, double gamma) +{ + // total = T_c x Rot_0 x T_c^{-1} + // Use Euler angles, see many books from tech mech, e.g. + // Shabana "multibody systems" + + Transformation3d tc(c); + Transformation3d tcinv; + tc.CalcInverse (tcinv); + + Transformation3d r1, r2, r3, ht, ht2; + r1.SetAxisRotation (3, alpha); + r2.SetAxisRotation (1, beta); + r3.SetAxisRotation (3, gamma); + + ht.Combine (tc, r3); + ht2.Combine (ht, r2); + ht.Combine (ht2, r1); + Combine (ht, tcinv); + + // cout << "Rotation - Transformation:" << (*this) << endl; + // (*testout) << "Rotation - Transformation:" << (*this) << endl; +} + + + + +Transformation3d :: Transformation3d (const Point3d ** pp) +{ + for (int i = 1; i <= 3; i++) + { + offset[i-1] = (*pp[0]).X(i); + for (int j = 1; j <= 3; j++) + lin[i-1][j-1] = (*pp[j]).X(i) - (*pp[0]).X(i); + } +} + +Transformation3d :: Transformation3d (const Point3d pp[]) +{ + for (int i = 1; i <= 3; i++) + { + offset[i-1] = pp[0].X(i); + for (int j = 1; j <= 3; j++) + lin[i-1][j-1] = pp[j].X(i) - pp[0].X(i); + } +} + + +void Transformation3d :: CalcInverse (Transformation3d & inv) const +{ + static DenseMatrix a(3), inva(3); + static Vector b(3), sol(3); + + for (int i = 0; i < 3; i++) + { + b(i) = offset[i]; + for (int j = 0; j < 3; j++) + a(i, j) = lin[i][j]; + } + + ::netgen::CalcInverse (a, inva); + inva.Mult (b, sol); + + for (int i = 0; i < 3; i++) + { + inv.offset[i] = -sol(i); + for (int j = 0; j < 3; j++) + inv.lin[i][j] = inva(i, j); + } +} + + +void Transformation3d:: +Combine (const Transformation3d & ta, const Transformation3d & tb) +{ + // o = o_a+ m_a o_b + // m = m_a m_b + + for (int i = 0; i <= 2; i++) + { + offset[i] = ta.offset[i]; + for (int j = 0; j <= 2; j++) + offset[i] += ta.lin[i][j] * tb.offset[j]; + } + + for (int i = 0; i <= 2; i++) + for (int j = 0; j <= 2; j++) + { + lin[i][j] = 0; + for (int k = 0; k <= 2; k++) + lin[i][j] += ta.lin[i][k] * tb.lin[k][j]; + } +} +void Transformation3d :: SetAxisRotation (int dir, double alpha) +{ + double co = cos(alpha); + double si = sin(alpha); + dir--; + int pos1 = (dir+1) % 3; + int pos2 = (dir+2) % 3; + + int i, j; + for (i = 0; i <= 2; i++) + { + offset[i] = 0; + for (j = 0; j <= 2; j++) + lin[i][j] = 0; + } + + lin[dir][dir] = 1; + lin[pos1][pos1] = co; + lin[pos2][pos2] = co; + lin[pos1][pos2] = si; + lin[pos2][pos1] = -si; +} + +ostream & operator<< (ostream & ost, Transformation3d & trans) +{ + ost << "offset = "; + for (int i = 0; i <= 2; i++) + ost << trans.offset[i] << " "; + ost << endl << "linear = " << endl; + for (int i = 0; i <= 2; i++) + { + for (int j = 0; j <= 2; j++) + ost << trans.lin[i][j] << " "; + ost << endl; + } + return ost; +} +} diff --git a/libsrc/gprim/transform3d.hpp b/libsrc/gprim/transform3d.hpp new file mode 100644 index 00000000..cd412433 --- /dev/null +++ b/libsrc/gprim/transform3d.hpp @@ -0,0 +1,193 @@ +#ifndef FILE_TRANSFORM3D +#define FILE_TRANSFORM3D + +/* *************************************************************************/ +/* File: transform3d.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 22. Mar. 98 */ +/* *************************************************************************/ + +/* + Affine - Linear mapping in 3D space + */ + +namespace netgen +{ + +class Transformation3d; +ostream & operator<< (ostream & ost, Transformation3d & trans); + +class Transformation3d +{ + double lin[3][3]; + double offset[3]; +public: + /// + Transformation3d (); + /// Unit tet is mapped to tet descibed by pp + Transformation3d (const Point3d ** pp); + /// Unit tet is mapped to tet descibed by pp + Transformation3d (const Point3d pp[]); + /// translation + Transformation3d (const Vec3d & translate); + /// rotation with ... + Transformation3d (const Point3d & c, double alpha, double beta, double gamma); + /// + void CalcInverse (Transformation3d & inv) const; + /// this = ta x tb + void Combine (const Transformation3d & ta, const Transformation3d & tb); + /// dir = 1..3 (== x..z) + void SetAxisRotation (int dir, double alpha); + /// + void Transform (const Point3d & from, Point3d & to) const + { + for (int i = 1; i <= 3; i++) + { + to.X(i) = offset[i-1] + lin[i-1][0] * from.X(1) + + lin[i-1][1] * from.X(2) + lin[i-1][2] * from.X(3); + } + } + + /// + void Transform (Point3d & p) const + { + Point3d hp; + Transform (p, hp); + p = hp; + } + + /// transform vector, apply only linear part, not offset + void Transform (const Vec3d & from, Vec3d & to) const + { + for (int i = 1; i <= 3; i++) + { + to.X(i) = lin[i-1][0] * from.X(1) + + lin[i-1][1] * from.X(2) + lin[i-1][2] * from.X(3); + } + } + friend ostream & operator<< (ostream & ost, Transformation3d & trans); +}; + + + + + + + + + + + + + + +template +class Transformation +{ + Mat m; + Vec v; +public: + /// + Transformation () { m = 0; v = 0; } + + /// Unit tet is mapped to tet descibed by pp + Transformation (const Point * pp); + + /// translation + Transformation (const Vec & translate) + { + v = translate; + m = 0; + for (int i = 0; i < D; i++) + m(i,i) = 1; + } + + // rotation with ... + Transformation (const Point & c, double alpha, double beta, double gamma) + { + // total = T_c x Rot_0 x T_c^{-1} + // Use Euler angles, see many books from tech mech, e.g. + // Shabana "multibody systems" + + Vec vc(c); + Transformation tc(vc); + Transformation tcinv(-vc); + // tc.CalcInverse (tcinv); + + Transformation r1, r2, r3, ht, ht2; + r1.SetAxisRotation (3, alpha); + r2.SetAxisRotation (1, beta); + r3.SetAxisRotation (3, gamma); + + ht.Combine (tc, r3); + ht2.Combine (ht, r2); + ht.Combine (ht2, r1); + Combine (ht, tcinv); + + // cout << "Rotation - Transformation:" << (*this) << endl; + // (*testout) << "Rotation - Transformation:" << (*this) << endl; + } + + /// + void CalcInverse (Transformation & inv) const; + + /// this = ta x tb + void Combine (const Transformation & ta, const Transformation & tb) + { + v = ta.v + ta.m * tb.v; + m = ta.m * tb.m; + } + + + + /// dir = 1..3 (== x..z) + void SetAxisRotation (int dir, double alpha) + { + double co = cos(alpha); + double si = sin(alpha); + dir--; + int pos1 = (dir+1) % 3; + int pos2 = (dir+2) % 3; + + int i, j; + for (i = 0; i <= 2; i++) + { + v(i) = 0; + for (j = 0; j <= 2; j++) + m(i,j) = 0; + } + + m(dir,dir) = 1; + m(pos1, pos1) = co; + m(pos2, pos2) = co; + m(pos1, pos2) = si; + m(pos2, pos1) = -si; + } + + /// + void Transform (const Point & from, Point & to) const + { + to = Point (v + m * Vec(from)); + } + + void Transform (Point & p) const + { + p = Point (v + m * Vec(p)); + } + + + + /// transform vector, apply only linear part, not offset + void Transform (const Vec & from, Vec & to) const + { + to = m * from; + } +}; + +template +ostream & operator<< (ostream & ost, Transformation & trans); + + +} + +#endif diff --git a/libsrc/include/Makefile.am b/libsrc/include/Makefile.am new file mode 100644 index 00000000..f84db193 --- /dev/null +++ b/libsrc/include/Makefile.am @@ -0,0 +1,8 @@ +noinst_HEADERS = acisgeom.hpp gprim.hpp meshing.hpp occgeom.hpp \ +visual.hpp csg.hpp incvis.hpp myadt.hpp opti.hpp geometry2d.hpp \ +linalg.hpp mydefs.hpp parallel.hpp stlgeom.hpp mystdlib.h + +include_HEADERS = nginterface.h nginterface_v2.hpp + +AM_CPPFLAGS = +METASOURCES = AUTO diff --git a/libsrc/include/Makefile.in b/libsrc/include/Makefile.in new file mode 100644 index 00000000..bc1bce84 --- /dev/null +++ b/libsrc/include/Makefile.in @@ -0,0 +1,523 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc/include +DIST_COMMON = $(include_HEADERS) $(noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = acisgeom.hpp gprim.hpp meshing.hpp occgeom.hpp \ +visual.hpp csg.hpp incvis.hpp myadt.hpp opti.hpp geometry2d.hpp \ +linalg.hpp mydefs.hpp parallel.hpp stlgeom.hpp mystdlib.h + +include_HEADERS = nginterface.h nginterface_v2.hpp +AM_CPPFLAGS = +METASOURCES = AUTO +all: all-am + +.SUFFIXES: +$(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) --foreign libsrc/include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/include/Makefile +.PRECIOUS: 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): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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 mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +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 -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool ctags distclean 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-includeHEADERS 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-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags uninstall uninstall-am uninstall-includeHEADERS + + +# 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/libsrc/include/acisgeom.hpp b/libsrc/include/acisgeom.hpp new file mode 100644 index 00000000..491b7720 --- /dev/null +++ b/libsrc/include/acisgeom.hpp @@ -0,0 +1,3 @@ +#ifdef ACIS +#include "../acisgeom/acisgeom.hpp" +#endif diff --git a/libsrc/include/csg.hpp b/libsrc/include/csg.hpp new file mode 100644 index 00000000..ffd45ef0 --- /dev/null +++ b/libsrc/include/csg.hpp @@ -0,0 +1 @@ +#include "../csg/csg.hpp" diff --git a/libsrc/include/geometry2d.hpp b/libsrc/include/geometry2d.hpp new file mode 100644 index 00000000..bf0965c2 --- /dev/null +++ b/libsrc/include/geometry2d.hpp @@ -0,0 +1 @@ +#include "../geom2d/geometry2d.hpp" diff --git a/libsrc/include/gprim.hpp b/libsrc/include/gprim.hpp new file mode 100644 index 00000000..1e827aaf --- /dev/null +++ b/libsrc/include/gprim.hpp @@ -0,0 +1 @@ +#include "../gprim/gprim.hpp" diff --git a/libsrc/include/incvis.hpp b/libsrc/include/incvis.hpp new file mode 100644 index 00000000..b95005db --- /dev/null +++ b/libsrc/include/incvis.hpp @@ -0,0 +1,40 @@ +// libraries for User interface: + +#include +#include + +#if TK_MAJOR_VERSION==8 && TK_MINOR_VERSION>=4 +#define tcl_const const +#else +#define tcl_const +#endif + +#define GL_GLEXT_PROTOTYPES + + +# if defined(TOGL_AGL) || defined(TOGL_AGL_CLASSIC) +# include +# include +# else +# include +# include +# endif + + +#ifdef TOGL_X11 +// parallel +#define GLX_GLXEXT_PROTOTYPES +#include +#include +#endif + + + +// part of OpenGL 1.2, but not in Microsoft's OpenGL 1.1 header: +// GL version sould be checked at runtime +#ifndef GL_CLAMP_TO_EDGE +#define GL_CLAMP_TO_EDGE 0x812F +#endif + + + diff --git a/libsrc/include/linalg.hpp b/libsrc/include/linalg.hpp new file mode 100644 index 00000000..e96bd036 --- /dev/null +++ b/libsrc/include/linalg.hpp @@ -0,0 +1 @@ +#include "../linalg/linalg.hpp" diff --git a/libsrc/include/meshing.hpp b/libsrc/include/meshing.hpp new file mode 100644 index 00000000..e41a88f9 --- /dev/null +++ b/libsrc/include/meshing.hpp @@ -0,0 +1 @@ +#include <../meshing/meshing.hpp> diff --git a/libsrc/include/myadt.hpp b/libsrc/include/myadt.hpp new file mode 100644 index 00000000..d36bef05 --- /dev/null +++ b/libsrc/include/myadt.hpp @@ -0,0 +1 @@ +#include <../general/myadt.hpp> diff --git a/libsrc/include/mydefs.hpp b/libsrc/include/mydefs.hpp new file mode 100644 index 00000000..e72f6a79 --- /dev/null +++ b/libsrc/include/mydefs.hpp @@ -0,0 +1,49 @@ +#ifndef FILE_MYDEFS +#define FILE_MYDEFS + +/**************************************************************************/ +/* File: mydefs.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 10. Mar. 98 */ +/**************************************************************************/ + +/* + defines for graphics, testmodes, ... +*/ + + +// #define DEBUG + +// Philippose - 31/01/2009 +// Hack for the Windows Version +// in Linux, "PACKAGE_VERSION" is replaced +// in the configure/make phases, with the +// right version number +#ifdef WIN32 +#define PACKAGE_VERSION "5.2-alpha" +#endif + + +#ifdef WIN32 + #if NGINTERFACE_EXPORTS || NGLIB_EXPORTS || nglib_EXPORTS + #define DLL_HEADER __declspec(dllexport) + #else + #define DLL_HEADER __declspec(dllimport) + #endif +#else + #define DLL_HEADER +#endif + + +#define noDEMOVERSION +#define noDEVELOP +#define noSTEP +#define noSOLIDGEOM + +#define noDEMOAPP +#define noMODELLER + +#define noSTAT_STREAM +#define noLOG_STREAM + +#endif diff --git a/libsrc/include/mystdlib.h b/libsrc/include/mystdlib.h new file mode 100644 index 00000000..cb3bd672 --- /dev/null +++ b/libsrc/include/mystdlib.h @@ -0,0 +1,89 @@ +#ifndef FILE_MYSTDLIB +#define FILE_MYSTDLIB + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#ifdef PARALLEL +// #undef SEEK_SET +// #undef SEEK_CUR +// #undef SEEK_END +#include +#include // for usleep (only for parallel) +#endif + +#ifdef _OPENMP +#include +#endif + + +/* +#ifdef METIS +namespace metis { extern "C" { +#include +} } +#endif +*/ + + +#ifndef NO_PARALLEL_THREADS +#ifndef WIN32 +#include +#endif +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + + +/*** Windows headers ***/ +#ifdef _MSC_VER +# define WIN32_LEAN_AND_MEAN +# ifndef NO_PARALLEL_THREADS +# ifdef MSVC_EXPRESS +# include +# else +# include +# include +# endif // MSVC_EXPRESS +# endif +# include +# undef WIN32_LEAN_AND_MEAN +# include + +#else // Not using MC VC++ + +# ifndef NO_PARALLEL_THREADS +# include +# endif + +#endif + + +using namespace std; + +#endif + diff --git a/libsrc/include/nginterface.h b/libsrc/include/nginterface.h new file mode 100644 index 00000000..08096f3a --- /dev/null +++ b/libsrc/include/nginterface.h @@ -0,0 +1,473 @@ +#ifndef NGINTERFACE +#define NGINTERFACE + + + + + +/**************************************************************************/ +/* File: nginterface.h */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Nov. 99 */ +/**************************************************************************/ + +/* + Application program interface to Netgen + +*/ + +#ifdef WIN32 + #if NGINTERFACE_EXPORTS || NGLIB_EXPORTS || nglib_EXPORTS + #define DLL_HEADER __declspec(dllexport) + #else + #define DLL_HEADER __declspec(dllimport) + #endif +#else + #define DLL_HEADER +#endif + + +// max number of nodes per element +#define NG_ELEMENT_MAXPOINTS 12 + +// max number of nodes per surface element +#define NG_SURFACE_ELEMENT_MAXPOINTS 8 + + + +// implemented element types: +enum NG_ELEMENT_TYPE { + NG_PNT = 0, + NG_SEGM = 1, NG_SEGM3 = 2, + NG_TRIG = 10, NG_QUAD=11, NG_TRIG6 = 12, NG_QUAD6 = 13, + NG_TET = 20, NG_TET10 = 21, + NG_PYRAMID = 22, NG_PRISM = 23, NG_PRISM12 = 24, + NG_HEX = 25 +}; + +typedef double NG_POINT[3]; // coordinates +typedef int NG_EDGE[2]; // initial point, end point +typedef int NG_FACE[4]; // points, last one is 0 for trig + + +#ifdef __cplusplus +extern "C" { +#endif + + // load geomtry from file + DLL_HEADER void Ng_LoadGeometry (const char * filename); + + // load netgen mesh + DLL_HEADER void Ng_LoadMesh (const char * filename); + + // load netgen mesh + DLL_HEADER void Ng_LoadMeshFromString (const char * mesh_as_string); + + // space dimension (2 or 3) + DLL_HEADER int Ng_GetDimension (); + + // number of mesh points + DLL_HEADER int Ng_GetNP (); + + // number of mesh vertices (differs from GetNP for 2nd order elements) + DLL_HEADER int Ng_GetNV (); + + // number of mesh elements + DLL_HEADER int Ng_GetNE (); + + // number of surface triangles + DLL_HEADER int Ng_GetNSE (); + + // Get Point coordintes, index from 1 .. np + DLL_HEADER void Ng_GetPoint (int pi, double * p); + + // Get Element Points + DLL_HEADER NG_ELEMENT_TYPE Ng_GetElement (int ei, int * epi, int * np = 0); + + // Get Element Type + DLL_HEADER NG_ELEMENT_TYPE Ng_GetElementType (int ei); + + // Get sub-domain of element ei + DLL_HEADER int Ng_GetElementIndex (int ei); + + DLL_HEADER void Ng_SetElementIndex(const int ei, const int index); + + // Get Material of element ei + DLL_HEADER char * Ng_GetElementMaterial (int ei); + + // Get Material of domain dom + DLL_HEADER char * Ng_GetDomainMaterial (int dom); + + // Get User Data + DLL_HEADER int Ng_GetUserDataSize (char * id); + DLL_HEADER void Ng_GetUserData (char * id, double * data); + + // Get Surface Element Points + DLL_HEADER NG_ELEMENT_TYPE Ng_GetSurfaceElement (int ei, int * epi, int * np = 0); + + // Get Surface Element Type + DLL_HEADER NG_ELEMENT_TYPE Ng_GetSurfaceElementType (int ei); + + // Get Surface Element Index + DLL_HEADER int Ng_GetSurfaceElementIndex (int ei); + + // Get Surface Element Surface Number + DLL_HEADER int Ng_GetSurfaceElementSurfaceNumber (int ei); + + // Get Surface Element Number + DLL_HEADER int Ng_GetSurfaceElementFDNumber (int ei); + + // Get BCName for Surface Element + DLL_HEADER char * Ng_GetSurfaceElementBCName (int ei); + //void Ng_GetSurfaceElementBCName (int ei, char * name); + + // Get BCName for bc-number + DLL_HEADER char * Ng_GetBCNumBCName (int bcnr); + //void Ng_GetBCNumBCName (int bcnr, char * name); + + // Get normal vector of surface element node + DLL_HEADER void Ng_GetNormalVector (int sei, int locpi, double * nv); + + + DLL_HEADER void Ng_SetPointSearchStartElement(int el); + + // Find element of point, returns local coordinates + DLL_HEADER int Ng_FindElementOfPoint (double * p, double * lami, + int build_searchtrees = 0, + const int * const indices = NULL, const int numind = 0); + + // Find surface element of point, returns local coordinates + DLL_HEADER int Ng_FindSurfaceElementOfPoint (double * p, double * lami, + int build_searchtrees = 0, + const int * const indices = NULL, const int numind = 0); + + + // is elment ei curved ? + DLL_HEADER int Ng_IsElementCurved (int ei); + // is elment sei curved ? + DLL_HEADER int Ng_IsSurfaceElementCurved (int sei); + + /// Curved Elemens: + /// xi..local coordinates + /// x ..global coordinates + /// dxdxi...D x D Jacobian matrix (row major storage) + DLL_HEADER void Ng_GetElementTransformation (int ei, const double * xi, + double * x, double * dxdxi); + + + /// buffer must be at least 100 doubles, alignment of double + DLL_HEADER void Ng_GetBufferedElementTransformation (int ei, const double * xi, + double * x, double * dxdxi, + void * buffer, int buffervalid); + + + + /// Curved Elemens: + /// xi..local coordinates + /// x ..global coordinates + /// dxdxi...D x D-1 Jacobian matrix (row major storage) + /// curved ...is element curved ? + DLL_HEADER void Ng_GetSurfaceElementTransformation (int sei, const double * xi, + double * x, double * dxdxi); + + /// Curved Elemens: + /// xi..local coordinates + /// sxi..step xi + /// x ..global coordinates + /// dxdxi...D x D Jacobian matrix (row major storage) + DLL_HEADER void Ng_GetMultiElementTransformation (int ei, int n, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + + + DLL_HEADER int Ng_GetSegmentIndex (int elnr); + DLL_HEADER NG_ELEMENT_TYPE Ng_GetSegment (int elnr, int * epi, int * np = 0); + + + + + // Mark element for refinement + DLL_HEADER void Ng_SetRefinementFlag (int ei, int flag); + DLL_HEADER void Ng_SetSurfaceRefinementFlag (int sei, int flag); + + // Do local refinement + enum NG_REFINEMENT_TYPE { NG_REFINE_H = 0, NG_REFINE_P = 1, NG_REFINE_HP = 2 }; + DLL_HEADER void Ng_Refine (NG_REFINEMENT_TYPE reftype); + + // Use second order elements + DLL_HEADER void Ng_SecondOrder (); + DLL_HEADER void Ng_HighOrder (int order, bool rational = false); + //void Ng_HPRefinement (int levels, double parameter = 0.125); + DLL_HEADER void Ng_HPRefinement (int levels, double parameter = 0.125, + bool setorders = true,bool ref_level = false); + // void Ng_HPRefinement (int levels); + // void Ng_HPRefinement (int levels, double parameter); + + + // Topology and coordinate information of master element: + + DLL_HEADER int Ng_ME_GetNVertices (NG_ELEMENT_TYPE et); + DLL_HEADER int Ng_ME_GetNEdges (NG_ELEMENT_TYPE et); + DLL_HEADER int Ng_ME_GetNFaces (NG_ELEMENT_TYPE et); + + DLL_HEADER const NG_POINT * Ng_ME_GetVertices (NG_ELEMENT_TYPE et); + DLL_HEADER const NG_EDGE * Ng_ME_GetEdges (NG_ELEMENT_TYPE et); + DLL_HEADER const NG_FACE * Ng_ME_GetFaces (NG_ELEMENT_TYPE et); + + DLL_HEADER void Ng_UpdateTopology(); + + DLL_HEADER int Ng_GetNEdges(); + DLL_HEADER int Ng_GetNFaces(); + + + DLL_HEADER int Ng_GetElement_Edges (int elnr, int * edges, int * orient = 0); + DLL_HEADER int Ng_GetElement_Faces (int elnr, int * faces, int * orient = 0); + + DLL_HEADER int Ng_GetSurfaceElement_Edges (int selnr, int * edges, int * orient = 0); + DLL_HEADER int Ng_GetSurfaceElement_Face (int selnr, int * orient = 0); + + DLL_HEADER void Ng_GetSurfaceElementNeighbouringDomains(const int selnr, int & in, int & out); + + DLL_HEADER int Ng_GetFace_Vertices (int fnr, int * vert); + DLL_HEADER void Ng_GetEdge_Vertices (int ednr, int * vert); + DLL_HEADER int Ng_GetFace_Edges (int fnr, int * edge); + + DLL_HEADER int Ng_GetNVertexElements (int vnr); + DLL_HEADER void Ng_GetVertexElements (int vnr, int * els); + + DLL_HEADER int Ng_GetElementOrder (int enr); + DLL_HEADER void Ng_GetElementOrders (int enr, int * ox, int * oy, int * oz); + + DLL_HEADER void Ng_SetElementOrder (int enr, int order); + DLL_HEADER void Ng_SetElementOrders (int enr, int ox, int oy, int oz); + + DLL_HEADER int Ng_GetSurfaceElementOrder (int enr); + DLL_HEADER void Ng_GetSurfaceElementOrders (int enr, int * ox, int * oy); + + DLL_HEADER void Ng_SetSurfaceElementOrder (int enr, int order); + DLL_HEADER void Ng_SetSurfaceElementOrders (int enr, int ox, int oy); + + // Multilevel functions: + + // number of levels: + DLL_HEADER int Ng_GetNLevels (); + // get two parent nodes (indeed vertices !) of node ni + DLL_HEADER void Ng_GetParentNodes (int ni, int * parents); + + // get parent element (first child has always same number) + DLL_HEADER int Ng_GetParentElement (int ei); + + // get parent surface element (first child has always same number) + DLL_HEADER int Ng_GetParentSElement (int ei); + + // representant of anisotropic cluster + DLL_HEADER int Ng_GetClusterRepVertex (int vi); + DLL_HEADER int Ng_GetClusterRepEdge (int edi); + DLL_HEADER int Ng_GetClusterRepFace (int fai); + DLL_HEADER int Ng_GetClusterRepElement (int eli); + + + void Ng_SurfaceElementTransformation (int eli, double x, double y, + double * p3d, double * jacobian); + +#ifdef PARALLEL + + // the folling functions are 0-base !! + + // number on distant processor + // returns pairs (dist_proc, num_on_dist_proc) + int NgPar_GetDistantNodeNums ( int nodetype, int locnum, int * pnums ); + int NgPar_GetNDistantNodeNums ( int nodetype, int locnum ); + + int NgPar_GetGlobalNodeNum (int nodetype, int locnum); + +#endif + + namespace netgen { + // #include "../visualization/soldata.hpp" + class SolutionData; + class MouseEventHandler; + } + + enum Ng_SolutionType + { NG_SOLUTION_NODAL = 1, + NG_SOLUTION_ELEMENT = 2, + NG_SOLUTION_SURFACE_ELEMENT = 3, + NG_SOLUTION_NONCONTINUOUS = 4, + NG_SOLUTION_SURFACE_NONCONTINUOUS = 5, + NG_SOLUTION_VIRTUAL_FUNCTION = 6, + NG_SOLUTION_MARKED_ELEMENTS = 10, + NG_SOLUTION_ELEMENT_ORDER = 11 + }; + + struct Ng_SolutionData + { + const char * name; // name of gridfunction + double * data; // solution values + int components; // relevant (double) components in solution vector + int dist; // # doubles per entry alignment! + int iscomplex; // complex vector ? + bool draw_surface; + bool draw_volume; + int order; // order of elements, only partially supported + Ng_SolutionType soltype; // type of solution function + netgen::SolutionData * solclass; + }; + + // initialize solution data with default arguments + DLL_HEADER void Ng_InitSolutionData (Ng_SolutionData * soldata); + // set solution data + DLL_HEADER void Ng_SetSolutionData (Ng_SolutionData * soldata); + /// delete gridfunctions + DLL_HEADER void Ng_ClearSolutionData(); + // redraw + DLL_HEADER void Ng_Redraw(); + /// + DLL_HEADER void Ng_SetMouseEventHandler (netgen::MouseEventHandler * handler); + // + DLL_HEADER void Ng_SetVisualizationParameter (const char * name, + const char * value); + + + // number of periodic vertices + DLL_HEADER int Ng_GetNPeriodicVertices (int idnr); + // pairs should be an integer array of 2*npairs + DLL_HEADER void Ng_GetPeriodicVertices (int idnr, int * pairs); + + // number of periodic edges + DLL_HEADER int Ng_GetNPeriodicEdges (int idnr); + // pairs should be an integer array of 2*npairs + DLL_HEADER void Ng_GetPeriodicEdges (int idnr, int * pairs); + + DLL_HEADER void RunParallel ( void * (*fun)(void *), void * in); + + DLL_HEADER void Ng_PushStatus (const char * str); + DLL_HEADER void Ng_PopStatus (); + DLL_HEADER void Ng_SetThreadPercentage (double percent); + DLL_HEADER void Ng_GetStatus (char ** str, double & percent); + + DLL_HEADER void Ng_SetTerminate(void); + DLL_HEADER void Ng_UnSetTerminate(void); + DLL_HEADER int Ng_ShouldTerminate(void); + DLL_HEADER void Ng_SetRunning(int flag); + DLL_HEADER int Ng_IsRunning(); + + //// added by Roman Stainko .... + DLL_HEADER int Ng_GetVertex_Elements( int vnr, int* elems); + DLL_HEADER int Ng_GetVertex_SurfaceElements( int vnr, int* elems ); + DLL_HEADER int Ng_GetVertex_NElements( int vnr ); + DLL_HEADER int Ng_GetVertex_NSurfaceElements( int vnr ); + + +#ifdef SOCKETS + int Ng_SocketClientOpen( const int port, const char * host ); + void Ng_SocketClientWrite( const char * write, char ** reply); + void Ng_SocketClientClose ( void ); + void Ng_SocketClientGetServerHost ( const int number, char ** host ); + void Ng_SocketClientGetServerPort ( const int number, int * port ); + void Ng_SocketClientGetServerClientID ( const int number, int * id ); +#endif + + DLL_HEADER void Ng_InitPointCurve(double red, double green, double blue); + DLL_HEADER void Ng_AddPointCurvePoint(const double * point); + + +#ifdef PARALLEL + void Ng_SetElementPartition ( int elnr, int part ); + int Ng_GetElementPartition ( int elnr ); +#endif + + DLL_HEADER void Ng_SaveMesh ( const char * meshfile ); + DLL_HEADER void Ng_Bisect ( const char * refinementfile ); + + // if qualityloss is not equal to NULL at input, a (1-based) list of qualitylosses (due to projection) + // is saved in *qualityloss, its size is the return value + DLL_HEADER int Ng_Bisect_WithInfo ( const char * refinementfile, double ** qualityloss); + + typedef void * Ng_Mesh; + DLL_HEADER Ng_Mesh Ng_SelectMesh (Ng_Mesh mesh); + + DLL_HEADER void Ng_GetArgs (int & argc, char ** &argv); + + +#ifdef __cplusplus +} +#endif + +#endif + + + + + + +/* + The new node interface ... + it is 0-based ! + */ + +extern "C" { + + /* + number of nodes of type nt + nt = 0 is Vertex + nt = 1 is Edge + nt = 2 is Face + nt = 3 is Cell + */ + DLL_HEADER int Ng_GetNNodes (int nt); + + /* + closure nodes of node (nt, nodenr): + nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc + E.g., nodeset = 6 includes edge and face nodes + nodes consists of pairs of integers (nodetype, nodenr) + return value is number of nodes + */ + DLL_HEADER int Ng_GetClosureNodes (int nt, int nodenr, int nodeset, int * nodes); + + + /* + number of dim-dimensional elements + dim = 3 ... volume elements + dim = 2 ... surface elements + dim = 1 ... segments + dim = 0 ... not available + */ + DLL_HEADER int Ng_GetNElements (int dim); + + /* + closure nodes of dim-dimensional element elmentnr: + nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc + E.g., nodeset = 6 includes edge and face nodes + nodes consists of pairs of integers (nodetype, nodenr) + return value is number of nodes + */ + DLL_HEADER int Ng_GetElementClosureNodes (int dim, int elementnr, int nodeset, int * nodes); + + + struct Ng_Tcl_Interp; + typedef int (Ng_Tcl_CmdProc) (Ng_Tcl_Interp *interp, int argc, const char *argv[]); + + DLL_HEADER void Ng_Tcl_CreateCommand (Ng_Tcl_Interp * interp, + const char * cmdName, Ng_Tcl_CmdProc * proc); + + void Ng_Tcl_SetResult (Ng_Tcl_Interp * interp, const char * result); +} + + + + + +#ifdef __cplusplus +#include +namespace netgen +{ + DLL_HEADER extern std::ostream * testout; + DLL_HEADER extern int printmessage_importance; +} + +#endif + diff --git a/libsrc/include/nginterface_v2.hpp b/libsrc/include/nginterface_v2.hpp new file mode 100644 index 00000000..e53d6dc8 --- /dev/null +++ b/libsrc/include/nginterface_v2.hpp @@ -0,0 +1,248 @@ +#ifndef NGINTERFACE_V2 +#define NGINTERFACE_V2 + + +/**************************************************************************/ +/* File: nginterface_v2.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: May 09 */ +/**************************************************************************/ + +/* + C++ interface to Netgen +*/ + + +namespace netgen +{ + struct T_EDGE2 + { + int orient:1; + int nr:31; // 0-based + }; + struct T_FACE2 + { + int orient:3; + int nr:29; // 0-based + }; + + class Ng_Element + { + + class Ng_Points + { + public: + int num; + const int * ptr; + + int Size() const { return num; } + int operator[] (int i) const { return ptr[i]-1; } + }; + + + class Ng_Vertices + { + public: + int num; + const int * ptr; + + int Size() const { return num; } + int operator[] (int i) const { return ptr[i]-1; } + }; + + class Ng_Edges + { + public: + int num; + const T_EDGE2 * ptr; + + int Size() const { return num; } + // int operator[] (int i) const { return abs (ptr[i])-1; } + int operator[] (int i) const { return ptr[i].nr; } + }; + + class Ng_Faces + { + public: + int num; + const T_FACE2 * ptr; + + int Size() const { return num; } + // int operator[] (int i) const { return (ptr[i]-1) / 8; } + int operator[] (int i) const { return ptr[i].nr; } + }; + + public: + NG_ELEMENT_TYPE type; + NG_ELEMENT_TYPE GetType() const { return type; } + + Ng_Points points; // all points + Ng_Vertices vertices; + Ng_Edges edges; + Ng_Faces faces; + }; + + + class Ng_Point + { + double * pt; + public: + Ng_Point (double * apt) : pt(apt) { ; } + double operator[] (int i) + { return pt[i]; } + operator const double * () { return pt; } + }; + + + + + template class Ng_Node; + + template <> + class Ng_Node<1> + { + class Ng_Vertices + { + public: + const int * ptr; + + int Size() const { return 2; } + int operator[] (int i) const { return ptr[i]-1; } + }; + + + public: + Ng_Vertices vertices; + }; + + + + template <> + class Ng_Node<2> + { + class Ng_Vertices + { + public: + int nv; + const int * ptr; + + int Size() const { return nv; } + int operator[] (int i) const { return ptr[i]-1; } + }; + + class Ng_Edges + { + public: + int ned; + const int * ptr; + + int Size() const { return ned; } + int operator[] (int i) const { return ptr[i]-1; } + }; + + + public: + Ng_Vertices vertices; + Ng_Edges edges; + }; + + + + + + + + + + + class DLL_HEADER Ngx_Mesh + { + private: + class Mesh * mesh; + + public: + Ngx_Mesh () { ; } + Ngx_Mesh(class Mesh * amesh) : mesh(amesh) { ; } + void LoadMesh (const string & filename); + + virtual ~Ngx_Mesh(); + + bool Valid () { return mesh != NULL; } + + int GetDimension() const; + int GetNLevels() const; + + int GetNElements (int dim) const; + int GetNNodes (int nt) const; + + Ng_Point GetPoint (int nr) const; + + template + Ng_Element GetElement (int nr) const; + + template + int GetElementIndex (int nr) const; + + + /// Curved Elements: + /// elnr .. element nr + /// xi..... DIM_EL local coordinates + /// x ..... DIM_SPACE global coordinates + /// dxdxi...DIM_SPACE x DIM_EL Jacobian matrix (row major storage) + template + void ElementTransformation (int elnr, + const double * xi, + double * x, + double * dxdxi) const; + + + /// Curved Elements: + /// elnr .. element nr + /// npts .. number of points + /// xi..... DIM_EL local coordinates + /// sxi ... step xi + /// x ..... DIM_SPACE global coordinates + /// dxdxi...DIM_SPACE x DIM_EL Jacobian matrix (row major storage) + template + void MultiElementTransformation (int elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) const; + + + template + Ng_Node GetNode (int nr) const; + + + template + int GetNNodes (); + + // Find element of point, returns local coordinates + template + int FindElementOfPoint + (double * p, double * lami, + bool build_searchtrees = false, + int * const indices = NULL, int numind = 0) const; + + }; + + + + DLL_HEADER Ngx_Mesh * LoadMesh (const string & filename); +} + + +#ifdef HAVE_NETGEN_SOURCES +#include + +namespace netgen +{ +#define NGX_INLINE inline +#include +} + +#endif + + +#endif + diff --git a/libsrc/include/occgeom.hpp b/libsrc/include/occgeom.hpp new file mode 100644 index 00000000..af258e0d --- /dev/null +++ b/libsrc/include/occgeom.hpp @@ -0,0 +1 @@ +#include "../occ/occgeom.hpp" diff --git a/libsrc/include/opti.hpp b/libsrc/include/opti.hpp new file mode 100644 index 00000000..5792d70f --- /dev/null +++ b/libsrc/include/opti.hpp @@ -0,0 +1 @@ +#include "../linalg/opti.hpp" diff --git a/libsrc/include/parallel.hpp b/libsrc/include/parallel.hpp new file mode 100644 index 00000000..4ba662f8 --- /dev/null +++ b/libsrc/include/parallel.hpp @@ -0,0 +1 @@ +#include "../parallel/parallel.hpp" diff --git a/libsrc/include/stlgeom.hpp b/libsrc/include/stlgeom.hpp new file mode 100644 index 00000000..f1eea264 --- /dev/null +++ b/libsrc/include/stlgeom.hpp @@ -0,0 +1 @@ +#include <../stlgeom/stlgeom.hpp> diff --git a/libsrc/include/visual.hpp b/libsrc/include/visual.hpp new file mode 100644 index 00000000..f026f5a4 --- /dev/null +++ b/libsrc/include/visual.hpp @@ -0,0 +1 @@ +#include "../visualization/visual.hpp" diff --git a/libsrc/interface/Makefile.am b/libsrc/interface/Makefile.am new file mode 100644 index 00000000..01379795 --- /dev/null +++ b/libsrc/interface/Makefile.am @@ -0,0 +1,12 @@ +noinst_HEADERS = writeuser.hpp + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include -I$(top_srcdir)/libsrc/interface $(MPI_INCLUDES) $(TCL_INCLUDES) -DOPENGL +METASOURCES = AUTO +lib_LTLIBRARIES = libinterface.la +libinterface_la_SOURCES = nginterface.cpp nginterface_v2.cpp \ + read_fnf_mesh.cpp readtetmesh.cpp readuser.cpp writeabaqus.cpp writediffpack.cpp \ + writedolfin.cpp writeelmer.cpp writefeap.cpp writefluent.cpp writegmsh.cpp writejcm.cpp \ + writepermas.cpp writetecplot.cpp writetet.cpp writetochnog.cpp writeuser.cpp \ + wuchemnitz.cpp writegmsh2.cpp writeOpenFOAM15x.cpp + + diff --git a/libsrc/interface/Makefile.in b/libsrc/interface/Makefile.in new file mode 100644 index 00000000..995743c5 --- /dev/null +++ b/libsrc/interface/Makefile.in @@ -0,0 +1,620 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc/interface +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libinterface_la_LIBADD = +am_libinterface_la_OBJECTS = nginterface.lo nginterface_v2.lo \ + read_fnf_mesh.lo readtetmesh.lo readuser.lo writeabaqus.lo \ + writediffpack.lo writedolfin.lo writeelmer.lo writefeap.lo \ + writefluent.lo writegmsh.lo writejcm.lo writepermas.lo \ + writetecplot.lo writetet.lo writetochnog.lo writeuser.lo \ + wuchemnitz.lo writegmsh2.lo writeOpenFOAM15x.lo +libinterface_la_OBJECTS = $(am_libinterface_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libinterface_la_SOURCES) +DIST_SOURCES = $(libinterface_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = writeuser.hpp +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include -I$(top_srcdir)/libsrc/interface $(MPI_INCLUDES) $(TCL_INCLUDES) -DOPENGL +METASOURCES = AUTO +lib_LTLIBRARIES = libinterface.la +libinterface_la_SOURCES = nginterface.cpp nginterface_v2.cpp \ + read_fnf_mesh.cpp readtetmesh.cpp readuser.cpp writeabaqus.cpp writediffpack.cpp \ + writedolfin.cpp writeelmer.cpp writefeap.cpp writefluent.cpp writegmsh.cpp writejcm.cpp \ + writepermas.cpp writetecplot.cpp writetet.cpp writetochnog.cpp writeuser.cpp \ + wuchemnitz.cpp writegmsh2.cpp writeOpenFOAM15x.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/interface/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/interface/Makefile +.PRECIOUS: 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): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libinterface.la: $(libinterface_la_OBJECTS) $(libinterface_la_DEPENDENCIES) $(EXTRA_libinterface_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libinterface_la_OBJECTS) $(libinterface_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nginterface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nginterface_v2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read_fnf_mesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readtetmesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readuser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeOpenFOAM15x.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeabaqus.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writediffpack.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writedolfin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeelmer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writefeap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writefluent.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writegmsh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writegmsh2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writejcm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writepermas.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writetecplot.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writetet.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writetochnog.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writeuser.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wuchemnitz.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + 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-libLTLIBRARIES + +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: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES 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 uninstall uninstall-am uninstall-libLTLIBRARIES + + +# 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/libsrc/interface/nginterface.cpp b/libsrc/interface/nginterface.cpp new file mode 100644 index 00000000..8c80331b --- /dev/null +++ b/libsrc/interface/nginterface.cpp @@ -0,0 +1,2307 @@ +#include + +#include +#include + + +#ifdef SOCKETS +#include "../sockets/sockets.hpp" +#endif + +#include "nginterface.h" +#include "../visualization/soldata.hpp" + + +#ifdef _MSC_VER +// Philippose - 30/01/2009 +// MSVC Express Edition Support +#ifdef MSVC_EXPRESS + +// #include + +static pthread_t meshingthread; +void RunParallel ( void * (*fun)(void *), void * in) +{ + if (netgen::mparam.parthread) // && (ntasks == 1) ) + { + pthread_attr_t attr; + pthread_attr_init (&attr); + // the following call can be removed if not available: + pthread_attr_setstacksize(&attr, 1000000); + //pthread_create (&meshingthread, &attr, fun, NULL); + pthread_create (&meshingthread, &attr, fun, in); + } + else + fun (in); +} + +#else // Using MS VC++ Standard / Enterprise / Professional edition + +// Afx - Threads need different return - value: + +static void* (*sfun)(void *); +unsigned int fun2 (void * val) +{ + sfun (val); + return 0; +} + +void RunParallel ( void* (*fun)(void *), void * in) +{ + sfun = fun; + if (netgen::mparam.parthread) + AfxBeginThread (fun2, in); + //AfxBeginThread (fun2, NULL); + else + fun (in); +} + +#endif // #ifdef MSVC_EXPRESS + +#else // For #ifdef _MSC_VER + +// #include + +static pthread_t meshingthread; +void RunParallel ( void * (*fun)(void *), void * in) +{ + bool parthread = netgen::mparam.parthread; + +#ifdef PARALLEL + int provided; + MPI_Query_thread(&provided); + if (provided < 3) + if (netgen::ntasks > 1) parthread = false; + // cout << "runparallel = " << parthread << endl; +#endif + + if (parthread) + { + pthread_attr_t attr; + pthread_attr_init (&attr); + // the following call can be removed if not available: + pthread_attr_setstacksize(&attr, 1000000); + //pthread_create (&meshingthread, &attr, fun, NULL); + pthread_create (&meshingthread, &attr, fun, in); + } + else + fun (in); +} + +#endif // #ifdef _MSC_VER + + + + + + +namespace netgen +{ +#include "writeuser.hpp" + + MeshingParameters mparam; + + // global variable mesh (should not be used in libraries) + AutoPtr mesh; + // NetgenGeometry * ng_geometry = NULL; // new NetgenGeometry; + AutoPtr ng_geometry; + + // extern NetgenGeometry * ng_geometry; + // extern AutoPtr mesh; + +#ifndef NOTCL + extern Tcl_Interp * tcl_interp; +#endif + + +#ifdef SOCKETS + extern AutoPtr clientsocket; + //extern Array< AutoPtr < ServerInfo > > servers; + extern Array< ServerInfo* > servers; +#endif + + +} + + +using namespace netgen; + + +void Ng_LoadGeometry (const char * filename) +{ + // he: if filename is empty, return + // can be used to reset geometry + if (!filename || strcmp(filename,"")==0) + { + ng_geometry.Reset (new NetgenGeometry()); + return; + } + + for (int i = 0; i < geometryregister.Size(); i++) + { + NetgenGeometry * hgeom = geometryregister[i]->Load (filename); + if (hgeom) + { + ng_geometry.Reset (hgeom); + mesh.Reset(); + return; + } + } + + + // if (id == 0) + cerr << "cannot load geometry '" << filename << "'" << ", id = " << id << endl; +} + + +void Ng_LoadMeshFromStream ( istream & input ) +{ + mesh.Reset (new Mesh()); + mesh -> Load(input); + + for (int i = 0; i < geometryregister.Size(); i++) + { + NetgenGeometry * hgeom = geometryregister[i]->LoadFromMeshFile (input); + if (hgeom) + { + ng_geometry.Reset (hgeom); + break; + } + } +} + + + + +void Ng_LoadMesh (const char * filename) +{ +#ifdef PARALLEL + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + + if (id == 0) + { +#endif + if ( string(filename).find(".vol") == string::npos ) + /* + if ( (strlen (filename) > 4) && + strcmp (filename + (strlen (filename)-4), ".vol") != 0 ) + */ + { + mesh.Reset (new Mesh()); + ReadFile(*mesh,filename); + + //mesh->SetGlobalH (mparam.maxh); + //mesh->CalcLocalH(); + return; + } + + string fn(filename); + + istream * infile; + if (fn.substr (fn.length()-3, 3) == ".gz") + infile = new igzstream (filename); + else + infile = new ifstream (filename); + + Ng_LoadMeshFromStream(*infile); + delete infile; + +#ifdef PARALLEL + if (ntasks > 1) + { + + char * weightsfilename = new char [strlen(filename)+1]; + strcpy (weightsfilename, filename); + weightsfilename[strlen (weightsfilename)-3] = 'w'; + weightsfilename[strlen (weightsfilename)-2] = 'e'; + weightsfilename[strlen (weightsfilename)-1] = 'i'; + + ifstream weightsfile(weightsfilename); + delete [] weightsfilename; + + if (!(weightsfile.good())) + { + // cout << "regular distribute" << endl; + mesh -> Distribute(); + } + else + { + char str[20]; + bool endfile = false; + int n, dummy; + + Array segment_weights; + Array surface_weights; + Array volume_weights; + + while (weightsfile.good() && !endfile) + { + weightsfile >> str; + + if (strcmp (str, "edgeweights") == 0) + { + weightsfile >> n; + segment_weights.SetSize(n); + for (int i = 0; i < n; i++) + weightsfile >> dummy >> segment_weights[i]; + } + + if (strcmp (str, "surfaceweights") == 0) + { + weightsfile >> n; + surface_weights.SetSize(n); + for (int i=0; i> dummy >> surface_weights[i]; + } + + if (strcmp (str, "volumeweights") == 0) + { + weightsfile >> n; + volume_weights.SetSize(n); + for (int i=0; i> dummy >> volume_weights[i]; + } + + if (strcmp (str, "endfile") == 0) + endfile = true; + } + + mesh -> Distribute(volume_weights, surface_weights, segment_weights); + } + } + } + else + { + mesh.Reset (new Mesh()); + mesh->SendRecvMesh(); + } +#endif +} + +void Ng_LoadMeshFromString (const char * mesh_as_string) +{ + istringstream instream(mesh_as_string); + Ng_LoadMeshFromStream(instream); +} + + + + +int Ng_GetDimension () +{ + return (mesh) ? mesh->GetDimension() : -1; +} + +int Ng_GetNP () +{ + return (mesh) ? mesh->GetNP() : 0; +} + +int Ng_GetNV () +{ + return (mesh) ? mesh->GetNV() : 0; +} + +int Ng_GetNE () +{ + if(!mesh) return 0; + if (mesh->GetDimension() == 3) + return mesh->GetNE(); + else + return mesh->GetNSE(); +} + +int Ng_GetNSE () +{ + if(!mesh) return 0; + if (mesh->GetDimension() == 3) + return mesh->GetNSE(); + else + return mesh->GetNSeg(); +} + +void Ng_GetPoint (int pi, double * p) +{ + if (pi < 1 || pi > mesh->GetNP()) + { + if (printmessage_importance>0) + cout << "Ng_GetPoint: illegal point " << pi << endl; + return; + } + + const Point3d & hp = mesh->Point (pi); + p[0] = hp.X(); + p[1] = hp.Y(); + if (mesh->GetDimension() == 3) + p[2] = hp.Z(); +} + + +NG_ELEMENT_TYPE Ng_GetElement (int ei, int * epi, int * np) +{ + if (mesh->GetDimension() == 3) + { + int i; + const Element & el = mesh->VolumeElement (ei); + for (i = 0; i < el.GetNP(); i++) + epi[i] = el.PNum(i+1); + + if (np) + *np = el.GetNP(); + + if (el.GetType() == PRISM) + { + // degenerated prism, (should be obsolete) + const int map1[] = { 3, 2, 5, 6, 1 }; + const int map2[] = { 1, 3, 6, 4, 2 }; + const int map3[] = { 2, 1, 4, 5, 3 }; + + const int * map = NULL; + int deg1 = 0, deg2 = 0, deg3 = 0; + //int deg = 0; + if (el.PNum(1) == el.PNum(4)) { map = map1; deg1 = 1; } + if (el.PNum(2) == el.PNum(5)) { map = map2; deg2 = 1; } + if (el.PNum(3) == el.PNum(6)) { map = map3; deg3 = 1; } + + switch (deg1+deg2+deg3) + { + { + case 1: + if (printmessage_importance>0) + cout << "degenerated prism found, deg = 1" << endl; + for (i = 0; i < 5; i++) + epi[i] = el.PNum (map[i]); + + if (np) *np = 5; + return NG_PYRAMID; + break; + } + case 2: + { + if (printmessage_importance>0) + cout << "degenerated prism found, deg = 2" << endl; + if (!deg1) epi[3] = el.PNum(4); + if (!deg2) epi[3] = el.PNum(5); + if (!deg3) epi[3] = el.PNum(6); + + if (np) *np = 4; + return NG_TET; + break; + } + default: + ; + } + + } + + return NG_ELEMENT_TYPE (el.GetType()); + } + else + { + const Element2d & el = mesh->SurfaceElement (ei); + for (int i = 0; i < el.GetNP(); i++) + epi[i] = el.PNum(i+1); + + if (np) *np = el.GetNP(); + return NG_ELEMENT_TYPE (el.GetType()); + } + + // should not occur + return NG_TET; +} + + +NG_ELEMENT_TYPE Ng_GetElementType (int ei) +{ + if (mesh->GetDimension() == 3) + { + return NG_ELEMENT_TYPE (mesh->VolumeElement (ei).GetType()); + } + else + { + const Element2d & el = mesh->SurfaceElement (ei); + switch (el.GetNP()) + { + case 3: return NG_TRIG; + case 4: return NG_QUAD; + case 6: return NG_TRIG6; + } + } + + // should not occur + return NG_TET; +} + + + +int Ng_GetElementIndex (int ei) +{ + if (mesh->GetDimension() == 3) + return mesh->VolumeElement(ei).GetIndex(); + else + { + int ind = mesh->SurfaceElement(ei).GetIndex(); + ind = mesh->GetFaceDescriptor(ind).BCProperty(); + return ind; + } +} + +void Ng_SetElementIndex(const int ei, const int index) +{ + mesh->VolumeElement(ei).SetIndex(index); +} + +char * Ng_GetElementMaterial (int ei) +{ + static char empty[] = ""; + if (mesh->GetDimension() == 3) + { + int ind = mesh->VolumeElement(ei).GetIndex(); + // cout << "ind = " << ind << endl; + const char * mat = mesh->GetMaterial (ind); + if (mat) + return const_cast (mat); + else + return empty; + } + // add astrid + else + { + int ind = mesh->SurfaceElement(ei).GetIndex(); + ind = mesh->GetFaceDescriptor(ind).BCProperty(); + const char * mat = mesh->GetMaterial ( ind ); + if (mat) + return const_cast (mat); + else + return empty; + } + return 0; +} + +char * Ng_GetDomainMaterial (int dom) +{ + static char empty[] = ""; + // astrid + if ( 1 ) // mesh->GetDimension() == 3) + { + const char * mat = mesh->GetMaterial(dom); + if (mat) + return const_cast (mat); + else + return empty; + } + + return 0; +} + +int Ng_GetUserDataSize (char * id) +{ + Array da; + mesh->GetUserData (id, da); + return da.Size(); +} + +void Ng_GetUserData (char * id, double * data) +{ + Array da; + mesh->GetUserData (id, da); + for (int i = 0; i < da.Size(); i++) + data[i] = da[i]; +} + + +NG_ELEMENT_TYPE Ng_GetSurfaceElement (int ei, int * epi, int * np) +{ + if (mesh->GetDimension() == 3) + { + const Element2d & el = mesh->SurfaceElement (ei); + for (int i = 0; i < el.GetNP(); i++) + epi[i] = el[i]; + + if (np) *np = el.GetNP(); + + return NG_ELEMENT_TYPE (el.GetType()); + } + else + { + const Segment & seg = mesh->LineSegment (ei); + + if (seg[2] < 0) + { + epi[0] = seg[0]; + epi[1] = seg[1]; + + if (np) *np = 2; + return NG_SEGM; + } + else + { + epi[0] = seg[0]; + epi[1] = seg[1]; + epi[2] = seg[2]; + + if (np) *np = 3; + return NG_SEGM3; + } + } + + return NG_TRIG; +} + +int Ng_GetSurfaceElementIndex (int ei) +{ + if (mesh->GetDimension() == 3) + return mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).BCProperty(); + else + return mesh->LineSegment(ei).si; +} + +int Ng_GetSurfaceElementSurfaceNumber (int ei) +{ + if (mesh->GetDimension() == 3) + return mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).SurfNr(); + else + return mesh->LineSegment(ei).si; +} +int Ng_GetSurfaceElementFDNumber (int ei) +{ + if (mesh->GetDimension() == 3) + return mesh->SurfaceElement(ei).GetIndex(); + else + return -1; +} + + +char * Ng_GetSurfaceElementBCName (int ei) +{ + if ( mesh->GetDimension() == 3 ) + return const_cast(mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).GetBCName().c_str()); + else + return const_cast(mesh->LineSegment(ei).GetBCName().c_str()); +} + + +// Inefficient (but maybe safer) version: +//void Ng_GetSurfaceElementBCName (int ei, char * name) +//{ +// if ( mesh->GetDimension() == 3 ) +// strcpy(name,mesh->GetFaceDescriptor(mesh->SurfaceElement(ei).GetIndex()).GetBCName().c_str()); +// else +// strcpy(name,mesh->LineSegment(ei).GetBCName().c_str()); +//} + +char * Ng_GetBCNumBCName (int bcnr) +{ + return const_cast(mesh->GetBCName(bcnr).c_str()); +} + + +// Inefficient (but maybe safer) version: +//void Ng_GetBCNumBCName (int bcnr, char * name) +//{ +// strcpy(name,mesh->GetBCName(bcnr).c_str()); +//} + +void Ng_GetNormalVector (int sei, int locpi, double * nv) +{ + nv[0] = 0; + nv[1] = 0; + nv[2] = 1; + + if (mesh->GetDimension() == 3) + { + Vec<3> n; + Point<3> p; + p = mesh->Point (mesh->SurfaceElement(sei).PNum(locpi)); + + int surfi = mesh->GetFaceDescriptor(mesh->SurfaceElement(sei).GetIndex()).SurfNr(); + + (*testout) << "surfi = " << surfi << endl; +#ifdef OCCGEOMETRYxxx + OCCGeometry * occgeometry = dynamic_cast (ng_geometry); + if (occgeometry) + { + PointGeomInfo gi = mesh->SurfaceElement(sei).GeomInfoPi(locpi); + occgeometry->GetSurface (surfi).GetNormalVector(p, gi, n); + nv[0] = n(0); + nv[1] = n(1); + nv[2] = n(2); + } +#endif + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (geometry) + { + n = geometry->GetSurface (surfi) -> GetNormalVector(p); + nv[0] = n(0); + nv[1] = n(1); + nv[2] = n(2); + } + } +} + + + +void Ng_SetPointSearchStartElement(const int el) +{ + mesh->SetPointSearchStartElement(el); +} + + +int Ng_FindElementOfPoint (double * p, double * lami, int build_searchtree, + const int * const indices, const int numind) + +{ + Array * dummy(NULL); + int ind = -1; + + if(indices != NULL) + { + dummy = new Array(numind); + for(int i=0; iGetDimension() == 3) + { + Point3d p3d(p[0], p[1], p[2]); + ind = + mesh->GetElementOfPoint(p3d, lami, dummy, build_searchtree != 0); + } + else + { + double lam3[3]; + Point3d p2d(p[0], p[1], 0); + ind = + mesh->GetElementOfPoint(p2d, lam3, dummy, build_searchtree != 0); + + if (ind > 0) + { + if(mesh->SurfaceElement(ind).GetType()==QUAD) + { + lami[0] = lam3[0]; + lami[1] = lam3[1]; + } + else + { + lami[0] = 1-lam3[0]-lam3[1]; + lami[1] = lam3[0]; + } + } + } + + delete dummy; + + return ind; +} + +int Ng_FindSurfaceElementOfPoint (double * p, double * lami, int build_searchtree, + const int * const indices, const int numind) + +{ + Array * dummy(NULL); + int ind = -1; + + if(indices != NULL) + { + dummy = new Array(numind); + for(int i=0; iGetDimension() == 3) + { + Point3d p3d(p[0], p[1], p[2]); + ind = + mesh->GetSurfaceElementOfPoint(p3d, lami, dummy, build_searchtree != 0); + } + else + { + //throw NgException("FindSurfaceElementOfPoint for 2D meshes not yet implemented"); + cerr << "FindSurfaceElementOfPoint for 2D meshes not yet implemented" << endl; + } + + delete dummy; + + return ind; +} + + +int Ng_IsElementCurved (int ei) +{ + switch (mesh->GetDimension()) + { + case 1: return mesh->GetCurvedElements().IsSegmentCurved (ei-1); + case 2: return mesh->GetCurvedElements().IsSurfaceElementCurved (ei-1); + case 3: return mesh->GetCurvedElements().IsElementCurved (ei-1); + } + return 0; + /* + if (mesh->GetDimension() == 2) + return mesh->GetCurvedElements().IsSurfaceElementCurved (ei-1); + else + return mesh->GetCurvedElements().IsElementCurved (ei-1); + */ +} + + +int Ng_IsSurfaceElementCurved (int sei) +{ + if (mesh->GetDimension() == 2) + return mesh->GetCurvedElements().IsSegmentCurved (sei-1); + else + return mesh->GetCurvedElements().IsSurfaceElementCurved (sei-1); +} + + + + +void Ng_GetElementTransformation (int ei, const double * xi, + double * x, double * dxdxi) +{ + if (mesh->GetDimension() == 2) + { + Point<2> xl(xi[0], xi[1]); + Point<3> xg; + Mat<3,2> dx; + + mesh->GetCurvedElements().CalcSurfaceTransformation (xl, ei-1, xg, dx); + + if (x) + { + for (int i = 0; i < 2; i++) + x[i] = xg(i); + } + + if (dxdxi) + { + for (int i=0; i<2; i++) + { + dxdxi[2*i] = dx(i,0); + dxdxi[2*i+1] = dx(i,1); + } + } + } + else + { + Point<3> xl(xi[0], xi[1], xi[2]); + Point<3> xg; + Mat<3,3> dx; + + mesh->GetCurvedElements().CalcElementTransformation (xl, ei-1, xg, dx); + + if (x) + { + for (int i = 0; i < 3; i++) + x[i] = xg(i); + } + + if (dxdxi) + { + for (int i=0; i<3; i++) + { + dxdxi[3*i] = dx(i,0); + dxdxi[3*i+1] = dx(i,1); + dxdxi[3*i+2] = dx(i,2); + } + } + } +} + + + + +void Ng_GetMultiElementTransformation (int ei, int n, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) +{ + if (mesh->GetDimension() == 2) + mesh->GetCurvedElements().CalcMultiPointSurfaceTransformation<2> (ei-1, n, xi, sxi, x, sx, dxdxi, sdxdxi); + else + mesh->GetCurvedElements().CalcMultiPointElementTransformation (ei-1, n, xi, sxi, x, sx, dxdxi, sdxdxi); +} + + + +void Ng_GetSurfaceElementTransformation (int sei, const double * xi, + double * x, double * dxdxi) +{ + if (mesh->GetDimension() == 2) + { + Point<3> xg; + Vec<3> dx; + + mesh->GetCurvedElements().CalcSegmentTransformation (xi[0], sei-1, xg, dx); + + if (x) + for (int i = 0; i < 2; i++) + x[i] = xg(i); + + if (dxdxi) + for (int i=0; i<2; i++) + dxdxi[i] = dx(i); + + } + else + { + Point<2> xl(xi[0], xi[1]); + Point<3> xg; + Mat<3,2> dx; + + mesh->GetCurvedElements().CalcSurfaceTransformation (xl, sei-1, xg, dx); + + for (int i=0; i<3; i++) + { + if (x) + x[i] = xg(i); + if (dxdxi) + { + dxdxi[2*i] = dx(i,0); + dxdxi[2*i+1] = dx(i,1); + } + } + } +} + + + + + +int Ng_GetSegmentIndex (int ei) +{ + const Segment & seg = mesh->LineSegment (ei); + return seg.edgenr; +} + + +NG_ELEMENT_TYPE Ng_GetSegment (int ei, int * epi, int * np) +{ + const Segment & seg = mesh->LineSegment (ei); + + epi[0] = seg[0]; + epi[1] = seg[1]; + + if (seg[2] < 0) + { + if (np) *np = 2; + return NG_SEGM; + } + else + { + epi[2] = seg[2]; + if (np) *np = 3; + return NG_SEGM3; + } +} + + + + + + +void Ng_GetSurfaceElementNeighbouringDomains(const int selnr, int & in, int & out) +{ + if ( mesh->GetDimension() == 3 ) + { + in = mesh->GetFaceDescriptor(mesh->SurfaceElement(selnr).GetIndex()).DomainIn(); + out = mesh->GetFaceDescriptor(mesh->SurfaceElement(selnr).GetIndex()).DomainOut(); + } + else + { + in = mesh -> LineSegment(selnr) . domin; + out = mesh -> LineSegment(selnr) . domout; + } +} + + +#ifdef PARALLEL + +// gibt anzahl an distant pnums zurueck +// * pnums entspricht ARRAY +int NgPar_GetDistantNodeNums ( int nodetype, int locnum, int * distnums ) +{ + int size = NgPar_GetNDistantNodeNums (nodetype, locnum); + locnum++; + switch ( nodetype ) + { + case 0: + mesh->GetParallelTopology().GetDistantPNums( locnum, distnums ); + break; + case 1: + mesh->GetParallelTopology().GetDistantEdgeNums( locnum, distnums ); + break; + case 2: + mesh->GetParallelTopology().GetDistantFaceNums( locnum, distnums ); + break; + case 3: + // mesh->GetParallelTopology().GetDistantElNums( locnum, distnums ); + break; + default: + cerr << "NgPar_GetDistantNodeNums() Unknown nodetype " << nodetype << endl; + size = -1; + } + + return size; +} + +int NgPar_GetNDistantNodeNums ( int nodetype, int locnum ) +{ + locnum++; + switch ( nodetype ) + { + case 0: return mesh->GetParallelTopology().GetNDistantPNums (locnum); + case 1: return mesh->GetParallelTopology().GetNDistantEdgeNums (locnum); + case 2: return mesh->GetParallelTopology().GetNDistantFaceNums(locnum ); + case 3: return 0; + } + return -1; +} + +int NgPar_GetGlobalNodeNum (int nodetype, int locnum) +{ + locnum++; + switch (nodetype) + { + case 0: return mesh->GetParallelTopology().GetGlobalPNum (locnum)-1; + case 1: return mesh->GetParallelTopology().GetGlobalEdgeNum (locnum)-1; + case 2: return mesh->GetParallelTopology().GetGlobalFaceNum (locnum)-1; + case 3: return mesh->GetParallelTopology().GetGlobalElNum (locnum)-1; + } + return -1; +} + + +#endif + +void Ng_SetRefinementFlag (int ei, int flag) +{ + if (mesh->GetDimension() == 3) + { + mesh->VolumeElement(ei).SetRefinementFlag (flag != 0); + mesh->VolumeElement(ei).SetStrongRefinementFlag (flag >= 10); + } + else + { + mesh->SurfaceElement(ei).SetRefinementFlag (flag != 0); + mesh->SurfaceElement(ei).SetStrongRefinementFlag (flag >= 10); + } +} + +void Ng_SetSurfaceRefinementFlag (int ei, int flag) +{ + if (mesh->GetDimension() == 3) + { + mesh->SurfaceElement(ei).SetRefinementFlag (flag != 0); + mesh->SurfaceElement(ei).SetStrongRefinementFlag (flag >= 10); + } +} + + +void Ng_Refine (NG_REFINEMENT_TYPE reftype) +{ + NgLock meshlock (mesh->MajorMutex(), 1); + + BisectionOptions biopt; + biopt.usemarkedelements = 1; + biopt.refine_p = 0; + biopt.refine_hp = 0; + if (reftype == NG_REFINE_P) + biopt.refine_p = 1; + if (reftype == NG_REFINE_HP) + biopt.refine_hp = 1; + + const Refinement & ref = ng_geometry->GetRefinement(); + + // Refinement * ref; + MeshOptimize2d * opt = NULL; + + /* + if (geometry2d) + ref = new Refinement2d(*geometry2d); + else if (stlgeometry) + ref = new RefinementSTLGeometry(*stlgeometry); + #ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); + #endif + #ifdef ACIS + else if (acisgeometry) + { + ref = new ACISRefinementSurfaces (*acisgeometry); + opt = new ACISMeshOptimize2dSurfaces(*acisgeometry); + ref->Set2dOptimizer(opt); + } + #endif + else if (geometry && mesh->GetDimension() == 3) + { + ref = new RefinementSurfaces(*geometry); + opt = new MeshOptimize2dSurfaces(*geometry); + ref->Set2dOptimizer(opt); + } + else + { + ref = new Refinement(); + } + */ + + ref.Bisect (*mesh, biopt); + + mesh -> UpdateTopology(); + mesh -> GetCurvedElements().SetIsHighOrder (false); + + // mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + // delete ref; + delete opt; +} + +void Ng_SecondOrder () +{ + const_cast (ng_geometry->GetRefinement()).MakeSecondOrder(*mesh); + /* + if (stlgeometry) + { + RefinementSTLGeometry ref (*stlgeometry); + ref.MakeSecondOrder (*mesh); + } + + else if (geometry2d) + { + Refinement2d ref (*geometry2d); + ref.MakeSecondOrder (*mesh); + } + + else if (geometry && mesh->GetDimension() == 3) + + { + RefinementSurfaces ref (*geometry); + ref.MakeSecondOrder (*mesh); + } + else + { + if (printmessage_importance>0) + cout << "no geom" << endl; + Refinement ref; + ref.MakeSecondOrder (*mesh); + } + */ + mesh -> UpdateTopology(); +} + +/* + void Ng_HPRefinement (int levels) + { + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); + else + ref = new RefinementSurfaces (*geometry); + + + HPRefinement (*mesh, ref, levels); + } + + void Ng_HPRefinement (int levels, double parameter) + { + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); + else + ref = new RefinementSurfaces (*geometry); + + + HPRefinement (*mesh, ref, levels, parameter); + } +*/ + +void Ng_HPRefinement (int levels, double parameter, bool setorders, + bool ref_level) +{ + NgLock meshlock (mesh->MajorMutex(), true); + Refinement & ref = const_cast (ng_geometry -> GetRefinement()); + HPRefinement (*mesh, &ref, levels, parameter, setorders, ref_level); + /* + Refinement * ref; + + if (stlgeometry) + ref = new RefinementSTLGeometry (*stlgeometry); + else if (geometry2d) + ref = new Refinement2d (*geometry2d); + else + ref = new RefinementSurfaces (*geometry); + + HPRefinement (*mesh, ref, levels, parameter, setorders, ref_level); + */ +} + + +void Ng_HighOrder (int order, bool rational) +{ + NgLock meshlock (mesh->MajorMutex(), true); + + mesh -> GetCurvedElements().BuildCurvedElements + (&const_cast (ng_geometry -> GetRefinement()), + order, rational); + + mesh -> SetNextMajorTimeStamp(); +} + + + + + + + + + + + + +int Ng_ME_GetNVertices (NG_ELEMENT_TYPE et) +{ + switch (et) + { + case NG_SEGM: + case NG_SEGM3: + return 2; + + case NG_TRIG: + case NG_TRIG6: + return 3; + + case NG_QUAD: + return 4; + + case NG_TET: + case NG_TET10: + return 4; + + case NG_PYRAMID: + return 5; + + case NG_PRISM: + case NG_PRISM12: + return 6; + + case NG_HEX: + return 8; + + default: + cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; + } + return 0; +} + +int Ng_ME_GetNEdges (NG_ELEMENT_TYPE et) +{ + switch (et) + { + case NG_SEGM: + case NG_SEGM3: + return 1; + + case NG_TRIG: + case NG_TRIG6: + return 3; + + case NG_QUAD: + return 4; + + case NG_TET: + case NG_TET10: + return 6; + + case NG_PYRAMID: + return 8; + + case NG_PRISM: + case NG_PRISM12: + return 9; + + case NG_HEX: + return 12; + + default: + cerr << "Ng_ME_GetNEdges, illegal element type " << et << endl; + } + return 0; +} + + +int Ng_ME_GetNFaces (NG_ELEMENT_TYPE et) +{ + switch (et) + { + case NG_SEGM: + case NG_SEGM3: + return 0; + + case NG_TRIG: + case NG_TRIG6: + return 1; + + case NG_QUAD: + case NG_QUAD6: + return 1; + + case NG_TET: + case NG_TET10: + return 4; + + case NG_PYRAMID: + return 5; + + case NG_PRISM: + case NG_PRISM12: + return 5; + + case NG_HEX: + return 6; + + default: + cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; + } + return 0; +} + + +const NG_POINT * Ng_ME_GetVertices (NG_ELEMENT_TYPE et) +{ + static double segm_points [][3] = + { { 1, 0, 0 }, + { 0, 0, 0 } }; + + static double trig_points [][3] = + { { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 0 } }; + + static double quad_points [][3] = + { { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 } }; + + static double tet_points [][3] = + { { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 0, 0, 0 } }; + + static double pyramid_points [][3] = + { + { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 0, 1-1e-7 }, + }; + + static double prism_points[][3] = + { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 0 }, + { 1, 0, 1 }, + { 0, 1, 1 }, + { 0, 0, 1 } + }; + + switch (et) + { + case NG_SEGM: + case NG_SEGM3: + return segm_points; + + case NG_TRIG: + case NG_TRIG6: + return trig_points; + + case NG_QUAD: + case NG_QUAD6: + return quad_points; + + case NG_TET: + case NG_TET10: + return tet_points; + + case NG_PYRAMID: + return pyramid_points; + + case NG_PRISM: + case NG_PRISM12: + return prism_points; + + case NG_HEX: + default: + cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; + } + return 0; +} + + + +const NG_EDGE * Ng_ME_GetEdges (NG_ELEMENT_TYPE et) +{ + static int segm_edges[1][2] = + { { 1, 2 }}; + + static int trig_edges[3][2] = + { { 3, 1 }, + { 3, 2 }, + { 1, 2 }}; + + static int quad_edges[4][2] = + { { 1, 2 }, + { 4, 3 }, + { 1, 4 }, + { 2, 3 }}; + + + static int tet_edges[6][2] = + { { 4, 1 }, + { 4, 2 }, + { 4, 3 }, + { 1, 2 }, + { 1, 3 }, + { 2, 3 }}; + + static int prism_edges[9][2] = + { { 3, 1 }, + { 1, 2 }, + { 3, 2 }, + { 6, 4 }, + { 4, 5 }, + { 6, 5 }, + { 3, 6 }, + { 1, 4 }, + { 2, 5 }}; + + static int pyramid_edges[8][2] = + { { 1, 2 }, + { 2, 3 }, + { 1, 4 }, + { 4, 3 }, + { 1, 5 }, + { 2, 5 }, + { 3, 5 }, + { 4, 5 }}; + + + + switch (et) + { + case NG_SEGM: + case NG_SEGM3: + return segm_edges; + + case NG_TRIG: + case NG_TRIG6: + return trig_edges; + + case NG_QUAD: + case NG_QUAD6: + return quad_edges; + + case NG_TET: + case NG_TET10: + return tet_edges; + + case NG_PYRAMID: + return pyramid_edges; + + case NG_PRISM: + case NG_PRISM12: + return prism_edges; + + case NG_HEX: + default: + cerr << "Ng_ME_GetEdges, illegal element type " << et << endl; + } + return 0; +} + + +const NG_FACE * Ng_ME_GetFaces (NG_ELEMENT_TYPE et) +{ + static int tet_faces[4][4] = + { { 4, 2, 3, 0 }, + { 4, 1, 3, 0 }, + { 4, 1, 2, 0 }, + { 1, 2, 3, 0 } }; + + static int prism_faces[5][4] = + { + { 1, 2, 3, 0 }, + { 4, 5, 6, 0 }, + { 3, 1, 4, 6 }, + { 1, 2, 5, 4 }, + { 2, 3, 6, 5 } + }; + + static int pyramid_faces[5][4] = + { + { 1, 2, 5, 0 }, + { 2, 3, 5, 0 }, + { 3, 4, 5, 0 }, + { 4, 1, 5, 0 }, + { 1, 2, 3, 4 } + }; + + static int trig_faces[1][4] = + { + { 1, 2, 3, 0 }, + }; + + switch (et) + { + case NG_TET: + case NG_TET10: + return tet_faces; + + case NG_PRISM: + case NG_PRISM12: + return prism_faces; + + case NG_PYRAMID: + return pyramid_faces; + + + case NG_SEGM: + case NG_SEGM3: + + case NG_TRIG: + case NG_TRIG6: + return trig_faces; + case NG_QUAD: + + + case NG_HEX: + + default: + cerr << "Ng_ME_GetFaces, illegal element type " << et << endl; + } + return 0; +} + + + +void Ng_UpdateTopology() +{ + if (mesh) + mesh -> UpdateTopology(); +} + +Ng_Mesh Ng_SelectMesh (Ng_Mesh newmesh) +{ + Mesh * hmesh = mesh.Ptr(); + mesh.Ptr() = (Mesh*)newmesh; + return hmesh; +} + + + +int Ng_GetNEdges() +{ + return mesh->GetTopology().GetNEdges(); +} +int Ng_GetNFaces() +{ + return mesh->GetTopology().GetNFaces(); +} + + + +int Ng_GetElement_Edges (int elnr, int * edges, int * orient) +{ + const MeshTopology & topology = mesh->GetTopology(); + if (mesh->GetDimension() == 3) + return topology.GetElementEdges (elnr, edges, orient); + else + return topology.GetSurfaceElementEdges (elnr, edges, orient); +} + +int Ng_GetElement_Faces (int elnr, int * faces, int * orient) +{ + const MeshTopology & topology = mesh->GetTopology(); + if (mesh->GetDimension() == 3) + return topology.GetElementFaces (elnr, faces, orient); + else + { + faces[0] = elnr; + if (orient) orient[0] = 0; + return 1; + } +} + +int Ng_GetSurfaceElement_Edges (int elnr, int * edges, int * orient) +{ + const MeshTopology & topology = mesh->GetTopology(); + if (mesh->GetDimension() == 3) + return topology.GetSurfaceElementEdges (elnr, edges, orient); + else + { + if (orient) + topology.GetSegmentEdge(elnr, edges[0], orient[0]); + else + edges[0] = topology.GetSegmentEdge(elnr); + } + return 1; + /* + int i, ned; + const MeshTopology & topology = mesh->GetTopology(); + Array ia; + topology.GetSurfaceElementEdges (elnr, ia); + ned = ia.Size(); + for (i = 1; i <= ned; i++) + edges[i-1] = ia.Get(i); + + if (orient) + { + topology.GetSurfaceElementEdgeOrientations (elnr, ia); + for (i = 1; i <= ned; i++) + orient[i-1] = ia.Get(i); + } + return ned; + */ +} + +int Ng_GetSurfaceElement_Face (int selnr, int * orient) +{ + if (mesh->GetDimension() == 3) + { + const MeshTopology & topology = mesh->GetTopology(); + if (orient) + *orient = topology.GetSurfaceElementFaceOrientation (selnr); + return topology.GetSurfaceElementFace (selnr); + } + return -1; +} + +int Ng_GetFace_Vertices (int fnr, int * vert) +{ + const MeshTopology & topology = mesh->GetTopology(); + ArrayMem ia; + topology.GetFaceVertices (fnr, ia); + for (int i = 0; i < ia.Size(); i++) + vert[i] = ia[i]; + // cout << "face verts = " << ia << endl; + return ia.Size(); +} + + +int Ng_GetFace_Edges (int fnr, int * edge) +{ + const MeshTopology & topology = mesh->GetTopology(); + ArrayMem ia; + topology.GetFaceEdges (fnr, ia); + for (int i = 0; i < ia.Size(); i++) + edge[i] = ia[i]; + return ia.Size(); +} + +void Ng_GetEdge_Vertices (int ednr, int * vert) +{ + const MeshTopology & topology = mesh->GetTopology(); + topology.GetEdgeVertices (ednr, vert[0], vert[1]); +} + + +int Ng_GetNVertexElements (int vnr) +{ + switch (mesh->GetDimension()) + { + case 3: + return mesh->GetTopology().GetVertexElements(vnr).Size(); + case 2: + return mesh->GetTopology().GetVertexSurfaceElements(vnr).Size(); + case 1: + { + int cnt = 0; + for (SegmentIndex i = 0; i < mesh->GetNSeg(); i++) + if ( ((*mesh)[i][0] == vnr) || ((*mesh)[i][1] == vnr) ) cnt++; + return cnt; + } + } +} + +void Ng_GetVertexElements (int vnr, int * els) +{ + switch (mesh->GetDimension()) + { + case 3: + { + FlatArray ia = mesh->GetTopology().GetVertexElements(vnr); + for (int i = 0; i < ia.Size(); i++) els[i] = ia[i]+1; + break; + } + case 2: + { + FlatArray ia = mesh->GetTopology().GetVertexSurfaceElements(vnr); + for (int i = 0; i < ia.Size(); i++) els[i] = ia[i]; + break; + } + case 1: + { + int cnt = 0; + for (SegmentIndex i = 0; i < mesh->GetNSeg(); i++) + if ( ((*mesh)[i][0] == vnr) || ((*mesh)[i][1] == vnr) ) + els[cnt++] = i+1; + break; + } + } +} + + +int Ng_GetElementOrder (int enr) +{ + if (mesh->GetDimension() == 3) + return mesh->VolumeElement(enr).GetOrder(); + else + return mesh->SurfaceElement(enr).GetOrder(); +} + +void Ng_GetElementOrders (int enr, int * ox, int * oy, int * oz) +{ + if (mesh->GetDimension() == 3) + mesh->VolumeElement(enr).GetOrder(*ox, *oy, *oz); + else + mesh->SurfaceElement(enr).GetOrder(*ox, *oy, *oz); +} + +void Ng_SetElementOrder (int enr, int order) +{ + if (mesh->GetDimension() == 3) + return mesh->VolumeElement(enr).SetOrder(order); + else + return mesh->SurfaceElement(enr).SetOrder(order); +} + +void Ng_SetElementOrders (int enr, int ox, int oy, int oz) +{ + if (mesh->GetDimension() == 3) + mesh->VolumeElement(enr).SetOrder(ox, oy, oz); + else + mesh->SurfaceElement(enr).SetOrder(ox, oy); +} + + +int Ng_GetSurfaceElementOrder (int enr) +{ + return mesh->SurfaceElement(enr).GetOrder(); +} + +//HERBERT: falsche Anzahl von Argumenten +//void Ng_GetSurfaceElementOrders (int enr, int * ox, int * oy, int * oz) +void Ng_GetSurfaceElementOrders (int enr, int * ox, int * oy) +{ + int d; + mesh->SurfaceElement(enr).GetOrder(*ox, *oy, d); +} + +void Ng_SetSurfaceElementOrder (int enr, int order) +{ + return mesh->SurfaceElement(enr).SetOrder(order); +} + +void Ng_SetSurfaceElementOrders (int enr, int ox, int oy) +{ + mesh->SurfaceElement(enr).SetOrder(ox, oy); +} + + +int Ng_GetNLevels () +{ + return (mesh) ? mesh->mglevels : 0; +} + + +void Ng_GetParentNodes (int ni, int * parents) +{ + if (ni <= mesh->mlbetweennodes.Size()) + { + parents[0] = mesh->mlbetweennodes.Get(ni).I1(); + parents[1] = mesh->mlbetweennodes.Get(ni).I2(); + } + else + parents[0] = parents[1] = 0; +} + + +int Ng_GetParentElement (int ei) +{ + if (mesh->GetDimension() == 3) + { + if (ei <= mesh->mlparentelement.Size()) + return mesh->mlparentelement.Get(ei); + } + else + { + if (ei <= mesh->mlparentsurfaceelement.Size()) + return mesh->mlparentsurfaceelement.Get(ei); + } + return 0; +} + + +int Ng_GetParentSElement (int ei) +{ + if (mesh->GetDimension() == 3) + { + if (ei <= mesh->mlparentsurfaceelement.Size()) + return mesh->mlparentsurfaceelement.Get(ei); + } + else + { + return 0; + } + return 0; +} + + + + + +int Ng_GetClusterRepVertex (int pi) +{ + return mesh->GetClusters().GetVertexRepresentant(pi); +} + +int Ng_GetClusterRepEdge (int pi) +{ + return mesh->GetClusters().GetEdgeRepresentant(pi); +} + +int Ng_GetClusterRepFace (int pi) +{ + return mesh->GetClusters().GetFaceRepresentant(pi); +} + +int Ng_GetClusterRepElement (int pi) +{ + return mesh->GetClusters().GetElementRepresentant(pi); +} + + + + + +int Ng_GetNPeriodicVertices (int idnr) +{ + Array apairs; + mesh->GetIdentifications().GetPairs (idnr, apairs); + return apairs.Size(); +} + + +// pairs should be an integer array of 2*npairs +void Ng_GetPeriodicVertices (int idnr, int * pairs) +{ + Array apairs; + mesh->GetIdentifications().GetPairs (idnr, apairs); + for (int i = 0; i < apairs.Size(); i++) + { + pairs[2*i] = apairs[i].I1(); + pairs[2*i+1] = apairs[i].I2(); + } + +} + + + +int Ng_GetNPeriodicEdges (int idnr) +{ + Array map; + //const MeshTopology & top = mesh->GetTopology(); + int nse = mesh->GetNSeg(); + + int cnt = 0; + // for (int id = 1; id <= mesh->GetIdentifications().GetMaxNr(); id++) + { + mesh->GetIdentifications().GetMap(idnr, map); + //(*testout) << "ident-map " << id << ":" << endl << map << endl; + + for (SegmentIndex si = 0; si < nse; si++) + { + PointIndex other1 = PointIndex (map[(*mesh)[si][0]]); + PointIndex other2 = PointIndex (map[(*mesh)[si][1]]); + // (*testout) << "seg = " << (*mesh)[si] << "; other = " + // << other1 << "-" << other2 << endl; + if (other1 && other2 && mesh->IsSegment (other1, other2)) + { + cnt++; + } + } + } + return cnt; +} + +void Ng_GetPeriodicEdges (int idnr, int * pairs) +{ + Array map; + const MeshTopology & top = mesh->GetTopology(); + int nse = mesh->GetNSeg(); + + int cnt = 0; + // for (int id = 1; id <= mesh->GetIdentifications().GetMaxNr(); id++) + { + mesh->GetIdentifications().GetMap(idnr, map); + + //(*testout) << "map = " << map << endl; + + for (SegmentIndex si = 0; si < nse; si++) + { + PointIndex other1 = PointIndex (map[(*mesh)[si][0]]); + PointIndex other2 = PointIndex (map[(*mesh)[si][1]]); + if (other1 && other2 && mesh->IsSegment (other1, other2)) + { + SegmentIndex otherseg = mesh->SegmentNr (other1, other2); + pairs[cnt++] = top.GetSegmentEdge (si+1); + pairs[cnt++] = top.GetSegmentEdge (otherseg+1); + } + } + } +} + + + +void Ng_PushStatus (const char * str) +{ + PushStatus (MyStr (str)); +} + +void Ng_PopStatus () +{ + PopStatus (); +} + +void Ng_SetThreadPercentage (double percent) +{ + SetThreadPercent (percent); +} + +void Ng_GetStatus (char ** str, double & percent) +{ + MyStr s; + GetStatus(s,percent); + *str = new char[s.Length()+1]; + strcpy(*str,s.c_str()); +} + + +void Ng_SetTerminate(void) +{ + multithread.terminate = 1; +} +void Ng_UnSetTerminate(void) +{ + multithread.terminate = 0; +} + +int Ng_ShouldTerminate(void) +{ + return multithread.terminate; +} + +void Ng_SetRunning(int flag) +{ + multithread.running = flag; +} +int Ng_IsRunning() +{ + return multithread.running; +} + +///// Added by Roman Stainko .... +int Ng_GetVertex_Elements( int vnr, int* elems ) +{ + const MeshTopology& topology = mesh->GetTopology(); + ArrayMem indexArray; + topology.GetVertexElements( vnr, indexArray ); + + for( int i=0; iGetTopology(); + ArrayMem indexArray; + topology.GetVertexSurfaceElements( vnr, indexArray ); + + for( int i=0; iGetTopology(); + ArrayMem indexArray; + topology.GetVertexElements( vnr, indexArray ); + + return indexArray.Size(); +} + +///// Added by Roman Stainko .... +int Ng_GetVertex_NSurfaceElements( int vnr ) +{ + const MeshTopology& topology = mesh->GetTopology(); + ArrayMem indexArray; + topology.GetVertexSurfaceElements( vnr, indexArray ); + + return indexArray.Size(); +} + + + +#ifdef SOCKETS +int Ng_SocketClientOpen( const int port, const char * host ) +{ + try + { + if(host) + clientsocket.Reset(new ClientSocket(port,host)); + else + clientsocket.Reset(new ClientSocket(port)); + } + catch( SocketException e) + { + cerr << e.Description() << endl; + return 0; + } + return 1; +} + +void Ng_SocketClientWrite( const char * write, char** reply) +{ + string output = write; + (*clientsocket) << output; + string sreply; + (*clientsocket) >> sreply; + *reply = new char[sreply.size()+1]; + strcpy(*reply,sreply.c_str()); +} + + +void Ng_SocketClientClose ( void ) +{ + clientsocket.Reset(NULL); +} + + +void Ng_SocketClientGetServerHost ( const int number, char ** host ) +{ + *host = new char[servers[number]->host.size()+1]; + strcpy(*host,servers[number]->host.c_str()); +} + +void Ng_SocketClientGetServerPort ( const int number, int * port ) +{ + *port = servers[number]->port; +} + +void Ng_SocketClientGetServerClientID ( const int number, int * id ) +{ + *id = servers[number]->clientid; +} + +#endif // SOCKETS + + + + +#ifdef PARALLEL +void Ng_SetElementPartition ( const int elnr, const int part ) +{ + mesh->VolumeElement(elnr+1).SetPartition(part); + +} +int Ng_GetElementPartition ( const int elnr ) +{ + return mesh->VolumeElement(elnr+1).GetPartition(); +} +#endif + + +void Ng_InitPointCurve(double red, double green, double blue) +{ + mesh->InitPointCurve(red, green, blue); +} + +void Ng_AddPointCurvePoint(const double * point) +{ + Point3d pt; + pt.X() = point[0]; + pt.Y() = point[1]; + pt.Z() = point[2]; + mesh->AddPointCurvePoint(pt); +} + + +void Ng_SaveMesh ( const char * meshfile ) +{ + mesh -> Save(string(meshfile)); +} + + +int Ng_Bisect_WithInfo ( const char * refinementfile, double ** qualityloss, int * qualityloss_size ) +{ + BisectionOptions biopt; + biopt.outfilename = NULL; // "ngfepp.vol"; + biopt.femcode = "fepp"; + biopt.refinementfilename = refinementfile; + + Refinement * ref = const_cast (&ng_geometry -> GetRefinement()); + MeshOptimize2d * opt = NULL; + /* + if (stlgeometry) + ref = new RefinementSTLGeometry(*stlgeometry); + #ifdef OCCGEOMETRY + else if (occgeometry) + ref = new OCCRefinementSurfaces (*occgeometry); + #endif + #ifdef ACIS + else if (acisgeometry) + { + ref = new ACISRefinementSurfaces(*acisgeometry); + opt = new ACISMeshOptimize2dSurfaces(*acisgeometry); + ref->Set2dOptimizer(opt); + } + #endif + else + { + ref = new RefinementSurfaces(*geometry); + opt = new MeshOptimize2dSurfaces(*geometry); + ref->Set2dOptimizer(opt); + } + */ +#ifdef ACIS + if (acisgeometry) + { + // ref = new ACISRefinementSurfaces(*acisgeometry); + opt = new ACISMeshOptimize2dSurfaces(*acisgeometry); + ref->Set2dOptimizer(opt); + } + else +#endif + { + // ref = new RefinementSurfaces(*geometry); + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (geometry) + { + opt = new MeshOptimize2dSurfaces(*geometry); + ref->Set2dOptimizer(opt); + } + } + + if(!mesh->LocalHFunctionGenerated()) + mesh->CalcLocalH(mparam.grading); + + mesh->LocalHFunction().SetGrading (mparam.grading); + + Array * qualityloss_arr = NULL; + if(qualityloss != NULL) + qualityloss_arr = new Array; + + ref -> Bisect (*mesh, biopt, qualityloss_arr); + + int retval = 0; + + if(qualityloss != NULL) + { + *qualityloss = new double[qualityloss_arr->Size()+1]; + + for(int i = 0; iSize(); i++) + (*qualityloss)[i+1] = (*qualityloss_arr)[i]; + + retval = qualityloss_arr->Size(); + + delete qualityloss_arr; + } + + mesh -> UpdateTopology(); + mesh -> GetCurvedElements().BuildCurvedElements (ref, mparam.elementorder); + + multithread.running = 0; + delete ref; + delete opt; + + return retval; +} + +void Ng_Bisect ( const char * refinementfile ) +{ + Ng_Bisect_WithInfo( refinementfile, NULL, NULL ); +} + + + + + +/* + number of nodes of type nt + nt = 0 is Vertex + nt = 1 is Edge + nt = 2 is Face + nt = 3 is Cell +*/ +int Ng_GetNNodes (int nt) +{ + switch (nt) + { + case 0: return mesh -> GetNV(); + case 1: return mesh->GetTopology().GetNEdges(); + case 2: return mesh->GetTopology().GetNFaces(); + case 3: return mesh -> GetNE(); + } + return -1; +} + + +int Ng_GetClosureNodes (int nt, int nodenr, int nodeset, int * nodes) +{ + switch (nt) + { + case 3: // The closure of a cell + { + int cnt = 0; + if (nodeset & 1) // Vertices + { + const Element & el = (*mesh)[ElementIndex(nodenr)]; + for (int i = 0; i < el.GetNP(); i++) + { + nodes[cnt++] = 0; + nodes[cnt++] = el[i] - PointIndex::BASE; + } + } + + if (nodeset & 2) // Edges + { + int edges[12]; + int ned; + ned = mesh->GetTopology().GetElementEdges (nodenr+1, edges, 0); + for (int i = 0; i < ned; i++) + { + nodes[cnt++] = 1; + nodes[cnt++] = edges[i]-1; + } + } + + if (nodeset & 4) // Faces + { + int faces[12]; + int nfa; + nfa = mesh->GetTopology().GetElementFaces (nodenr+1, faces, 0); + for (int i = 0; i < nfa; i++) + { + nodes[cnt++] = 2; + nodes[cnt++] = faces[i]-1; + } + } + + if (nodeset & 8) // Cell + { + nodes[cnt++] = 3; + nodes[cnt++] = nodenr; + } + + return cnt/2; + } + default: + { + cerr << "GetClosureNodes not implemented for Nodetype " << nt << endl; + } + } + return 0; +} + + + +int Ng_GetNElements (int dim) +{ + switch (dim) + { + case 0: return mesh -> GetNV(); + case 1: return mesh -> GetNSeg(); + case 2: return mesh -> GetNSE(); + case 3: return mesh -> GetNE(); + } + return -1; +} + + + +/* + closure nodes of element + nodeset is bit-coded, bit 0 includes Vertices, bit 1 edges, etc + E.g., nodeset = 6 includes edge and face nodes + nodes is pair of integers (nodetype, nodenr) + return value is number of nodes +*/ +int Ng_GetElementClosureNodes (int dim, int elementnr, int nodeset, int * nodes) +{ + switch (dim) + { + case 3: // The closure of a volume element = CELL + { + return Ng_GetClosureNodes (3, elementnr, nodeset, nodes); + } + case 2: + { + int cnt = 0; + if (nodeset & 1) // Vertices + { + const Element2d & el = (*mesh)[SurfaceElementIndex(elementnr)]; + for (int i = 0; i < el.GetNP(); i++) + { + nodes[cnt++] = 0; + nodes[cnt++] = el[i] - PointIndex::BASE; + } + } + + if (nodeset & 2) // Edges + { + int edges[12]; + int ned; + ned = mesh->GetTopology().GetSurfaceElementEdges (elementnr+1, edges, 0); + for (int i = 0; i < ned; i++) + { + nodes[cnt++] = 1; + nodes[cnt++] = edges[i]-1; + } + } + + if (nodeset & 4) // Faces + { + int face = mesh->GetTopology().GetSurfaceElementFace (elementnr+1); + nodes[cnt++] = 2; + nodes[cnt++] = face-1; + } + + return cnt/2; + } + default: + { + cerr << "GetClosureNodes not implemented for Element of dimension " << dim << endl; + } + } + return 0; +} + + + +void Ng_GetArgs (int & argc, char ** &argv) +{ + argc = h_argc; + argv = h_argv; +} diff --git a/libsrc/interface/nginterface_v2.cpp b/libsrc/interface/nginterface_v2.cpp new file mode 100644 index 00000000..2f682982 --- /dev/null +++ b/libsrc/interface/nginterface_v2.cpp @@ -0,0 +1,606 @@ +#include + +#ifdef SOCKETS +#include "../sockets/sockets.hpp" +#endif + +#include "nginterface.h" +#include "nginterface_v2.hpp" + + + +namespace netgen +{ +#include "writeuser.hpp" + extern AutoPtr mesh; +} + + +namespace netgen +{ +#define NGX_INLINE +#include "nginterface_v2_impl.hpp" + + Ngx_Mesh * LoadMesh (const string & filename) + { + netgen::mesh.Ptr() = NULL; + Ng_LoadMesh (filename.c_str()); + return new Ngx_Mesh (netgen::mesh.Ptr()); + } + + void Ngx_Mesh :: LoadMesh (const string & filename) + { + netgen::mesh.Ptr() = NULL; + Ng_LoadMesh (filename.c_str()); + mesh = netgen::mesh.Ptr(); + } + + /* + Ngx_Mesh :: Ngx_Mesh (Mesh * amesh) + : mesh(amesh) + { ; } + */ + + Ngx_Mesh :: ~Ngx_Mesh () + { + if (netgen::mesh.Ptr() == mesh) + netgen::mesh.Ptr() = NULL; + delete mesh; + } + + int Ngx_Mesh :: GetDimension() const + { + return mesh -> GetDimension(); + } + + int Ngx_Mesh :: GetNLevels() const + { + return mesh -> mglevels; + } + + int Ngx_Mesh :: GetNElements (int dim) const + { + switch (dim) + { + case 0: return 0; // mesh -> GetNV(); + case 1: return mesh -> GetNSeg(); + case 2: return mesh -> GetNSE(); + case 3: return mesh -> GetNE(); + } + return -1; + } + + int Ngx_Mesh :: GetNNodes (int nt) const + { + switch (nt) + { + case 0: return mesh -> GetNV(); + case 1: return mesh->GetTopology().GetNEdges(); + case 2: return mesh->GetTopology().GetNFaces(); + case 3: return mesh -> GetNE(); + } + return -1; + } + + /* + Ng_Point Ngx_Mesh :: GetPoint (int nr) const + { + return Ng_Point (&mesh->Point(nr + PointIndex::BASE)(0)); + } + */ + + template <> DLL_HEADER Ng_Element Ngx_Mesh :: GetElement<0> (int nr) const + { + cout << "Netgen does not support 0-D elements" << endl; + Ng_Element ret; + return ret; + } + + /* + template <> DLL_HEADER Ng_Element Ngx_Mesh :: GetElement<1> (int nr) const + { + const Segment & el = mesh->LineSegment (SegmentIndex(nr)); + + Ng_Element ret; + ret.type = NG_ELEMENT_TYPE(el.GetType()); + + ret.points.num = el.GetNP(); + ret.points.ptr = (int*)&(el[0]); + + ret.vertices.num = 2; + ret.vertices.ptr = (int*)&(el[0]); + + ret.edges.num = 1; + ret.edges.ptr = mesh->GetTopology().GetSegmentElementEdgesPtr (nr); + + ret.faces.num = 0; + ret.faces.ptr = NULL; + + return ret; + } + + template <> DLL_HEADER Ng_Element Ngx_Mesh :: GetElement<2> (int nr) const + { + const Element2d & el = mesh->SurfaceElement (SurfaceElementIndex (nr)); + + Ng_Element ret; + ret.type = NG_ELEMENT_TYPE(el.GetType()); + ret.points.num = el.GetNP(); + ret.points.ptr = (int*)&el[0]; + + ret.vertices.num = el.GetNV(); + ret.vertices.ptr = (int*)&(el[0]); + + ret.edges.num = MeshTopology::GetNEdges (el.GetType()); + ret.edges.ptr = mesh->GetTopology().GetSurfaceElementEdgesPtr (nr); + + ret.faces.num = MeshTopology::GetNFaces (el.GetType()); + ret.faces.ptr = mesh->GetTopology().GetSurfaceElementFacesPtr (nr); + + return ret; + } + + template <> DLL_HEADER Ng_Element Ngx_Mesh :: GetElement<3> (int nr) const + { + const Element & el = mesh->VolumeElement (ElementIndex (nr)); + + Ng_Element ret; + ret.type = NG_ELEMENT_TYPE(el.GetType()); + ret.points.num = el.GetNP(); + ret.points.ptr = (int*)&el[0]; + + ret.vertices.num = el.GetNV(); + ret.vertices.ptr = (int*)&(el[0]); + + ret.edges.num = MeshTopology::GetNEdges (el.GetType()); + ret.edges.ptr = mesh->GetTopology().GetElementEdgesPtr (nr); + + ret.faces.num = MeshTopology::GetNFaces (el.GetType()); + ret.faces.ptr = mesh->GetTopology().GetElementFacesPtr (nr); + + return ret; + } + */ + + template <> + DLL_HEADER int Ngx_Mesh :: GetElementIndex<0> (int nr) const + { + return 0; + } + + /* + template <> + DLL_HEADER int Ngx_Mesh :: GetElementIndex<1> (int nr) const + { + return (*mesh)[SegmentIndex(nr)].si; + } + + template <> + DLL_HEADER int Ngx_Mesh :: GetElementIndex<2> (int nr) const + { + int ind = (*mesh)[SurfaceElementIndex(nr)].GetIndex(); + return mesh->GetFaceDescriptor(ind).BCProperty(); + } + + template <> + DLL_HEADER int Ngx_Mesh :: GetElementIndex<3> (int nr) const + { + return (*mesh)[ElementIndex(nr)].GetIndex(); + } + */ + + + + + + + + + + + + + + + + + + /* + DLL_HEADER Ng_Point Ng_GetPoint (int nr) + { + Ng_Point ret; + ret.pt = &mesh->Point(nr + PointIndex::BASE)(0); + return ret; + } + + + template <> + DLL_HEADER int Ng_GetElementIndex<1> (int nr) + { + return (*mesh)[SegmentIndex(nr)].si; + } + + template <> + DLL_HEADER int Ng_GetElementIndex<2> (int nr) + { + int ind = (*mesh)[SurfaceElementIndex(nr)].GetIndex(); + return mesh->GetFaceDescriptor(ind).BCProperty(); + } + + template <> + DLL_HEADER int Ng_GetElementIndex<3> (int nr) + { + return (*mesh)[ElementIndex(nr)].GetIndex(); + } + + template <> int DLL_HEADER Ng_GetNElements<0> () + { + return 0; + } + + template <> int DLL_HEADER Ng_GetNElements<1> () + { + return mesh->GetNSeg(); + } + + template <> DLL_HEADER int Ng_GetNElements<2> () + { + return mesh->GetNSE(); + } + + template <> DLL_HEADER int Ng_GetNElements<3> () + { + return mesh->GetNE(); + } + + template <> DLL_HEADER Ng_Element Ng_GetElement<0> (int nr) + { + cout << "Netgen does not support 0-D elements" << endl; + Ng_Element ret; + return ret; + } + + template <> DLL_HEADER Ng_Element Ng_GetElement<1> (int nr) + { + const Segment & el = mesh->LineSegment (SegmentIndex(nr)); + + Ng_Element ret; + ret.type = NG_ELEMENT_TYPE(el.GetType()); + + ret.points.num = el.GetNP(); + ret.points.ptr = (int*)&(el[0]); + + ret.vertices.num = 2; + ret.vertices.ptr = (int*)&(el[0]); + + ret.edges.num = 1; + ret.edges.ptr = mesh->GetTopology().GetSegmentElementEdgesPtr (nr); + + ret.faces.num = 0; + ret.faces.ptr = NULL; + + return ret; + } + + template <> DLL_HEADER Ng_Element Ng_GetElement<2> (int nr) + { + const Element2d & el = mesh->SurfaceElement (SurfaceElementIndex (nr)); + + Ng_Element ret; + ret.type = NG_ELEMENT_TYPE(el.GetType()); + ret.points.num = el.GetNP(); + ret.points.ptr = (int*)&el[0]; + + ret.vertices.num = el.GetNV(); + ret.vertices.ptr = (int*)&(el[0]); + + ret.edges.num = MeshTopology::GetNEdges (el.GetType()); + ret.edges.ptr = mesh->GetTopology().GetSurfaceElementEdgesPtr (nr); + + ret.faces.num = MeshTopology::GetNFaces (el.GetType()); + ret.faces.ptr = mesh->GetTopology().GetSurfaceElementFacesPtr (nr); + + return ret; + } + + template <> DLL_HEADER Ng_Element Ng_GetElement<3> (int nr) + { + const Element & el = mesh->VolumeElement (ElementIndex (nr)); + + Ng_Element ret; + ret.type = NG_ELEMENT_TYPE(el.GetType()); + ret.points.num = el.GetNP(); + ret.points.ptr = (int*)&el[0]; + + ret.vertices.num = el.GetNV(); + ret.vertices.ptr = (int*)&(el[0]); + + ret.edges.num = MeshTopology::GetNEdges (el.GetType()); + ret.edges.ptr = mesh->GetTopology().GetElementEdgesPtr (nr); + + ret.faces.num = MeshTopology::GetNFaces (el.GetType()); + ret.faces.ptr = mesh->GetTopology().GetElementFacesPtr (nr); + + return ret; + } + */ + + + + + + + + + + template <> DLL_HEADER void Ngx_Mesh :: + ElementTransformation<3,3> (int elnr, + const double * xi, + double * x, + double * dxdxi) const + { + Point<3> xl(xi[0], xi[1], xi[2]); + Point<3> xg; + Mat<3,3> dx; + mesh->GetCurvedElements().CalcElementTransformation (xl, elnr, xg, dx); + + if (x) + for (int i = 0; i < 3; i++) x[i] = xg(i); + + if (dxdxi) + for (int i=0; i<3; i++) + { + dxdxi[3*i] = dx(i,0); + dxdxi[3*i+1] = dx(i,1); + dxdxi[3*i+2] = dx(i,2); + } + } + + template <> DLL_HEADER void Ngx_Mesh :: + ElementTransformation<2,3> (int elnr, + const double * xi, + double * x, + double * dxdxi) const + { + Point<2> xl(xi[0], xi[1]); + Point<3> xg; + Mat<3,2> dx; + + mesh->GetCurvedElements().CalcSurfaceTransformation (xl, elnr, xg, dx); + + if (x) + for (int i = 0; i < 3; i++) x[i] = xg(i); + + if (dxdxi) + for (int i=0; i<3; i++) + { + dxdxi[2*i] = dx(i,0); + dxdxi[2*i+1] = dx(i,1); + } + } + + + template <> DLL_HEADER void Ngx_Mesh :: + ElementTransformation<2,2> (int elnr, + const double * xi, + double * x, + double * dxdxi) const + { + Point<2> xl(xi[0], xi[1]); + Point<3> xg; + Mat<3,2> dx; + + mesh->GetCurvedElements().CalcSurfaceTransformation (xl, elnr, xg, dx); + + if (x) + for (int i = 0; i < 2; i++) x[i] = xg(i); + + if (dxdxi) + for (int i=0; i<2; i++) + { + dxdxi[2*i] = dx(i,0); + dxdxi[2*i+1] = dx(i,1); + } + } + + + + + template <> DLL_HEADER void Ngx_Mesh :: + ElementTransformation<1,2> (int elnr, + const double * xi, + double * x, + double * dxdxi) const + { + Point<3> xg; + Vec<3> dx; + + mesh->GetCurvedElements().CalcSegmentTransformation (xi[0], elnr, xg, dx); + + if (x) + for (int i = 0; i < 2; i++) x[i] = xg(i); + + if (dxdxi) + for (int i=0; i < 2; i++) + dxdxi[i] = dx(i); + } + + + + template <> DLL_HEADER void Ngx_Mesh :: + ElementTransformation<1,1> (int elnr, + const double * xi, + double * x, + double * dxdxi) const + { + Point<3> xg; + Vec<3> dx; + + mesh->GetCurvedElements().CalcSegmentTransformation (xi[0], elnr, xg, dx); + + if (x) x[0] = xg(0); + if (dxdxi) dxdxi[0] = dx(0); + } + + + template <> DLL_HEADER void Ngx_Mesh :: + ElementTransformation<0,1> (int elnr, + const double * xi, + double * x, + double * dxdxi) const + { + cout << "1D not supported" << endl; + } + + + + + + + + + + + + template <> DLL_HEADER void Ngx_Mesh :: + MultiElementTransformation<3,3> (int elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) const + { + mesh->GetCurvedElements().CalcMultiPointElementTransformation (elnr, npts, xi, sxi, x, sx, dxdxi, sdxdxi); + } + + template <> DLL_HEADER void Ngx_Mesh :: + MultiElementTransformation<2,2> (int elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) const + { + mesh->GetCurvedElements().CalcMultiPointSurfaceTransformation<2> (elnr, npts, xi, sxi, x, sx, dxdxi, sdxdxi); + } + + template <> DLL_HEADER void Ngx_Mesh :: + MultiElementTransformation<2,3> (int elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) const + { + mesh->GetCurvedElements().CalcMultiPointSurfaceTransformation<3> (elnr, npts, xi, sxi, x, sx, dxdxi, sdxdxi); + } + + template <> DLL_HEADER void Ngx_Mesh :: + MultiElementTransformation<1,2> (int elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) const + { + mesh->GetCurvedElements().CalcMultiPointSegmentTransformation<2> (elnr, npts, xi, sxi, x, sx, dxdxi, sdxdxi); + } + + template <> DLL_HEADER void Ngx_Mesh :: + MultiElementTransformation<1,1> (int elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) const + { + for (int i = 0; i < npts; i++) + ElementTransformation<1,1> (elnr, xi + i*sxi, x+i*sx, dxdxi+i*sdxdxi); + } + + + template <> DLL_HEADER void Ngx_Mesh :: + MultiElementTransformation<0,1> (int elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) const + { + cout << "1D not supported" << endl; + } + + + + + + + template <> DLL_HEADER int Ngx_Mesh :: GetNNodes<1> () + { + return mesh->GetTopology().GetNEdges(); + } + + template <> DLL_HEADER int Ngx_Mesh :: GetNNodes<2> () + { + return mesh->GetTopology().GetNFaces(); + } + + template <> DLL_HEADER Ng_Node<1> Ngx_Mesh :: GetNode<1> (int nr) const + { + Ng_Node<1> node; + node.vertices.ptr = mesh->GetTopology().GetEdgeVerticesPtr(nr); + return node; + } + + template <> DLL_HEADER Ng_Node<2> Ngx_Mesh :: GetNode<2> (int nr) const + { + Ng_Node<2> node; + node.vertices.ptr = mesh->GetTopology().GetFaceVerticesPtr(nr); + node.vertices.nv = (node.vertices.ptr[3] == 0) ? 3 : 4; + return node; + } + + + template <> + DLL_HEADER int Ngx_Mesh :: FindElementOfPoint <2> + (double * p, double * lami, + bool build_searchtree, + int * const indices, int numind) const + + { + Array dummy(numind); + for (int i = 0; i < numind; i++) dummy[i] = indices[i]+1; + + double lam3[3]; + Point<3> p2d(p[0], p[1], 0); + int ind = + mesh->GetElementOfPoint(p2d, lam3, &dummy, build_searchtree); + + if (ind > 0) + { + if(mesh->SurfaceElement(ind).GetType()==QUAD) + { + lami[0] = lam3[0]; + lami[1] = lam3[1]; + } + else + { + lami[0] = 1-lam3[0]-lam3[1]; + lami[1] = lam3[0]; + } + } + return ind-1; + } + + + template <> + DLL_HEADER int Ngx_Mesh :: FindElementOfPoint <3> + (double * p, double * lami, + bool build_searchtree, + int * const indices, int numind) const + + { + Array dummy(numind); + for (int i = 0; i < numind; i++) dummy[i] = indices[i]+1; + + Point<3> p3d(p[0], p[1], p[2]); + int ind = + mesh->GetElementOfPoint(p3d, lami, &dummy, build_searchtree); + return ind-1; + } + + + +} + + +int link_it_nginterface_v2; + diff --git a/libsrc/interface/read_fnf_mesh.cpp b/libsrc/interface/read_fnf_mesh.cpp new file mode 100644 index 00000000..d1cff5fc --- /dev/null +++ b/libsrc/interface/read_fnf_mesh.cpp @@ -0,0 +1,451 @@ + +// +// Read Pro/ENGINEER neutral format +// + +#include + +#include +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + bool ReadLine (istream & in, string & buf) + { + do + { + buf = ""; + + while (in.good()) + { + char ch = in.get(); + if (ch == '\n') break; + if (ch == '\r') break; + if (ch == '\\') + { + // while (iswhite (ch = in.get() ) + ch = in.get(); // '\n' CR + ch = in.get(); // '\n' LF + } + else + buf += ch; + } + } + while (in.good() && (buf == "" || buf[0] == '#')); + + return in.good(); + } + + + + + + class LoadType + { + public: + int id; + string name; + string placement; + string valuetype; + Array places; + }; + + + + + void ReadFNFFormat (Mesh & mesh, + const string & filename) + { + ifstream fin (filename.c_str()); + + string buf; + + mesh.SetDimension (3); + + while (ReadLine (fin, buf)) + { + stringstream sbuf(buf); + string start_sect, token; char ch; + + sbuf >> start_sect; + + if (start_sect == "%START_SECT") + { + sbuf >> ch >> token; + + if (token == "HEADER") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%TITLE") + { + char ch; + string name; + sbuf >> ch >> name; + cout << "Title: " << name << endl; + } + else if (token == "%STATISTICS") + { + ; + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION HEADER, unknown field: " << buf << endl; + } + } + } + + + else if (token == "ELEM_TYPES") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%ELEM_TYPE") + { + int nr; + string def; + char ch; + sbuf >> nr >> def >> ch; + if (def == "DEF") + { + string classname, type; + sbuf >> classname >> type; + if (classname != "SOLID" || type != "TETRA") + cerr << "Element not supported: " << buf << endl; + } + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION ELEM_TYPE, unknown field: " << buf << endl; + } + } + } + + + else if (token == "COORD_SYSTEMS") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%END_SECT") + { + break; + } + else + { + // cout << "COORD_SYSTEMS, unknown field: " << buf << endl; + } + } + } + + + + else if (token == "MATERIALS") + { + *testout << "parse materials" << endl; + Array young_modulus, poisson_ratio, mass_density; + + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%MATERIAL") + { + int nr; + string prop; + char ch; + double val; + + sbuf >> nr >> prop >> ch; + if (prop == "DEF") + { + ; + } + else + { + sbuf >> val; + *testout << "prop = " << prop << ", val = " << val << endl; + if (prop == "YOUNG_MODULUS") + young_modulus.Append (val); + else if (prop == "POISSON_RATIO") + poisson_ratio.Append (val); + else if (prop == "MASS_DENSITY") + mass_density.Append (val); + } + } + else if (token == "%END_SECT") + { + mesh.SetUserData ("YOUNG_MODULUS", young_modulus); + mesh.SetUserData ("POISSON_RATIO", poisson_ratio); + mesh.SetUserData ("MASS_DENSITY", mass_density); + *testout << "young = " << young_modulus << endl; + *testout << "poisson = " << poisson_ratio << endl; + break; + } + else + { + cout << "SECTION MATERIALS, unknown field: " << buf << endl; + } + } + } + + + else if (token == "MESH") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + sbuf >> token; + if (token == "%NODE") + { + string st; + char ch; + int nr, ks_id; + double x,y,z; + sbuf >> nr >> st >> ch >> x >> y >> z >> ks_id; + mesh.AddPoint (Point3d (x,y,z) ); + } + else if (token == "%ELEM") + { + string elemid, def; + char ch; + int elnr, typid, matid; + string propid; + sbuf >> elnr >> def >> ch; + sbuf >> typid >> matid >> propid; + Array pnums; + while (1) + { + int pn; + sbuf >> pn; + if (!sbuf.good()) break; + pnums.Append (pn); + } + int pe2ng [] = { 0, 1, 2, 3, 4, 7, 5, 6, 8, 9 }; + Element el(pnums.Size()); + for (int j = 0; j < pnums.Size(); j++) + el[pe2ng[j]] = pnums[j]; + el.SetIndex (matid); + mesh.AddVolumeElement (el); + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION MESH, unknown: " << buf << endl; + } + } + } + else if (token == "MESH_TOPOLOGY") + { + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token, kw; + int nr; + char ch; + + sbuf >> token; + if (token == "%EDGE") + { + sbuf >> nr >> kw >> ch; + if (kw == "NODES") + { + Array enums; + while (1) + { + int en; + sbuf >> en; + if (!sbuf.good()) break; + enums.Append (en); + } + for (int j = 0; j+2 < enums.Size(); j+=2) + { + Segment seg; + seg[0] = enums[j]; + seg[1] = enums[j+2]; + seg[2] = enums[j+1]; + seg.edgenr = nr; + mesh.AddSegment (seg); + } + } + } + else if (token == "%SURFACE") + { + sbuf >> nr >> kw >> ch; + if (kw == "FACES") + { + Array fnums; + while (1) + { + int fn; + sbuf >> fn; + if (!sbuf.good()) break; + fnums.Append (fn); + } + + FaceDescriptor fd(-1, -1, -1, -1); + fd.SetBCProperty (nr); + *testout << "add fd " << mesh.GetNFD() << ", nr = " << nr << endl; + mesh.AddFaceDescriptor (fd); + + for (int j = 0; j < fnums.Size(); j += 2) + { + int elnr = fnums[j]; + int fnr = fnums[j+1]; + + const Element & el = mesh.VolumeElement (elnr); + Element2d el2d; + el.GetFace (fnr, el2d); + el2d.SetIndex (nr); + + mesh.AddSurfaceElement (el2d); + } + } + } + else if (token == "%END_SECT") + { + break; + } + else + { + cout << "SECTION MESH, unknown: " << buf << endl; + } + } + } + + + + + else if (token == "LOADS") + { + Array loadtypes; + + while (1) + { + ReadLine (fin, buf); + stringstream sbuf(buf); + string token; + + sbuf >> token; + + if (token == "%LOAD_TYPE") + { + string def; + char ch; + + LoadType * lt = new LoadType; + sbuf >> lt->id >> def >> ch >> lt->name >> lt->placement >> lt->valuetype; + + if (lt->name == "DISPLACEMENT") + cout << "loadtype DISPLACEMENT found" << endl; + + if (lt->placement != "FACE" && lt->placement != "EDGE" && lt->placement != "NODE") + cout << "unsupported placement " << lt->placement << endl; + + loadtypes.Append (lt); + } + + else if (token == "%LOAD") + { + int id; + string def; + char ch; + int placement; + int load_type_id, con_case_id; + sbuf >> id >> def >> ch; + + if (def == "DEF") + { + sbuf >> load_type_id >> con_case_id; + } + if (def == "VAL") + { + sbuf >> placement; + for (int i = 0; i < loadtypes.Size(); i++) + if (load_type_id == loadtypes[i]->id) + loadtypes[i]->places.Append (placement); + } + } + + else if (token == "%END_SECT") + { + for (int i = 0; i < loadtypes.Size(); i++) + { + if (loadtypes[i]->placement == "FACE" && loadtypes[i]->name == "DISPLACEMENT") + { + mesh.SetUserData ("CONSTRAINT_DISP_FACE", loadtypes[i]->places); + cout << "constrained faces: " << loadtypes[i]->places << endl; + } + if (loadtypes[i]->placement == "EDGE" && loadtypes[i]->name == "DISPLACEMENT") + { + mesh.SetUserData ("CONSTRAINT_DISP_EDGE", loadtypes[i]->places); + cout << "constrained edges: " << loadtypes[i]->places << endl; + } + if (loadtypes[i]->placement == "NODE" && loadtypes[i]->name == "DISPLACEMENT") + { + mesh.SetUserData ("CONSTRAINT_DISP_NODE", loadtypes[i]->places); + cout << "constrained nodes: " << loadtypes[i]->places << endl; + } + } + break; + } + else + { + cout << "SECTION LOADS, unknown field: " << buf << endl; + } + } + } + + + + else + { + cout << "unknown section " << token << endl; + } + } + else + cout << "parse line: (" << buf << ")" << endl; + } + } +} diff --git a/libsrc/interface/readtetmesh.cpp b/libsrc/interface/readtetmesh.cpp new file mode 100644 index 00000000..1258068b --- /dev/null +++ b/libsrc/interface/readtetmesh.cpp @@ -0,0 +1,797 @@ + +// +// Read CST file format +// + +#include + +#include +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + + + + void ReadTETFormat (Mesh & mesh, + const string & hfilename) + { + const char * filename = hfilename.c_str(); + + cout << "Reading .tet mesh" << endl; + + ifstream in (filename); + + int inputsection = 0; + bool done = false; + + char ch; + string str; + + string version; + + int unitcode; + double tolerance; + double dS1, dS2, alphaDeg, x3D, y3D, z3D; + int nelts,nfaces,nedges,nnodes; + int nperiodicmasternodes,ncornerperiodicmasternodes,ncubicperiodicmasternodes; + int nperiodicmasteredges,ncornerperiodicmasteredges; + int nperiodicmasterfaces; + int nodeid,type,pid; + int dummyint; + int modelverts,modeledges,modelfaces,modelcells; + Point3d p; + int numObj3D,numObj2D,numObj1D,numObj0D; + bool nullstarted; + Array eldom; + int minId3D = -1, minId2D = -1; + int maxId3D(-1), maxId2D(-1), maxId1D(-1), maxId0D(-1); + Array *> segmentdata; + Array tris; + + Array userdata_int; // just save data for 1:1 output + Array userdata_double; + Array point_pids; + Array tetfacedata; + Array uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D; + + while(!done) + { + // skip "//" comment + bool comment = true; + while(comment) + { + ch = in.get(); + while(ch == ' ' || ch == '\n' || ch == '\t' || ch =='\r') + ch = in.get(); + + if(ch != '/') + { + comment = false; + in.putback(ch); + } + else + { + ch = in.get(); + if(ch != '/') + { + comment = false; + in.putback(ch); + in.putback('/'); + } + else + { + in.ignore(10000,'\n'); + } + } + } + + + switch(inputsection) + { + case 0: + // version number + in >> version; + cout << "Version number " << version << endl; + if(version != "1.1" && version != "2" && version != "2.0") + { + cerr << "WARNING: import only tested for versions 1.1 and 2" << endl; + //done = true; + } + userdata_double.Append(atof(version.c_str())); + break; + + case 1: + // unit code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL) + in >> unitcode; + cout << "unit code " << unitcode << endl; + userdata_int.Append(unitcode); + break; + + case 2: + // Geometric coord "zero" tolerance threshold + in >> tolerance; + cout << "tolerance " << tolerance << endl; + userdata_double.Append(tolerance); + break; + + case 3: + // Periodic UnitCell dS1 , dS2 , alphaDeg + in >> dS1 >> dS2 >> alphaDeg; + userdata_double.Append(dS1); + userdata_double.Append(dS2); + userdata_double.Append(alphaDeg); + break; + + case 4: + // Periodic UnitCell origin in global coords (x3D,y3D,z3D) + in >> x3D >> y3D >> z3D; + userdata_double.Append(x3D); + userdata_double.Append(y3D); + userdata_double.Append(z3D); + break; + + case 5: + // Model entity count: Vertices, Edges, Faces, Cells (Version 2) + in >> modelverts >> modeledges >> modelfaces >> modelcells; + userdata_int.Append(modelverts); + userdata_int.Append(modeledges); + userdata_int.Append(modelfaces); + userdata_int.Append(modelcells); + break; + + case 6: + // Topological mesh-entity counts (#elements,#faces,#edges,#nodes) + in >> nelts >> nfaces >> nedges >> nnodes; + cout << nelts << " elements, " << nfaces << " faces, " << nedges << " edges, " << nnodes << " nodes" << endl; + mesh.SetAllocSize(nnodes,2*nedges,nfaces,nelts); + break; + + case 7: + // NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), PID: + { + cout << "read nodes" << endl; + for(int i=0; i> nodeid >> p.X() >> p.Y() >> p.Z() >> type >> pid; + mesh.AddPoint(p); + point_pids.Append(pid); + if(pid > maxId0D) + maxId0D = pid; + //(*testout) << "point " << p << " type " << type << " mastersexist " << mastersexist << endl; + } + } + break; + + case 8: + // Number of Periodic Master Nodes + in >> nperiodicmasternodes; + break; + + case 9: + // MasterNodeID, SlaveNodeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint; + + in >> dummyint; + } + break; + + case 10: + // Number of Corner Periodic Master Nodes + in >> ncornerperiodicmasternodes; + break; + + case 11: + // MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint; + + for(int j=0; j<3; j++) + in >> dummyint; + } + break; + + case 12: + // Number of Cubic Periodic Master Nodes + in >> ncubicperiodicmasternodes; + break; + + case 13: + //MasterNodeID, 7-SlaveNodeID's, TranslCodes + for(int i=0; i> dummyint; + + for(int j=0; j<7; j++) + in >> dummyint; + } + break; + + case 14: + // EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), PID + cout << "read edges" << endl; + nullstarted = false; + segmentdata.SetSize(nedges); + for(int i=0; i(7); + *segmentdata[i] = -1; + in >> dummyint; + in >> (*segmentdata[i])[0] >> (*segmentdata[i])[1]; + in >> type; + in >> (*segmentdata[i])[2]; + if((*segmentdata[i])[2] > maxId1D) + maxId1D = (*segmentdata[i])[2]; + } + break; + + case 15: + // Number of Periodic Master Edges + in >> nperiodicmasteredges; + break; + + case 16: + // MasterEdgeID, SlaveEdgeID, TranslCode (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint >> dummyint >> dummyint; + break; + + case 17: + // Number of Corner Periodic Master Edges + in >> ncornerperiodicmasteredges; + break; + + case 18: + // MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2) + for(int i=0; i> dummyint; + for(int j=0; j<3; j++) + in >> dummyint; + for(int j=0; j<3; j++) + in >> dummyint; + } + break; + + case 19: + // FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), PID + { + //Segment seg; + int segnum_ng[3]; + bool neg[3]; + cout << "read faces" << endl; + nullstarted = false; + for(int i=0; i> trinum; + for(int j=0; j<3; j++) + { + in >> segnum; + neg[j] = (segnum<0); + if(!neg[j]) + segnum_ng[j] = segnum-1; + else + segnum_ng[j] = -segnum-1; + + if(neg[j]) + tris.Last()->PNum(j+1) = (*segmentdata[segnum_ng[j]])[1]; + else + tris.Last()->PNum(j+1) = (*segmentdata[segnum_ng[j]])[0]; + + tris.Last()->GeomInfoPi(j+1).trignum = trinum; + } + in >> type; + int faceid; + in >> faceid; + + if(faceid > maxId2D) + maxId2D = faceid; + + if(i==0 || faceid < minId2D) + minId2D = faceid; + + tris.Last()->SetIndex(faceid); + + if(faceid > 0) + { + //if(nullstarted) + // { + // cout << "Faces: Assumption about index 0 wrong (face"<> nperiodicmasterfaces; + break; + + case 21: + // MasterFaceID, SlaveFaceID, TranslCode (1=dS1 2=dS2) + { + Vec<3> randomvec(-1.32834,3.82399,0.5429151); + int maxtransl = -1; + for(int i=0; i nodes1(3),nodes2(3); + Array sortval1(3),sortval2(3); + in >> tri1 >> tri2 >> transl; + + if(transl > maxtransl) + maxtransl = transl; + + + for(int j=0; j<3; j++) + { + nodes1[j] = tris[tri1-1]->PNum(j+1); + sortval1[j] = Vec<3>(mesh[nodes1[j]])*randomvec; + nodes2[j] = tris[tri2-1]->PNum(j+1); + sortval2[j] = Vec<3>(mesh[nodes2[j]])*randomvec; + } + + BubbleSort(sortval1,nodes1); + BubbleSort(sortval2,nodes2); + + for(int j=0; j<3; j++) + mesh.GetIdentifications().Add(nodes1[j],nodes2[j],transl); + + } + for(int i=1; i<= maxtransl; i++) + mesh.GetIdentifications().SetType(i,Identifications::PERIODIC); + } + break; + + case 22: + // ElemID, FaceID0, FaceID1, FaceID2, FaceID3, PID + { + cout << "read elements (1)" << endl; + + //SurfaceElementIndex surf[4]; + bool neg[4]; + int elemid; + int domain; + + eldom.SetSize(nelts); + + for(int i=0; i> elemid; + for(int j=0; j<4;j++) + { + in >> dummyint; + neg[j] = (dummyint < 0); + if(neg[j]) + tetfacedata.Append(-dummyint-1); + //surf[j] = -dummyint-1; + else + tetfacedata.Append(dummyint-1); + tetfacedata.Append(((neg[j]) ? 1 : 0)); + //surf[j] = dummyint-1; + } + + in >> domain; + eldom[i] = domain; + tetfacedata.Append(domain); + + if(i==0 || domain < minId3D) + minId3D = domain; + + if(domain > maxId3D) + maxId3D = domain; + + // for(int j=0; j<4; j++) + // { + // if(mesh.GetNSE() <= surf[j]) + // continue; + + // int faceind = 0; + // for(int k=1; k<=mesh.GetNFD(); k++) + // { + // if(mesh.GetFaceDescriptor(k).SurfNr() == mesh[surf[j]].GetIndex()) + // faceind = k; + // } + // if(faceind) + // { + // if(neg[j]) + // mesh.GetFaceDescriptor(faceind).SetDomainOut(domain); + // else + // mesh.GetFaceDescriptor(faceind).SetDomainIn(domain); + // } + // else + // { + // if(neg[j]) + // faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf[j]].GetIndex(),0,domain,0)); + // else + // faceind = mesh.AddFaceDescriptor(FaceDescriptor(mesh[surf[j]].GetIndex(),domain,0,0)); + // mesh.GetFaceDescriptor(faceind).SetBCProperty(mesh[surf[j]].GetIndex()); + // } + // } + } + cout << endl; + + + // Array indextodescriptor(maxId2D+1); + + // for(int i=1; i<=mesh.GetNFD(); i++) + // indextodescriptor[mesh.GetFaceDescriptor(i).SurfNr()] = i; + + + // for(SurfaceElementIndex i=0; i> dummyint; + for(int j=1; j<=4; j++) + in >> el.PNum(j); + swap(el.PNum(1),el.PNum(2)); + + el.SetIndex(eldom[i]); + mesh.AddVolumeElement(el); + } + } + break; + + case 24: + // Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D) + { + in >> numObj3D; + userdata_int.Append(numObj3D); + in >> numObj2D; + userdata_int.Append(numObj2D); + in >> numObj1D; + userdata_int.Append(numObj1D); + in >> numObj0D; + userdata_int.Append(numObj0D); + } + break; + + case 25: + // Number of Ports (Ports are a subset of Object2D list) + { + in >> dummyint; + //userdata_int.Append(dummyint); + } + break; + + case 26: + // Object3D GroupID, #Elems ElemID List + { + uid_to_group_3D.SetSize(maxId3D+1); + uid_to_group_3D = -1; + for(int i=0; i> groupid; + (*testout) << "3d groupid " << groupid << endl; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + + (*testout) << "read " << dummyint << endl; + //userdata_int.Append(dummyint); + + if(dummyint < 0) + dummyint *= -1; + uid_to_group_3D[eldom[dummyint-1]] = groupid; + } + } + } + break; + + case 27: + // Object2D GroupID, #Faces FaceID List + { + Array ports; + //int totnum = 0; + uid_to_group_2D.SetSize(maxId2D+1); + uid_to_group_2D = -1; + + for(int i=0; i> groupid; + (*testout) << "2d groupid " << groupid << endl; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + char port; + while((port = in.get()) == ' ') + ; + + (*testout) << "read " << dummyint << endl; + if(dummyint < 0) + dummyint *= -1; + int uid = tris[dummyint-1]->GetIndex(); + + if(port == 'P' || port == 'p') + { + if(!ports.Contains(uid)) + ports.Append(uid); + } + else + in.putback(port); + + //userdata_int.Append(dummyint); + + uid_to_group_2D[uid] = groupid; + (*testout) << "setting " << uid << endl; + + //totnum++; + } + } + mesh.SetUserData("TETmesh:ports",ports); + } + break; + + case 28: + // Object1D GroupID, #Edges EdgeID List + { + uid_to_group_1D.SetSize(maxId1D+1); + uid_to_group_1D = -1; + + for(int i=0; i> groupid; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + //userdata_int.Append(dummyint); + + if(dummyint < 0) + dummyint *= -1; + uid_to_group_1D[(*segmentdata[dummyint-1])[2]] = groupid; + } + } + } + break; + + case 29: + // Object0D GroupID, #Nodes NodeID List + { + uid_to_group_0D.SetSize(maxId0D+1); + uid_to_group_0D = -1; + for(int i=0; i> groupid; + //userdata_int.Append(groupid); + int nelems; + in >> nelems; + //userdata_int.Append(nelems); + for(int j=0; j> dummyint; + //userdata_int.Append(dummyint); + + if(dummyint < 0) + dummyint *= -1; + uid_to_group_0D[point_pids[dummyint-1]] = groupid; + } + } + } + break; + + + + default: + done = true; + + } + + if(inputsection == 4 && version == "1.1") + inputsection++; + + inputsection++; + } + in.close(); + + + mesh.SetUserData("TETmesh:double",userdata_double); + userdata_int.Append(minId2D); + userdata_int.Append(minId3D); + mesh.SetUserData("TETmesh:int",userdata_int); + //if(version == "1.1") + mesh.SetUserData("TETmesh:point_id",point_pids); + + mesh.SetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D); + mesh.SetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D); + mesh.SetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D); + mesh.SetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D); + + + Array surfindices(tris.Size()); + surfindices = -1; + + for(int i=0; iGetIndex() > 0) + surfindices[i] = mesh.AddSurfaceElement(*tris[i]); + } + else + { + if(tris[i]->GetIndex() > 0 && + tris[i]->GetIndex() < minId3D) + { + tris[i]->SetIndex(tris[i]->GetIndex()-minId2D+1); + surfindices[i] = mesh.AddSurfaceElement(*tris[i]); + } + } + delete tris[i]; + } + + + mesh.ClearFaceDescriptors(); + if(atof(version.c_str()) <= 1.999999) + for(int i = 1; i <= maxId2D; i++) + mesh.AddFaceDescriptor(FaceDescriptor(i,0,0,0)); + else + for(int i=minId2D; i indextodescriptor(maxId2D+1); + + // for(int i=1; i<=mesh.GetNFD(); i++) + // indextodescriptor[mesh.GetFaceDescriptor(i).SurfNr()] = i; + + + // for(SurfaceElementIndex i=0; i 0) || + (atof(version.c_str()) > 1.999999 && (*segmentdata[i])[2] > 0 && (*segmentdata[i])[2] < minId2D)) + { + seg[0] = (*segmentdata[i])[0]; + seg[1] = (*segmentdata[i])[1]; + seg.edgenr = (*segmentdata[i])[2]; + seg.epgeominfo[0].edgenr = (*segmentdata[i])[2]; + seg.epgeominfo[1].edgenr = (*segmentdata[i])[2]; + seg.si = (*segmentdata[i])[3]-minId2D+1; + seg.surfnr1 = -1;//(*segmentdata[i])[3]; + seg.surfnr2 = -1;//(*segmentdata[i])[4]; + seg.geominfo[0].trignum = (*segmentdata[i])[5]; + seg.geominfo[1].trignum = (*segmentdata[i])[5]; + mesh.AddSegment(seg); + + seg[0] = (*segmentdata[i])[1]; + seg[1] = (*segmentdata[i])[0]; + seg.si = (*segmentdata[i])[4]-minId2D+1; + seg.surfnr1 = -1;//(*segmentdata[i])[3]; + seg.surfnr2 = -1;//(*segmentdata[i])[4]; + seg.geominfo[0].trignum = (*segmentdata[i])[6]; + seg.geominfo[1].trignum = (*segmentdata[i])[6]; + mesh.AddSegment(seg); + } + delete segmentdata[i]; + } + + /* + for(int i=mesh.GetNSeg(); i>=1; i--) + if(mesh.LineSegment(i).epgeominfo[0].edgenr == 0 || + mesh.LineSegment(i).epgeominfo[1].edgenr == 0) + mesh.FullDeleteSegment(i); + */ + + mesh.CalcSurfacesOfNode(); + + } +} + + diff --git a/libsrc/interface/readuser.cpp b/libsrc/interface/readuser.cpp new file mode 100644 index 00000000..f21466af --- /dev/null +++ b/libsrc/interface/readuser.cpp @@ -0,0 +1,422 @@ +// +// Read user dependent output file +// + + +#include + + +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + + void ReadFile (Mesh & mesh, + const string & hfilename) + { + cout << "Read User File" << endl; + + const char * filename = hfilename.c_str(); + + char reco[100]; + int np, nbe; + + + + // ".surf" - mesh + + if ( (strlen (filename) > 5) && + strcmp (&filename[strlen (filename)-5], ".surf") == 0 ) + + { + cout << "Surface file" << endl; + + ifstream in (filename); + + in >> reco; + in >> np; + for (int i = 1; i <= np; i++) + { + Point3d p; + in >> p.X() >> p.Y() >> p.Z(); + p.Z() *= 10; + mesh.AddPoint (p); + } + + mesh.ClearFaceDescriptors(); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + + in >> nbe; + // int invert = globflags.GetDefineFlag ("invertsurfacemesh"); + for (int i = 1; i <= nbe; i++) + { + Element2d el; + el.SetIndex(1); + + for (int j = 1; j <= 3; j++) + { + in >> el.PNum(j); + // el.PNum(j)++; + if (el.PNum(j) < PointIndex(1) || + el.PNum(j) > PointIndex(np)) + { + cerr << "Point Number " << el.PNum(j) << " out of range 1..." + << np << endl; + return; + } + } + /* + if (invert) + swap (el.PNum(2), el.PNum(3)); + */ + + mesh.AddSurfaceElement (el); + } + + + cout << "points: " << np << " faces: " << nbe << endl; + } + + + + + + if ( (strlen (filename) > 4) && + strcmp (&filename[strlen (filename)-4], ".unv") == 0 ) + { + char reco[100]; + int invert; + + ifstream in(filename); + + mesh.ClearFaceDescriptors(); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + + + while (in.good()) + { + in >> reco; + cout << "reco = " << reco << endl; + + if (strcmp (reco, "2411") == 0) + { + cout << "nodes found" << endl; + + while (1) + { + int pi, hi; + Point<3> p; + + in >> pi; + if (pi == -1) + break; + + in >> hi >> hi >> hi; + in >> p(0) >> p(1) >> p(2); + + cout << "p(" << pi << ") = " + << p << endl; + + mesh.AddPoint (p); + } + cout << "read " << mesh.GetNP() << " points" << endl; + } + + if (strcmp (reco, "2412") == 0) + { + cout << "elements found" << endl; + + while (1) + { + int label, fe_id, phys_prop, mat_prop, color, nnodes; + int nodes[100]; + int hi; + + in >> label; + if (label == -1) break; + in >> fe_id >> phys_prop >> mat_prop >> color >> nnodes; + + cout << "fe_id = " << fe_id << " col = " << color << ", nnodes = " << nnodes << endl; + + if (fe_id >= 11 && fe_id <= 32) + in >> hi >> hi >> hi; + + + for (int j = 0; j < nnodes; j++) + in >> nodes[j]; + + switch (fe_id) + { + case 41: + { + Element2d el (TRIG); + el.SetIndex (1); + for (int j = 0; j < nnodes; j++) + el[j] = nodes[j]; + mesh.AddSurfaceElement (el); + + break; + } + case 111: + { + Element el (TET); + el.SetIndex (1); + for (int j = 0; j < nnodes; j++) + el[j] = nodes[j]; + mesh.AddVolumeElement (el); + + break; + } + } + } + } + } + + + Point3d pmin, pmax; + mesh.GetBox (pmin, pmax); + cout << "bounding-box = " << pmin << "-" << pmax << endl; + } + + + + // fepp format2d: + + if ( (strlen (filename) > 7) && + strcmp (&filename[strlen (filename)-7], ".mesh2d") == 0 ) + { + cout << "Reading FEPP2D Mesh" << endl; + + char buf[100]; + int np, ne, nseg, i, j; + + ifstream in (filename); + + in >> buf; + + in >> nseg; + for (i = 1; i <= nseg; i++) + { + int bound, p1, p2; + in >> bound >> p1 >> p2; + // forget them + } + + in >> ne; + for (i = 1; i <= ne; i++) + { + int mat, nelp; + in >> mat >> nelp; + Element2d el (nelp == 3 ? TRIG : QUAD); + el.SetIndex (mat); + for (j = 1; j <= nelp; j++) + in >> el.PNum(j); + mesh.AddSurfaceElement (el); + } + + in >> np; + for (i = 1; i <= np; i++) + { + Point3d p(0,0,0); + in >> p.X() >> p.Y(); + mesh.AddPoint (p); + } + } + + + else if ( (strlen (filename) > 5) && + strcmp (&filename[strlen (filename)-5], ".mesh") == 0 ) + { + cout << "Reading Neutral Format" << endl; + + int np, ne, nse, i, j; + + ifstream in (filename); + + in >> np; + + if (in.good()) + { + // file starts with an integer + + for (i = 1; i <= np; i++) + { + Point3d p(0,0,0); + in >> p.X() >> p.Y() >> p.Z(); + mesh.AddPoint (p); + } + + in >> ne; + for (i = 1; i <= ne; i++) + { + int mat; + in >> mat; + Element el (4); + el.SetIndex (mat); + for (j = 1; j <= 4; j++) + in >> el.PNum(j); + mesh.AddVolumeElement (el); + } + + mesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0)); + + in >> nse; + for (i = 1; i <= nse; i++) + { + int mat; // , nelp; + in >> mat; + Element2d el (TRIG); + el.SetIndex (mat); + for (j = 1; j <= 3; j++) + in >> el.PNum(j); + mesh.AddSurfaceElement (el); + } + } + else + { + char buf[100]; + in.clear(); + do + { + in >> buf; + cout << "buf = " << buf << endl; + if (strcmp (buf, "points") == 0) + { + in >> np; + cout << "np = " << np << endl; + } + } + while (in.good()); + } + } + + + if ( (strlen (filename) > 4) && + strcmp (&filename[strlen (filename)-4], ".emt") == 0 ) + { + ifstream inemt (filename); + + string pktfile = filename; + int len = strlen (filename); + pktfile[len-3] = 'p'; + pktfile[len-2] = 'k'; + pktfile[len-1] = 't'; + cout << "pktfile = " << pktfile << endl; + + int np, nse, i; + int bcprop; + ifstream inpkt (pktfile.c_str()); + inpkt >> np; + Array values(np); + for (i = 1; i <= np; i++) + { + Point3d p(0,0,0); + inpkt >> p.X() >> p.Y() >> p.Z() + >> bcprop >> values.Elem(i); + mesh.AddPoint (p); + } + + mesh.ClearFaceDescriptors(); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + mesh.GetFaceDescriptor(1).SetBCProperty (1); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + mesh.GetFaceDescriptor(2).SetBCProperty (2); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + mesh.GetFaceDescriptor(3).SetBCProperty (3); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + mesh.GetFaceDescriptor(4).SetBCProperty (4); + mesh.AddFaceDescriptor (FaceDescriptor(0,1,0,0)); + mesh.GetFaceDescriptor(5).SetBCProperty (5); + + int p1, p2, p3; + double value; + inemt >> nse; + for (i = 1; i <= nse; i++) + { + inemt >> p1 >> p2 >> p3 >> bcprop >> value; + + if (bcprop < 1 || bcprop > 4) + cerr << "bcprop out of range, bcprop = " << bcprop << endl; + p1++; + p2++; + p3++; + if (p1 < 1 || p1 > np || p2 < 1 || p2 > np || p3 < 1 || p3 > np) + { + cout << "p1 = " << p1 << " p2 = " << p2 << " p3 = " << p3 << endl; + } + + if (i > 110354) Swap (p2, p3); + if (mesh.Point(p1)(0) < 0.25) + Swap (p2,p3); + + Element2d el(TRIG); + + if (bcprop == 1) + { + if (values.Get(p1) < -69999) + el.SetIndex(1); + else + el.SetIndex(2); + } + else + el.SetIndex(3); + + + el.PNum(1) = p1; + el.PNum(2) = p2; + el.PNum(3) = p3; + mesh.AddSurfaceElement (el); + } + + + ifstream incyl ("ngusers/guenter/cylinder.surf"); + int npcyl, nsecyl; + incyl >> npcyl; + cout << "npcyl = " << npcyl << endl; + for (i = 1; i <= npcyl; i++) + { + Point3d p(0,0,0); + incyl >> p.X() >> p.Y() >> p.Z(); + mesh.AddPoint (p); + } + incyl >> nsecyl; + cout << "nsecyl = " << nsecyl << endl; + for (i = 1; i <= nsecyl; i++) + { + incyl >> p1 >> p2 >> p3; + p1 += np; + p2 += np; + p3 += np; + Element2d el(TRIG); + el.SetIndex(5); + el.PNum(1) = p1; + el.PNum(2) = p2; + el.PNum(3) = p3; + mesh.AddSurfaceElement (el); + } + } + + + // .tet mesh + if ( (strlen (filename) > 4) && + strcmp (&filename[strlen (filename)-4], ".tet") == 0 ) + { + ReadTETFormat (mesh, filename); + } + + + // .fnf mesh (FNF - PE neutral format) + if ( (strlen (filename) > 4) && + strcmp (&filename[strlen (filename)-4], ".fnf") == 0 ) + { + ReadFNFFormat (mesh, filename); + } + + } + +} + diff --git a/libsrc/interface/writeOpenFOAM15x.cpp b/libsrc/interface/writeOpenFOAM15x.cpp new file mode 100644 index 00000000..a2541dae --- /dev/null +++ b/libsrc/interface/writeOpenFOAM15x.cpp @@ -0,0 +1,811 @@ +/*! \file writeOpenFOAM15x.cpp +* \brief Export Netgen Mesh in the OpenFOAM 1.5+ File format +* \author Philippose Rajan +* \date 25 October 2009 +* +* This function extends the export capabilities of +* Netgen to include the OpenFOAM 1.5+ File Format. +* +* The OpenFOAM 1.5+ mesh format consists of a set of 5 files +* which together define the mesh points, faces, cells and +* boundary conditions. +* +* The files are: +* 1. points -> A list of the point co-ordinates +* 2. faces -> A list of the faces with format (pnt_ind1 pnt_ind2 .... pnt_ind) +* 3. owner -> The owner cell of each face +* 4. neighbour -> The neighbour cell of each face +* 5. boundary -> The set of boundaries with name, start face, and num. of faces +* +* For a detailed description of the format, refer to the following link: +* http://openfoamwiki.net/index.php/Write_OpenFOAM_meshes +* +*/ + +#include + +#include +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + // Global arrays used to maintain the owner, neighbour and face lists + // so that they are accessible across functions + static Array owner_facelist; + static Array owner_celllist; + static Array neighbour_celllist; + static Array surfelem_bclist; + static Array surfelem_lists; + + + + static void WriteOpenFOAM15xBanner(ostream * outfile) + { + static char FOAMversion[4] = "1.5"; + static char spaces[40]; + + memset(spaces, ' ', 40); + spaces[38 - strlen(FOAMversion)] = '\0'; + + *outfile << + "/*--------------------------------*- C++ -*----------------------------------*\\\n"; + + *outfile << + "| ========= | |\n" + "| \\\\ / F ield | OpenFOAM: The Open Source CFD Toolbox |\n" + "| \\\\ / O peration | Version: " << FOAMversion << spaces << "|\n" + "| \\\\ / A nd | Web: http://www.OpenFOAM.org |\n" + "| \\\\/ M anipulation | |\n" + "\\*---------------------------------------------------------------------------*/\n"; + + } + + + + static void WriteOpenFOAM15xDividerStart(ostream * outfile) + { + *outfile << + "// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //\n"; + } + + + + static void WriteOpenFOAM15xDividerEnd(ostream * outfile) + { + *outfile << + "// ************************************************************************* //\n"; + } + + + + static bool BuildOwnerNeighbourLists (const Mesh & mesh) + { + // Clear all the arrays + owner_facelist.DeleteAll(); + owner_celllist.DeleteAll(); + neighbour_celllist.DeleteAll(); + surfelem_bclist.DeleteAll(); + surfelem_lists.DeleteAll(); + + const MeshTopology& meshtopo = mesh.GetTopology(); + + // Update the mesh topology structures + const_cast (meshtopo).SetBuildEdges(true); + const_cast (meshtopo).SetBuildFaces(true); + const_cast (meshtopo).Update(); + + // Extract important mesh metrics + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int totfaces = meshtopo.GetNFaces(); + + // Preset the size of the arrays to speed up future operations + // Number of internal faces = total faces - num. of surface faces + owner_facelist.SetSize(totfaces - nse); + owner_celllist.SetSize(totfaces - nse); + neighbour_celllist.SetSize(totfaces - nse); + surfelem_bclist.SetSize(nse); + surfelem_lists.SetSize(nse); + + // Initialise arrays to zero if required + neighbour_celllist = 0; + + // Array used to keep track of Faces which have already been + // processed and added to the Owner list... In addition, also the + // location where the face appears in the Owner list is also stored + // to speed up creation of the Neighbour list + Array ownerfaces(totfaces); + ownerfaces = 0; + + // Array to hold the set of local faces of each volume element + // while running through the set of volume elements + // NOTE: The size is set automatically by the Netgen topology function + Array locfaces; + + // Secondary indices used to independently advance the owner + // and boundary condition arrays within the main loop + int owner_ind = 1; + int bc_ind = 1; + + // Loop through all the volume elements + for(int elind = 1; elind <= ne; elind++) + { + // Extract the current volume element + // const Element & el = mesh.VolumeElement(elind); + + // Get the face numbers of the faces of the current volume element + // The values returned are given a sign depending on the orientation + // of the faces. This is used while writing the faces file, to + // determine whether or not to invert the face triangle before writing + // it to file + meshtopo.GetElementFaces(elind,locfaces,true); + + // Loop through the faces + for(int i = 1; i <= locfaces.Size(); i++) + { + // The absolute value of a face number (because the faces + // returned by the GetElementFaces function prepend it + // with a sign depending on the face orientation) + int absfacenr = abs(locfaces.Elem(i)); + + // If the face already exists in the owner list, add + // the current cell into the neighbour list, in the + // same location where the face appears in the owner list + int owner_face = ownerfaces.Elem(absfacenr); + if(owner_face) + { + neighbour_celllist.Elem(owner_face) = elind; + + // From this point on, the code within this "if" block + // basically sorts the order of the the Neighbour cells (along + // with the faces list) in ascending order. + // The approach used is..... to traverse the owner and neighbour cell lists + // up and down, and sort the neighbour cells of a given owner cell + // as the list evolves. + // NOTE: A value of "zero" in the neighbour list implies that + // the neighbour has not been found yet, so the "zero" locations need + // to be skipped while sorting in ascending order + int curr_owner = owner_celllist.Elem(owner_face); + + int peek_loc = owner_face - 1; + int new_loc = owner_face; + + // Traversing upwards in the list + while((owner_celllist.Elem(peek_loc) == curr_owner) && (peek_loc >= 1)) + { + if((neighbour_celllist.Elem(peek_loc) != 0) + && (neighbour_celllist.Elem(new_loc) < neighbour_celllist.Elem(peek_loc))) + { + Swap(neighbour_celllist.Elem(new_loc),neighbour_celllist.Elem(peek_loc)); + Swap(owner_facelist.Elem(new_loc),owner_facelist.Elem(peek_loc)); + new_loc = peek_loc; + } + + peek_loc--; + } + + peek_loc = owner_face + 1; + + // Traversing downwards in the list + while((owner_celllist.Elem(peek_loc) == curr_owner) && (peek_loc <= owner_ind)) + { + if((neighbour_celllist.Elem(peek_loc) != 0) + && (neighbour_celllist.Elem(new_loc) > neighbour_celllist.Elem(peek_loc))) + { + Swap(neighbour_celllist.Elem(new_loc),neighbour_celllist.Elem(peek_loc)); + Swap(owner_facelist.Elem(new_loc),owner_facelist.Elem(peek_loc)); + new_loc = peek_loc; + } + + peek_loc++; + } + + continue; + } + + // Check if the face is a surface element (boundary face) + // if not, add the current volume element and the corresponding face into + // the owner list + int surfelem = meshtopo.GetFace2SurfaceElement(absfacenr); + if(!surfelem) + { + // If it is a new face which has not been listed before, + // add the current cell into the owner list, and save + // the index location to be used later by the neighbour list + owner_celllist.Elem(owner_ind) = elind; + owner_facelist.Elem(owner_ind) = locfaces.Elem(i); + // Update the array to indicate that the face is already processed + ownerfaces.Elem(absfacenr) = owner_ind; + + owner_ind++; + } + // If the face is a boundary face, extract the boundary condition number of the + // face, and append that along with the face number and the current cell + // into the various surface elements lists + else + { + Element2d sel = mesh.SurfaceElement(surfelem); + surfelem_bclist.Elem(bc_ind) = mesh.GetFaceDescriptor(sel.GetIndex()).BCProperty(); + surfelem_lists.Elem(bc_ind) = INDEX_2(locfaces.Elem(i),elind); + + bc_ind++; + } + } + } + + // This correction is required in cases where the mesh has been "uniform refined".... for + // some reason, the number of faces reported by Netgen is higher than the actual number + // of faces in the mesh + owner_facelist.SetSize(owner_ind-1); + owner_celllist.SetSize(owner_ind-1); + neighbour_celllist.SetSize(owner_ind-1); + + + // Sort the list of surface elements in ascending order of boundary condition number + // also sort the cell list in the same manner + QuickSort(surfelem_bclist,surfelem_lists); + +/* + // Debugging output to a file + ofstream dbg("OpenFOAMDebug.log"); + + dbg << " ------- Boundary List -------- \n"; + + for(int i = 1; i <= surfelem_bclist.Size(); i++) + { + dbg << "bc = " << surfelem_bclist.Elem(i) + << " : face = " << surfelem_lists.Elem(i).I1() + << " : cell = " << surfelem_lists.Elem(i).I2() << "\n"; + } + + dbg << "\n ------- Owner / Face / Neighbour List ------- \n"; + + for(int i = 1; i <= owner_celllist.Size(); i++) + { + dbg << "Ind:" << i << " :: (" + << owner_celllist.Elem(i) << " " + << owner_facelist.Elem(i) << " " + << neighbour_celllist.Elem(i) << ")\n"; + } + + dbg.close(); +*/ + return(false); + } + + + + static void WriteNeighbourFile (ostream * outfile) + { + // Write the OpenFOAM standard banner and dividers, etc... + WriteOpenFOAM15xBanner(outfile); + *outfile << "FoamFile \n" + << "{ \n" + << " version 2.0; \n" + << " format ascii; \n" + << " class labelList; \n" + << " note \"Mesh generated and converted using NETGEN-" << PACKAGE_VERSION << "\"; \n" + << " location \"constant\\polyMesh\"; \n" + << " object neighbour; \n" + << "} \n"; + WriteOpenFOAM15xDividerStart(outfile); + + *outfile << "\n\n"; + + int nneighbours = neighbour_celllist.Size(); + + *outfile << nneighbours << "\n"; + + *outfile << "(\n"; + + // Write the neighbour cells to file + for(int i = 1; i <= neighbour_celllist.Size(); i++) + { + *outfile << neighbour_celllist.Elem(i) - 1 << "\n"; + } + *outfile << ")\n\n"; + WriteOpenFOAM15xDividerEnd(outfile); + } + + + + static void WriteOwnerFile (ostream * outfile) + { + // Write the OpenFOAM standard banner and dividers, etc... + WriteOpenFOAM15xBanner(outfile); + *outfile << "FoamFile \n" + << "{ \n" + << " version 2.0; \n" + << " format ascii; \n" + << " class labelList; \n" + << " note \"Mesh generated and converted using NETGEN-" << PACKAGE_VERSION << "\"; \n" + << " location \"constant\\polyMesh\"; \n" + << " object owner; \n" + << "} \n"; + WriteOpenFOAM15xDividerStart(outfile); + + *outfile << "\n\n"; + + int nowners = owner_celllist.Size() + surfelem_lists.Size(); + + *outfile << nowners << "\n"; + + *outfile << "(\n"; + + // Write the owners of the internal cells to file + for(int i = 1; i <= owner_celllist.Size(); i++) + { + *outfile << owner_celllist.Elem(i) - 1 << "\n"; + } + + // Write the owners of the boundary cells to file + // (Written in order of ascending boundary condition numbers) + for(int i = 1; i <= surfelem_lists.Size(); i++) + { + *outfile << surfelem_lists.Elem(i).I2() - 1 << "\n"; + } + *outfile << ")\n\n"; + WriteOpenFOAM15xDividerEnd(outfile); + } + + + + static void WriteFacesFile (ostream * outfile, const Mesh & mesh) + { + const MeshTopology& meshtopo = mesh.GetTopology(); + + // Write the OpenFOAM standard banner and dividers, etc... + WriteOpenFOAM15xBanner(outfile); + *outfile << "FoamFile \n" + << "{ \n" + << " version 2.0; \n" + << " format ascii; \n" + << " class faceList; \n" + << " note \"Mesh generated and converted using NETGEN-" << PACKAGE_VERSION << "\"; \n" + << " location \"constant\\polyMesh\"; \n" + << " object faces; \n" + << "} \n"; + WriteOpenFOAM15xDividerStart(outfile); + + *outfile << "\n\n"; + + int nfaces = owner_facelist.Size() + surfelem_lists.Size(); + + *outfile << nfaces << "\n"; + + *outfile << "(\n"; + + // Array to hold the indices of the points of each face to + // flip if required + Array facepnts; + + // Write the faces in the order specified in the owners lists of the + // internal cells and the boundary cells + for(int i = 1; i <= owner_facelist.Size(); i++) + { + int face_w_orientation = owner_facelist.Elem(i); + int facenr = abs(face_w_orientation); + + meshtopo.GetFaceVertices(facenr,facepnts); + + // Get the orientation of the face, and invert it if required + // Since the faces already have the orientation "embedded" into + // them by means of the prepended sign, only this needs to be + // checked for... + if(face_w_orientation > 0) + { + int tmppnts = 0; + + if(facepnts.Size() == 4) + { + tmppnts = facepnts.Elem(1); + facepnts.Elem(1) = facepnts.Elem(2); + facepnts.Elem(2) = tmppnts; + + tmppnts = facepnts.Elem(3); + facepnts.Elem(3) = facepnts.Elem(4); + facepnts.Elem(4) = tmppnts; + } + else if(facepnts.Size() == 3) + { + tmppnts = facepnts.Elem(1); + facepnts.Elem(1) = facepnts.Elem(3); + facepnts.Elem(3) = tmppnts; + } + } + + *outfile << facepnts.Size(); + *outfile << "("; + for(int j = 1; j <= facepnts.Size(); j++) + { + *outfile << facepnts.Elem(j)-1; + if(j != facepnts.Size()) *outfile << " "; + } + *outfile << ")\n"; + } + + // Now append the faces of the surface elements (written in + // ascending order of boundary condition number) also into + // the faces file + for(int i = 1; i <= surfelem_lists.Size(); i++) + { + int face_w_orientation = surfelem_lists.Elem(i).I1(); + int facenr = abs(face_w_orientation); + + meshtopo.GetFaceVertices(facenr,facepnts); + + // Get the orientation of the face, and invert it if required + if(face_w_orientation > 0) + { + int tmppnts = 0; + + if(facepnts.Size() == 4) + { + tmppnts = facepnts.Elem(1); + facepnts.Elem(1) = facepnts.Elem(2); + facepnts.Elem(2) = tmppnts; + + tmppnts = facepnts.Elem(3); + facepnts.Elem(3) = facepnts.Elem(4); + facepnts.Elem(4) = tmppnts; + } + else if(facepnts.Size() == 3) + { + tmppnts = facepnts.Elem(1); + facepnts.Elem(1) = facepnts.Elem(3); + facepnts.Elem(3) = tmppnts; + } + } + + *outfile << facepnts.Size(); + *outfile << "("; + for(int j = 1; j <= facepnts.Size(); j++) + { + *outfile << facepnts.Elem(j)-1; + if(j != facepnts.Size()) *outfile << " "; + } + *outfile << ")\n"; + } + + *outfile << ")\n\n"; + WriteOpenFOAM15xDividerEnd(outfile); + } + + + + static void WritePointsFile (ostream * outfile, const Mesh & mesh) + { + int np = mesh.GetNP(); + + // Write the OpenFOAM standard banner and dividers, etc... + WriteOpenFOAM15xBanner(outfile); + *outfile << "FoamFile \n" + << "{ \n" + << " version 2.0; \n" + << " format ascii; \n" + << " class vectorField; \n" + << " note \"Mesh generated and converted using NETGEN-" << PACKAGE_VERSION << "\"; \n" + << " location \"constant\\polyMesh\"; \n" + << " object points; \n" + << "} \n"; + WriteOpenFOAM15xDividerStart(outfile); + + *outfile << "\n\n"; + + // Number of points in the following list + *outfile << np << "\n"; + + outfile->precision(6); + outfile->setf (ios::fixed, ios::floatfield); + outfile->setf (ios::showpoint); + + // Coordinate list starts here + *outfile << "(\n"; + + for(int i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + + // Write coordinates to file + *outfile << "("; + *outfile << p.X() << " "; + *outfile << p.Y() << " "; + *outfile << p.Z(); + *outfile << ")\n"; + } + *outfile << ")\n\n"; + WriteOpenFOAM15xDividerEnd(outfile); + } + + + + static void WriteBoundaryFile (ostream * outfile) + { + // Write the OpenFOAM standard banner and dividers, etc... + WriteOpenFOAM15xBanner(outfile); + *outfile << "FoamFile \n" + << "{ \n" + << " version 2.0; \n" + << " format ascii; \n" + << " class polyBoundaryMesh; \n" + << " note \"Mesh generated and converted using NETGEN-" << PACKAGE_VERSION << "\"; \n" + << " location \"constant\\polyMesh\"; \n" + << " object boundary; \n" + << "} \n"; + WriteOpenFOAM15xDividerStart(outfile); + + *outfile << "\n"; + + + Array bcarray; + int ind = 1; + + // Since the boundary conditions are already sorted in ascending + // order, the last element will give the maximum number of possible + // boundary condition entries + int bcmax = surfelem_bclist.Elem(surfelem_bclist.Size()); + + bcarray.SetSize(bcmax+1); + + bcarray.Elem(ind) = INDEX_3(surfelem_bclist.Elem(1),1,0); + + for(int i = 2; i <= surfelem_bclist.Size(); i++) + { + if(surfelem_bclist.Elem(i) == bcarray.Elem(ind).I1()) + { + bcarray.Elem(ind).I2() = bcarray.Elem(ind).I2()+1; + } + else + { + ind++; + bcarray.Elem(ind) = INDEX_3(surfelem_bclist.Elem(i),1,i-1); + } + } + + bcarray.SetSize(ind); + + *outfile << bcarray.Size() << "\n"; + *outfile << "(\n"; + + int startface = 0; + + for(int i = 1; i <= bcarray.Size(); i++) + { + startface = owner_celllist.Size() + bcarray.Elem(i).I3(); + + *outfile << " patch" << bcarray.Elem(i).I1() << "\n" + << " {\n" + << " type patch;\n" + << " physicalType patch;\n" + << " nFaces " << bcarray.Elem(i).I2() << ";\n" + << " startFace " << startface << ";\n" + << " }\n"; + } + + *outfile << ")\n\n"; + WriteOpenFOAM15xDividerEnd(outfile); + } + + + + void WriteOpenFOAM15xFormat (const Mesh & mesh, const string & casename, const bool compressed) + { + bool error = false; + char casefiles[256]; + + // Make sure that the mesh data has been updated + const_cast (mesh).Compress(); + const_cast (mesh).CalcSurfacesOfNode(); + const_cast (mesh).RebuildSurfaceElementLists(); + const_cast (mesh).BuildElementSearchTree(); + + + int np = mesh.GetNP(); + int nse = mesh.GetNSE(); + int ne = mesh.GetNE(); + + cout << "Write OpenFOAM 1.5+ Mesh Files....\n"; + + // Abort if there are no points, surface elements or volume elements + if((np <= 0) || (ne <= 0) || (nse <= 0)) + { + cout << "Export Error: Invalid mesh.... Aborting!\n"; + return; + } + + // OpenFOAM only supports linear meshes! + if(mparam.secondorder || mesh.GetCurvedElements().IsHighOrder()) + { + cout << "Export Error: OpenFOAM 1.5+ does not support non-linear elements.... Aborting!\n"; + return; + } + + if(( (mesh.SurfaceElement(nse/2).GetType() != TRIG) + && (mesh.SurfaceElement(nse/2).GetType() != QUAD) ) + || (mesh.VolumeElement(ne/2).GetType() == TET10) + || (mesh.VolumeElement(ne/2).GetType() == PRISM12)) + { + cout << "Export Error: OpenFOAM 1.5+ does not support non-linear elements.... Aborting!\n"; + return; + } + + + cout << "Writing OpenFOAM 1.5+ Mesh files to case: " << casename << "\n"; + + // Create the case directory if it does not already exist + // NOTE: This needs to be improved for the Linux variant....!!! + #ifdef WIN32 + char casedir[256]; + sprintf(casedir, "mkdir %s\\constant\\polyMesh", casename.c_str()); + system(casedir); + #else + char casedir[256]; + mkdir(casename.c_str(), S_IRWXU|S_IRWXG); + sprintf(casedir, "%s/constant", casename.c_str()); + mkdir(casedir, S_IRWXU|S_IRWXG); + sprintf(casedir, "%s/constant/polyMesh", casename.c_str()); + mkdir(casedir, S_IRWXU|S_IRWXG); + #endif + + // Open handles to the five required mesh files + // points + // faces + // owner + // neighbour + // boundary + ostream *outfile_pnts; + ostream *outfile_faces; + ostream *outfile_own; + ostream *outfile_nei; + ostream *outfile_bnd; + + if(compressed) + { + sprintf(casefiles, "%s/constant/polyMesh/points.gz", casename.c_str()); + outfile_pnts = new ogzstream(casefiles); + } + else + { + sprintf(casefiles, "%s/constant/polyMesh/points", casename.c_str()); + outfile_pnts = new ofstream(casefiles); + } + + if(compressed) + { + sprintf(casefiles, "%s/constant/polyMesh/faces.gz", casename.c_str()); + outfile_faces = new ogzstream(casefiles); + } + else + { + sprintf(casefiles, "%s/constant/polyMesh/faces", casename.c_str()); + outfile_faces = new ofstream(casefiles); + } + + if(compressed) + { + sprintf(casefiles, "%s/constant/polyMesh/owner.gz", casename.c_str()); + outfile_own = new ogzstream(casefiles); + } + else + { + sprintf(casefiles, "%s/constant/polyMesh/owner", casename.c_str()); + outfile_own = new ofstream(casefiles); + } + + if(compressed) + { + sprintf(casefiles, "%s/constant/polyMesh/neighbour.gz", casename.c_str()); + outfile_nei = new ogzstream(casefiles); + } + else + { + sprintf(casefiles, "%s/constant/polyMesh/neighbour", casename.c_str()); + outfile_nei = new ofstream(casefiles); + } + + // Note... the boundary file is not compressed + sprintf(casefiles, "%s/constant/polyMesh/boundary", casename.c_str()); + outfile_bnd = new ofstream(casefiles); + + ResetTime(); + + // Build the owner, neighbour, faces and boundary lists + // from the Netgen mesh + cout << "\nBuilding Owner, Neighbour and Face Lists: "; + + error = BuildOwnerNeighbourLists(mesh); + + cout << "Done! (Time Elapsed = " << GetTime() << " sec)\n"; + + + // Write the "owner" file + if(outfile_own->good() && !error) + { + cout << "Writing the owner file: "; + WriteOwnerFile(outfile_own); + delete outfile_own; + cout << "Done! (Time Elapsed = " << GetTime() << " sec)\n"; + } + else + { + cout << "Export Error: Error creating file: owner.... Aborting\n"; + error = true; + } + + + // Write the "neighbour" file + if(outfile_nei->good() && !error) + { + cout << "Writing the neighbour file: "; + WriteNeighbourFile(outfile_nei); + delete outfile_nei; + cout << "Done! (Time Elapsed = " << GetTime() << " sec)\n"; + } + else + { + cout << "Export Error: Error creating file: neighbour.... Aborting\n"; + error = true; + } + + + // Write the "faces" file + if(outfile_faces->good() && !error) + { + cout << "Writing the faces file: "; + WriteFacesFile(outfile_faces, mesh); + delete outfile_faces; + cout << "Done! (Time Elapsed = " << GetTime() << " sec)\n"; + } + else + { + cout << "Export Error: Error creating file: faces.... Aborting\n"; + error = true; + } + + + // Write the "points" file + if(outfile_pnts->good() && !error) + { + cout << "Writing the points file: "; + WritePointsFile(outfile_pnts,mesh); + delete outfile_pnts; + cout << "Done! (Time Elapsed = " << GetTime() << " sec)\n"; + } + else + { + cout << "Export Error: Error creating file: points.... Aborting\n"; + error = true; + } + + + // Write the "boundary" file + if(outfile_bnd->good() && !error) + { + cout << "Writing the boundary file: "; + WriteBoundaryFile(outfile_bnd); + delete outfile_bnd; + cout << "Done! (Time Elapsed = " << GetTime() << " sec)\n"; + } + else + { + cout << "Export Error: Error creating file: boundary.... Aborting\n"; + error = true; + } + + if(!error) + { + cout << "OpenFOAM 1.5+ Export successfully completed (Time elapsed = " << GetTime() << " sec) !\n"; + } + else + { + cout << "Error in OpenFOAM 1.5+ Export.... Aborted!\n"; + } + } +} + diff --git a/libsrc/interface/writeabaqus.cpp b/libsrc/interface/writeabaqus.cpp new file mode 100644 index 00000000..6f2f165c --- /dev/null +++ b/libsrc/interface/writeabaqus.cpp @@ -0,0 +1,237 @@ +// +// Write Abaqus file +// +// + +#include + +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + + + + +void WriteAbaqusFormat (const Mesh & mesh, + const string & filename) + +{ + + cout << "\nWrite Abaqus Volume Mesh" << endl; + + ofstream outfile (filename.c_str()); + + outfile << "*Heading" << endl; + outfile << " " << filename << endl; + + outfile.precision(8); + + outfile << "*Node" << endl; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int i, j, k; + + for (i = 1; i <= np; i++) + { + outfile << i << ", "; + outfile << mesh.Point(i)(0) << ", "; + outfile << mesh.Point(i)(1) << ", "; + outfile << mesh.Point(i)(2) << "\n"; + } + + int elemcnt = 0; //element counter + int finished = 0; + int indcnt = 1; //index counter + + while (!finished) + { + int actcnt = 0; + const Element & el1 = mesh.VolumeElement(1); + int non = el1.GetNP(); + if (non == 4) + { + outfile << "*Element, type=C3D4, ELSET=PART" << indcnt << endl; + } + else if (non == 10) + { + outfile << "*Element, type=C3D10, ELSET=PART" << indcnt << endl; + } + else + { + cout << "unsupported Element type!!!" << endl; + } + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + + if (el.GetIndex() == indcnt) + { + actcnt++; + if (el.GetNP() != non) + { + cout << "different element-types in a subdomain are not possible!!!" << endl; + continue; + } + + elemcnt++; + outfile << elemcnt << ", "; + if (non == 4) + { + outfile << el.PNum(1) << ", "; + outfile << el.PNum(2) << ", "; + outfile << el.PNum(4) << ", "; + outfile << el.PNum(3) << "\n"; + } + else if (non == 10) + { + outfile << el.PNum(1) << ", "; + outfile << el.PNum(2) << ", "; + outfile << el.PNum(4) << ", "; + outfile << el.PNum(3) << ", "; + outfile << el.PNum(5) << ", "; + outfile << el.PNum(9) << ", "; + outfile << el.PNum(7) << ", " << "\n"; + outfile << el.PNum(6) << ", "; + outfile << el.PNum(8) << ", "; + outfile << el.PNum(10) << "\n"; + } + else + { + cout << "unsupported Element type!!!" << endl; + for (j = 1; j <= el.GetNP(); j++) + { + outfile << el.PNum(j); + if (j != el.GetNP()) outfile << ", "; + } + outfile << "\n"; + } + } + } + indcnt++; + if (elemcnt == ne) {finished = 1; cout << "all elements found by Index!" << endl;} + if (actcnt == 0) {finished = 1;} + } + + if (mesh.GetIdentifications().GetMaxNr()) + { + // periodic identification, implementation for + // Helmut J. Boehm, TU Vienna + + char cfilename[255]; + strcpy (cfilename, filename.c_str()); + + char mpcfilename[255]; + strcpy (mpcfilename, cfilename); + size_t len = strlen (cfilename); + if (len >= 4 && (strcmp (mpcfilename+len-4, ".inp") == 0)) + strcpy (mpcfilename+len-4, ".mpc"); + else + strcat (mpcfilename, ".mpc"); + + ofstream mpc (mpcfilename); + + int masternode(0); + + Array pairs; + BitArray master(np), help(np); + master.Set(); + for (i = 1; i <= 3; i++) + { + mesh.GetIdentifications().GetPairs (i, pairs); + help.Clear(); + for (j = 1; j <= pairs.Size(); j++) + { + help.Set (pairs.Get(j).I1()); + } + master.And (help); + } + for (i = 1; i <= np; i++) + if (master.Test(i)) + masternode = i; + + cout << "masternode = " << masternode << " = " + << mesh.Point(masternode) << endl; + Array slaves(3); + for (i = 1; i <= 3; i++) + { + mesh.GetIdentifications().GetPairs (i, pairs); + for (j = 1; j <= pairs.Size(); j++) + { + if (pairs.Get(j).I1() == masternode) + slaves.Elem(i) = pairs.Get(j).I2(); + } + cout << "slave(" << i << ") = " << slaves.Get(i) + << " = " << mesh.Point(slaves.Get(i)) << endl; + } + + + outfile << "**\n" + << "*NSET,NSET=CTENODS\n" + << slaves.Get(1) << ", " + << slaves.Get(2) << ", " + << slaves.Get(3) << endl; + + + outfile << "**\n" + << "**POINT_fixed\n" + << "**\n" + << "*BOUNDARY, OP=NEW\n"; + for (j = 1; j <= 3; j++) + outfile << masternode << ", " << j << ",, 0.\n"; + + outfile << "**\n" + << "*BOUNDARY, OP=NEW\n"; + for (j = 1; j <= 3; j++) + { + Vec3d v(mesh.Point(masternode), mesh.Point(slaves.Get(j))); + double vlen = v.Length(); + int dir = 0; + if (fabs (v.X()) > 0.9 * vlen) dir = 2; + if (fabs (v.Y()) > 0.9 * vlen) dir = 3; + if (fabs (v.Z()) > 0.9 * vlen) dir = 1; + if (!dir) + cout << "ERROR: Problem with rigid body constraints" << endl; + outfile << slaves.Get(j) << ", " << dir << ",, 0.\n"; + } + + outfile << "**\n" + << "*EQUATION, INPUT=" << mpcfilename << endl; + + + BitArray eliminated(np); + eliminated.Clear(); + for (i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) + { + mesh.GetIdentifications().GetPairs (i, pairs); + if (!pairs.Size()) + continue; + + for (j = 1; j <= pairs.Size(); j++) + if (pairs.Get(j).I1() != masternode && + !eliminated.Test(pairs.Get(j).I2())) + { + eliminated.Set (pairs.Get(j).I2()); + for (k = 1; k <= 3; k++) + { + mpc << "4" << "\n"; + mpc << pairs.Get(j).I2() << "," << k << ", -1.0, "; + mpc << pairs.Get(j).I1() << "," << k << ", 1.0, "; + mpc << slaves.Get(i) << "," << k << ", 1.0, "; + mpc << masternode << "," << k << ", -1.0 \n"; + } + } + } + } + + + cout << "done" << endl; +} + +} diff --git a/libsrc/interface/writediffpack.cpp b/libsrc/interface/writediffpack.cpp new file mode 100644 index 00000000..07a21b2a --- /dev/null +++ b/libsrc/interface/writediffpack.cpp @@ -0,0 +1,325 @@ +// +// Write diffpack file +// +// by +// Bartosz Sawicki +// extended by +// Jacques Lechelle +// +#include + +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + +void WriteDiffPackFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + // double scale = globflags.GetNumFlag ("scale", 1); + double scale = 1; + + ofstream outfile(filename.c_str()); + outfile.precision(14); + + + if (mesh.GetDimension() == 3) + + { + // Output compatible to Diffpack grid format + // Bartosz Sawicki + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + Array BIname; + Array BCsinpoint; + int i, j, k, l; + + + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + const Element & eldummy = mesh.VolumeElement((int)1); + outfile << "\n\n" + "Finite element mesh (GridFE):\n\n" + " Number of space dim. = 3\n" + " Number of elements = " << ne << "\n" + " Number of nodes = " << np << "\n\n" + " All elements are of the same type : dpTRUE\n" + " Max number of nodes in an element: "<< eldummy.GetNP() << "\n" + " Only one subdomain : dpFALSE\n" + " Lattice data ? 0\n\n\n\n"; + + for (i = 1; i <= nse; i++) + { + int BI=mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex()).BCProperty(); + int nbi=BIname.Size(); + int found=0; + for (j = 1; j <= nbi; j++) + if(BI == BIname.Get(j)) found = 1; + if( ! found ) BIname.Append(BI); + } + + outfile << " " << BIname.Size() << " Boundary indicators: "; + for (i =1 ; i <= BIname.Size(); i++) + outfile << BIname.Get(i) << " "; + outfile << "\n\n\n"; + + outfile << " Nodal coordinates and nodal boundary indicators,\n" + " the columns contain:\n" + " - node number\n" + " - coordinates\n" + " - no of boundary indicators that are set (ON)\n" + " - the boundary indicators that are set (ON) if any.\n" + "#\n"; + + + // setup point-to-surfaceelement table + TABLE point2sel(np); + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = mesh[sei]; + for (int j = 0; j < el.GetNP(); j++) + point2sel.Add (el[j], sei); + } + + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + + outfile.width(12); + outfile << i << " ("; + outfile.width(16); + outfile << p.X()/scale << ", "; + outfile.width(16); + outfile << p.Y()/scale << ", "; + outfile.width(16); + outfile << p.Z()/scale << ") "; + + if(mesh[PointIndex(i)].Type() != INNERPOINT) + { + BCsinpoint.DeleteAll(); + /* + for (j = 1; j <= nse; j++) + */ + FlatArray sels = point2sel[i]; + for (int jj = 0; jj < sels.Size(); jj++) + { + for (k = 1; k <= mesh[sels[jj]].GetNP(); k++) + { + if(mesh[sels[jj]].PNum(k)==i) + { + int BC=mesh.GetFaceDescriptor(mesh[sels[jj]].GetIndex()).BCProperty(); + int nbcsp=BCsinpoint.Size(); + int found = 0; + for (l = 1; l <= nbcsp; l++) + if(BC == BCsinpoint.Get(l)) found = 1; + if( ! found ) BCsinpoint.Append(BC); + } + } + } + int nbcsp = BCsinpoint.Size(); + outfile << "[" << nbcsp << "] "; + for (j = 1; j <= nbcsp; j++) + outfile << BCsinpoint.Get(j) << " "; + outfile << "\n"; + } + else outfile << "[0]\n"; + + } + + outfile << "\n" + " Element types and connectivity\n" + " the columns contain:\n" + " - element number\n" + " - element type\n" + " - subdomain number\n" + " - the global node numbers of the nodes in the element.\n" + "#\n"; + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + outfile.width(5); + if(el.GetNP()==4) + outfile << i << " ElmT4n3D "; + else + outfile << i << " ElmT10n3D "; + outfile.width(4); + outfile << el.GetIndex() << " "; + if(el.GetNP()==10) + { + outfile.width(8); + outfile << el.PNum(1); + outfile.width(8); + outfile << el.PNum(3); + outfile.width(8); + outfile << el.PNum(2); + outfile.width(8); + outfile << el.PNum(4); + outfile.width(8); + outfile << el.PNum(6); + outfile.width(8); + outfile << el.PNum(8); + outfile.width(8); + outfile << el.PNum(5); + outfile.width(8); + outfile << el.PNum(7); + outfile.width(8); + outfile << el.PNum(10); + outfile.width(8); + outfile << el.PNum(9); + } + else + { + outfile.width(8); + outfile << el.PNum(1); + outfile.width(8); + outfile << el.PNum(3); + outfile.width(8); + outfile << el.PNum(2); + outfile.width(8); + outfile << el.PNum(4); + } + outfile << "\n"; + } + } /* Diffpack */ + + else + + { + // Output compatible to Diffpack grid format 2D + + int np = mesh.GetNP(); + //int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + Array BIname; + Array BCsinpoint; + int i, j, k, l; + + + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + const Element2d & eldummy = mesh.SurfaceElement((int)1); + outfile << "\n\n" + "Finite element mesh (GridFE):\n\n" + " Number of space dim. = 2\n" + " Number of elements = " << nse << "\n" + " Number of nodes = " << np << "\n\n" + " All elements are of the same type : dpTRUE\n" + " Max number of nodes in an element: "< + + +#include + +#include +#include +#include +#include + +namespace netgen +{ + +#include "writeuser.hpp" + + + + void WriteDolfinFormat (const Mesh & mesh, const string & filename) + { + cout << "start writing dolfin export" << endl; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + // int nse = mesh.GetNSE(); + int nsd = mesh.GetDimension(); + // int invertsurf = mparam.inverttrigs; + // int i, j; + + ofstream outfile (filename.c_str()); + + // char str[100]; + outfile.precision(8); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + if ( nsd == 3) { + + outfile << "" <"<" <"<"<"<"<"<"<"<"< + +#include +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + + +void WriteElmerFormat (const Mesh &mesh, + const string &filename) +{ + cout << "write elmer mesh files" << endl; + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int i, j; + char str[200]; + + int inverttets = mparam.inverttets; + int invertsurf = mparam.inverttrigs; + +#ifdef WIN32 + char a[256]; + sprintf( a, "mkdir %s", filename.c_str() ); + system( a ); +#else + // int rc = + mkdir(filename.c_str(), S_IRWXU|S_IRWXG); +#endif + + sprintf( str, "%s/mesh.header", filename.c_str() ); + ofstream outfile_h(str); + sprintf( str, "%s/mesh.nodes", filename.c_str() ); + ofstream outfile_n(str); + sprintf( str, "%s/mesh.elements", filename.c_str() ); + ofstream outfile_e(str); + sprintf( str, "%s/mesh.boundary", filename.c_str() ); + ofstream outfile_b(str); + + // fill hashtable + + INDEX_3_HASHTABLE face2volelement(ne); + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + INDEX_3 i3; + int k, l; + for (j = 1; j <= 4; j++) // loop over faces of tet + { + l = 0; + for (k = 1; k <= 4; k++) + if (k != j) + { + l++; + i3.I(l) = el.PNum(k); + } + i3.Sort(); + face2volelement.Set (i3, i); + } + } + +// outfile.precision(6); +// outfile.setf (ios::fixed, ios::floatfield); +// outfile.setf (ios::showpoint); + + outfile_h << np << " " << ne << " " << nse << "\n"; + outfile_h << "2" << "\n"; + outfile_h << "303 " << nse << "\n"; + outfile_h << "504 " << ne << "\n"; + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + + outfile_n << i << " -1 "; + outfile_n << p.X() << " "; + outfile_n << p.Y() << " "; + outfile_n << p.Z() << "\n"; + } + + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (inverttets) el.Invert(); + sprintf( str, "5%02d", (int)el.GetNP() ); + outfile_e << i << " " << el.GetIndex() << " " << str << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile_e << " "; + outfile_e << el.PNum(j); + } + outfile_e << "\n"; + } + + for (i = 1; i <= nse; i++) + { + Element2d el = mesh.SurfaceElement(i); + if (invertsurf) el.Invert(); + sprintf( str, "3%02d", (int)el.GetNP() ); + { + INDEX_3 i3; + for (j = 1; j <= 3; j++) i3.I(j) = el.PNum(j); + i3.Sort(); + + int elind = face2volelement.Get(i3); + outfile_b << i << " " << mesh.GetFaceDescriptor(el.GetIndex()).BCProperty() << + " " << elind << " 0 " << str << " "; + } + for (j = 1; j <= el.GetNP(); j++) + { + outfile_b << " "; + outfile_b << el.PNum(j); + } + outfile_b << "\n"; + } +} + +} diff --git a/libsrc/interface/writefeap.cpp b/libsrc/interface/writefeap.cpp new file mode 100644 index 00000000..85681aa0 --- /dev/null +++ b/libsrc/interface/writefeap.cpp @@ -0,0 +1,220 @@ +// +// Write FEAP file +// FEAP by Bob Taylor, Berkely +// +// contact Peter Wriggers or Albrecht Rieger, Hannover +// rieger@ibnm.uni-hannover.de +// + +#include + +#include +#include +#include +#include + +namespace netgen +{ + +#include "writeuser.hpp" + + +void WriteFEAPFormat (const Mesh & mesh, + const string & filename) + +{ + // Feap format by A. Rieger + // rieger@ibnm.uni-hannover.de + + int inverttets = mparam.inverttets; + //int invertsurf = mparam.inverttrigs; + + int i, j; + + double scale = 1; // globflags.GetNumFlag ("scale", 1); + + ofstream outfile(filename.c_str()); + + outfile << "feap" << "\n"; + outfile << mesh.GetNP(); + outfile << ","; + outfile << mesh.GetNE(); + outfile << ","; + outfile << "1,3,3,4" << "\n" << "\n"; + outfile << "!numnp,numel,nummat,ndm,ndf,nen"; + outfile << "\n"; + + outfile << "\n" << "\n"; + outfile << "!node,, X Y Z" << "\n"; + outfile << "COOR" << "\n"; + outfile.precision(4); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + for (i = 1; i <= mesh.GetNP(); i++) + { + outfile.width(5); + outfile << i; + outfile << ",,"; + outfile.width(10); + outfile << mesh.Point(i)(0)/scale << " "; + outfile.width(10); + outfile << mesh.Point(i)(1)/scale << " "; + outfile.width(10); + outfile << mesh.Point(i)(2)/scale << "\n"; + } + + outfile << "\n" << "\n"; + outfile << "!elm,,mat, n1 n2 n3 n4" << "\n"; + outfile << "ELEM" << "\n"; + + for (i = 1; i <= mesh.GetNE(); i++) + { + Element el = mesh.VolumeElement(i); + if (inverttets) + el.Invert(); + + + outfile.width(5); + outfile << i; + outfile << ",,"; + outfile << el.GetIndex(); + outfile << ","; + + + for (j = 1; j <= el.NP(); j++) + { + outfile.width(8); + outfile << el.PNum(j); + } + outfile << "\n"; + } + + outfile << "\n" << "\n"; + + + /* + + //outfile << "SLOA" << "\n"; + //outfile << "2,3,3" << "\n"; + //outfile << GetNSE() << "\n"; + outfile << "selm" << "\n" << GetNSE() << "\n"; + for (i = 1; i <= GetNSE(); i++) + { + if (SurfaceElement(i).GetIndex()) + { + outfile.width(8); + outfile << facedecoding.Get(SurfaceElement(i).GetIndex ()).surfnr; + //outfile.width(8); + //outfile << facedecoding.Get(SurfaceElement(i).GetIndex ()).domin; + //outfile.width(8); + //outfile << facedecoding.Get(SurfaceElement(i).GetIndex ()).domout; + } + else + outfile << " 0 0 0"; + + + Element2d sel = SurfaceElement(i); + if (invertsurf) + sel.Invert(); + //outfile.width(8); + //outfile << sel.GetNP(); + //if (facedecoding.Get(SurfaceElement(i).GetIndex ()).surfnr == 4) + //{ + for (j = 1; j <= sel.GetNP(); j++) + { + outfile.width(8); + outfile << sel.PNum(j); + } + //outfile.width(8); + //outfile << "0.0"; + //outfile.width(8); + //outfile << "0.0"; + //outfile.width(8); + //outfile << "1.0" << "\n"; + //} + outfile << "\n"; + //outfile << endl; + } + */ + + + + // BEGIN CONTACT OUTPUT + /* + int masterindex, slaveindex; + cout << "Master Surface index = "; + cin >> masterindex; + cout << "Slave Surface index = "; + cin >> slaveindex; + + + // CONTACT SURFACE 1 + outfile << "\n"; + outfile << "\n"; + outfile << "surface,1" << "\n";; + outfile.width(6); + outfile << "tria" << "\n";; + outfile.width(13); + outfile << "facet" << "\n";; + zz = 0; + for (i = 1; i <= mesh.GetNSE(); i++) + { + Element2d sel = mesh.SurfaceElement(i); + if (invertsurf) + sel.Invert(); + if (mesh.GetFaceDescriptor(sel.GetIndex ()).BCProperty() == masterindex) + { + zz++; + outfile.width(14); + outfile << zz; + outfile << ",,"; + for (j = 1; j <= sel.GetNP(); j++) + { + outfile << sel.PNum(j); + outfile << ","; + } + outfile << "\n"; + } + } + + + // CONTACT SURFACE 2 + outfile << "\n"; + outfile << "\n"; + outfile << "surface,2" << "\n";; + outfile.width(6); + outfile << "tria" << "\n";; + outfile.width(13); + outfile << "facet" << "\n";; + zz = 0; + for (i = 1; i <= mesh.GetNSE(); i++) + { + + Element2d sel = mesh.SurfaceElement(i); + if (invertsurf) + sel.Invert(); + if (mesh.GetFaceDescriptor(sel.GetIndex ()).BCProperty() == slaveindex) + { + zz++; + outfile.width(14); + outfile << zz; + outfile << ",,"; + for (j = 1; j <= sel.GetNP(); j++) + { + outfile << sel.PNum(j); + outfile << ","; + } + outfile << "\n"; + } + } + + outfile << "\n"; + outfile << "\n"; + */ + + // END CONTACT OUTPUT + + cout << "done" << endl; +} +} diff --git a/libsrc/interface/writefluent.cpp b/libsrc/interface/writefluent.cpp new file mode 100644 index 00000000..c5dac392 --- /dev/null +++ b/libsrc/interface/writefluent.cpp @@ -0,0 +1,193 @@ +// +// Write Fluent file +// Johannes Gerstmayr, University Linz +// + +#include + +#include +#include +#include +#include + +namespace netgen +{ + +#include "writeuser.hpp" + + + +void WriteFluentFormat (const Mesh & mesh, + const string & filename) + +{ + cout << "start writing fluent export" << endl; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int i, j; + + ofstream outfile (filename.c_str()); + char str[100]; + + outfile.precision(6); + //outfile.setf (ios::fixed, ios::floatfield); + //outfile.setf (ios::showpoint); + + outfile << "(0 \"Exported file from NETGEN \")" << endl; + outfile << "(0 \"Dimension:\")" << endl; + outfile << "(2 3)" << endl << endl; + + outfile << "(0 \"Nodes:\")" << endl; + + //number of nodes: + sprintf(str,"(10 (0 1 %x 1))",np); //hexadecimal!!! + outfile << str << endl; + + //nodes of zone 1: + sprintf(str,"(10 (7 1 %x 1)(",np); //hexadecimal!!! + outfile << str << endl; + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + + //outfile.width(10); + outfile << p.X() << " "; + outfile << p.Y() << " "; + outfile << p.Z() << "\n"; + } + outfile << "))" << endl << endl; + + //write faces with elements + + outfile << "(0 \"Faces:\")" << endl; + + Element2d face, face2; + int i2, j2; + Array surfaceelp; + Array surfaceeli; + Array locels; + + //no cells=no tets + //no faces=2*tets + + int noverbface = 2*ne-nse/2; + + sprintf(str,"(13 (0 1 %x 0))",(noverbface+nse)); //hexadecimal!!! + outfile << str << endl; + + sprintf(str,"(13 (4 1 %x 2 3)(",noverbface); //hexadecimal!!! + outfile << str << endl; + + const_cast (mesh).BuildElementSearchTree(); + + for (i = 1; i <= ne; i++) + { + if (ne > 2000) + { + if (i%2000 == 0) + { + cout << (double)i/(double)ne*100. << "%" << endl; + } + } + + Element el = mesh.VolumeElement(i); + //if (inverttets) + // el.Invert(); + + //outfile << el.GetIndex() << " "; + if (el.GetNP() != 4) {cout << "only tet-meshes supported in write fluent!" << endl;} + + //faces: + + Box3d box; + el.GetBox(mesh.Points(), box); + box.IncreaseRel(1e-6); + + mesh.GetIntersectingVolEls(box.PMin(),box.PMax(),locels); + int nel = locels.Size(); + int locind; + + //cout << "nel=" << nel << endl; + + for (j = 1; j <= el.GetNFaces(); j++) + { + el.GetFace(j, face); + face.Invert(); + int eli2 = 0; + int stopsig = 0; + + for (i2 = 1; i2 <= nel; i2++) + { + locind = locels.Get(i2); + //cout << " locind=" << locind << endl; + + Element el2 = mesh.VolumeElement(locind); + //if (inverttets) + // el2.Invert(); + + for (j2 = 1; j2 <= el2.GetNFaces(); j2++) + { + el2.GetFace(j2, face2); + + if (face2.HasFace(face)) {eli2 = locind; stopsig = 1; break;} + } + if (stopsig) break; + } + + if (eli2==i) cout << "error in WRITE_FLUENT!!!" << endl; + + if (eli2 > i) //dont write faces two times! + { + //i: left cell, eli: right cell + outfile << hex << face.PNum(2) << " " + << hex << face.PNum(1) << " " + << hex << face.PNum(3) << " " + << hex << i << " " + << hex << eli2 << "\n"; + } + if (eli2 == 0) + { + surfaceelp.Append(INDEX_3(face.PNum(2),face.PNum(1),face.PNum(3))); + surfaceeli.Append(i); + } + } + } + outfile << "))" << endl; + + sprintf(str,"(13 (2 %x %x 3 3)(",(noverbface+1),noverbface+nse); //hexadecimal!!! + outfile << str << endl; + + for (i = 1; i <= surfaceelp.Size(); i++) + { + outfile << hex << surfaceelp.Get(i).I1() << " " + << hex << surfaceelp.Get(i).I2() << " " + << hex << surfaceelp.Get(i).I3() << " " + << hex << surfaceeli.Get(i) << " " << 0 << "\n"; + } + + outfile << "))" << endl << endl; + + outfile << "(0 \"Cells:\")" << endl; + + sprintf(str,"(12 (0 1 %x 0))",ne); //hexadecimal!!! + outfile << str << endl; + + sprintf(str,"(12 (1 1 %x 1 2))",ne); //hexadecimal!!! + outfile << str << endl << endl; + + + + + outfile << "(0 \"Zones:\")\n" + << "(45 (1 fluid fluid)())\n" + // << "(45 (2 velocity-inlet velocity_inlet.1)())\n" + // << "(45 (3 pressure-outlet pressure_outlet.2)())\n" + << "(45 (2 wall wall)())\n" + << "(45 (4 interior default-interior)())\n" << endl; + + cout << "done" << endl; +} + +} diff --git a/libsrc/interface/writegmsh.cpp b/libsrc/interface/writegmsh.cpp new file mode 100644 index 00000000..93def677 --- /dev/null +++ b/libsrc/interface/writegmsh.cpp @@ -0,0 +1,200 @@ +/************************************* + * Write Gmsh file + * First issue the 04/26/2004 by Paul CARRICO (paul.carrico@free.fr) + * At the moment, the GMSH format is available for + * linear tetrahedron elements i.e. in 3D + * (based on Neutral Format) + * + * Second issue the 05/05/2004 by Paul CARRICO + * Thanks to Joachim Schoeberl for the correction of a minor bug + * the 2 initial Gmsh Format (i.e. volume format and surface format) are group together) + * in only one file + **************************************/ + +#include + +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + + + +/* + * GMSH mesh format + * points, elements, surface elements and physical entities + */ + +void WriteGmshFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + ofstream outfile (filename.c_str()); + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + int np = mesh.GetNP(); /// number of point + int ne = mesh.GetNE(); /// number of element + int nse = mesh.GetNSE(); /// number of surface element (BC) + int i, j, k, l; + + + /* + * 3D section : Linear volume elements (only tetrahedra) + */ + + if (ne > 0 && mesh.VolumeElement(1).GetNP() == 4) + { + cout << "Write GMSH Format \n"; + cout << "The GMSH format is available for linear tetrahedron elements only in 3D\n" << endl; + + int inverttets = mparam.inverttets; + int invertsurf = mparam.inverttrigs; + + + /// Write nodes + outfile << "$NOD\n"; + outfile << np << "\n"; + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + outfile << i << " "; /// node number + outfile << p.X() << " "; + outfile << p.Y() << " "; + outfile << p.Z() << "\n"; + } + outfile << "$ENDNOD\n"; + + /// write elements + outfile << "$ELM\n"; + outfile << ne + nse << "\n"; //// number of elements + number of surfaces BC + + for (i = 1; i <= nse; i++) + { + Element2d el = mesh.SurfaceElement(i); + if (invertsurf) el.Invert(); + outfile << i; + outfile << " "; + outfile << "2"; + outfile << " "; + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + /// that means that physical entity = elementary entity (arbitrary approach) + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + outfile << "3"; + outfile << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile << el.PNum(j); + } + outfile << "\n"; + } + + + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (inverttets) el.Invert(); + outfile << nse + i; /// element number + outfile << " "; + outfile << "4"; /// element type i.e. Tetraedron == 4 + outfile << " "; + outfile << 100000 + el.GetIndex(); + /// that means that physical entity = elementary entity (arbitrary approach) + outfile << " "; + outfile << 100000 + el.GetIndex(); /// volume number + outfile << " "; + outfile << "4"; /// number of nodes i.e. 4 for a tetrahedron + + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile << el.PNum(j); + } + outfile << "\n"; + } + + + outfile << "$ENDELM\n"; + } + + /* + * End of 3D section + */ + + + + + + /* + * 2D section : available for triangles and quadrangles + */ + else if (ne == 0) /// means that there's no 3D element + { + cout << "\n Write Gmsh Surface Mesh (triangle and/or quadrangles)" << endl; + + /// Write nodes + outfile << "$NOD\n"; + outfile << np << "\n"; + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + outfile << i << " "; /// node number + outfile << p.X() << " "; + outfile << p.Y() << " "; + outfile << p.Z() << "\n"; + } + outfile << "$ENDNOD\n"; + + + /// write triangles & quadrangles + outfile << "$ELM\n"; + outfile << nse << "\n"; + + for (k = 1; k <= nse; k++) + { + const Element2d & el = mesh.SurfaceElement(k); + + + outfile << k; + outfile << " "; + outfile << (el.GetNP()-1); // 2 for a triangle and 3 for a quadrangle + outfile << " "; + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + /// that means that physical entity = elementary entity (arbitrary approach) + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + outfile << (el.GetNP()); // number of node per surfacic element + outfile << " "; + + for (l = 1; l <= el.GetNP(); l++) + { + outfile << " "; + outfile << el.PNum(l); + } + outfile << "\n"; + + } + outfile << "$ENDELM$ \n"; + } + + /* + * End of 2D section + */ + + else + { + cout << " Invalide element type for Gmsh volume Format !\n"; + } + + +} +} + + diff --git a/libsrc/interface/writegmsh2.cpp b/libsrc/interface/writegmsh2.cpp new file mode 100644 index 00000000..5ec3dc8f --- /dev/null +++ b/libsrc/interface/writegmsh2.cpp @@ -0,0 +1,261 @@ +/*! \file writegmsh2.cpp +* \brief Export Netgen Mesh in the GMSH v2.xx File format +* \author Philippose Rajan +* \date 02 November 2008 +* +* This function extends the export capabilities of +* Netgen to include the GMSH v2.xx File Format. +* +* Current features of this function include: +* +* 1. Exports Triangles, Quadrangles and Tetrahedra \n +* 2. Supports upto second order elements of each type +* +*/ + + +#include + +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + + // Mapping of entities from Netgen definitions to GMSH definitions + enum GMSH_ELEMENTS {GMSH_TRIG = 2, GMSH_TRIG6 = 9, + GMSH_QUAD = 3, GMSH_QUAD8 = 16, + GMSH_TET = 4, GMSH_TET10 = 11}; + const int triGmsh[7] = {0,1,2,3,6,4,5}; + const int quadGmsh[9] = {0,1,2,3,4,5,8,6,7}; + const int tetGmsh[11] = {0,1,2,3,4,5,8,6,7,10,9}; + + + /*! GMSH v2.xx mesh format export function + * + * This function extends the export capabilities of + * Netgen to include the GMSH v2.xx File Format. + * + * Current features of this function include: + * + * 1. Exports Triangles, Quadrangles and Tetrahedra \n + * 2. Supports upto second order elements of each type + * + */ + void WriteGmsh2Format (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) + { + ofstream outfile (filename.c_str()); + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + int np = mesh.GetNP(); /// number of points in mesh + int ne = mesh.GetNE(); /// number of 3D elements in mesh + int nse = mesh.GetNSE(); /// number of surface elements (BC) + int i, j, k, l; + + + /* + * 3D section : Volume elements (currently only tetrahedra) + */ + + if ((ne > 0) + && (mesh.VolumeElement(1).GetNP() <= 10) + && (mesh.SurfaceElement(1).GetNP() <= 6)) + { + cout << "Write GMSH v2.xx Format \n"; + cout << "The GMSH v2.xx export is currently available for elements upto 2nd Order\n" << endl; + + int inverttets = mparam.inverttets; + int invertsurf = mparam.inverttrigs; + + /// Prepare GMSH 2.0 file (See GMSH 2.0 Documentation) + outfile << "$MeshFormat\n"; + outfile << (float)2.0 << " " + << (int)0 << " " + << (int)sizeof(double) << "\n"; + outfile << "$EndMeshFormat\n"; + + /// Write nodes + outfile << "$Nodes\n"; + outfile << np << "\n"; + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + outfile << i << " "; /// node number + outfile << p.X() << " "; + outfile << p.Y() << " "; + outfile << p.Z() << "\n"; + } + + outfile << "$EndNodes\n"; + + /// write elements (both, surface elements and volume elements) + outfile << "$Elements\n"; + outfile << ne + nse << "\n"; //// number of elements + number of surfaces BC + + for (i = 1; i <= nse; i++) + { + int elType = 0; + + Element2d el = mesh.SurfaceElement(i); + if(invertsurf) el.Invert(); + + if(el.GetNP() == 3) elType = GMSH_TRIG; //// GMSH Type for a 3 node triangle + if(el.GetNP() == 6) elType = GMSH_TRIG6; //// GMSH Type for a 6 node triangle + if(elType == 0) + { + cout << " Invalid surface element type for Gmsh 2.0 3D-Mesh Export Format !\n"; + return; + } + + outfile << i; + outfile << " "; + outfile << elType; + outfile << " "; + outfile << "2"; //// Number of tags (2 => Physical and elementary entities) + outfile << " "; + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + /// that means that physical entity = elementary entity (arbitrary approach) + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile << el.PNum(triGmsh[j]); + } + outfile << "\n"; + } + + + for (i = 1; i <= ne; i++) + { + int elType = 0; + + Element el = mesh.VolumeElement(i); + if (inverttets) el.Invert(); + + if(el.GetNP() == 4) elType = GMSH_TET; //// GMSH Element type for 4 node tetrahedron + if(el.GetNP() == 10) elType = GMSH_TET10; //// GMSH Element type for 10 node tetrahedron + if(elType == 0) + { + cout << " Invalid volume element type for Gmsh 2.0 3D-Mesh Export Format !\n"; + return; + } + + outfile << nse + i; //// element number (Remember to add on surface elements) + outfile << " "; + outfile << elType; + outfile << " "; + outfile << "2"; //// Number of tags (2 => Physical and elementary entities) + outfile << " "; + outfile << 100000 + el.GetIndex(); + /// that means that physical entity = elementary entity (arbitrary approach) + outfile << " "; + outfile << 100000 + el.GetIndex(); /// volume number + outfile << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile << el.PNum(tetGmsh[j]); + } + outfile << "\n"; + } + outfile << "$EndElements\n"; + } + /* + * End of 3D section + */ + + + /* + * 2D section : available for triangles and quadrangles + * upto 2nd Order + */ + else if(ne == 0) /// means that there's no 3D element + { + cout << "\n Write Gmsh v2.xx Surface Mesh (triangle and/or quadrangles upto 2nd Order)" << endl; + + /// Prepare GMSH 2.0 file (See GMSH 2.0 Documentation) + outfile << "$MeshFormat\n"; + outfile << (float)2.0 << " " + << (int)0 << " " + << (int)sizeof(double) << "\n"; + outfile << "$EndMeshFormat\n"; + + /// Write nodes + outfile << "$Nodes\n"; + outfile << np << "\n"; + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + outfile << i << " "; /// node number + outfile << p.X() << " "; + outfile << p.Y() << " "; + outfile << p.Z() << "\n"; + } + outfile << "$EndNodes\n"; + + /// write triangles & quadrangles + outfile << "$Elements\n"; + outfile << nse << "\n"; + + for (k = 1; k <= nse; k++) + { + int elType = 0; + + const Element2d & el = mesh.SurfaceElement(k); + + if(el.GetNP() == 3) elType = GMSH_TRIG; //// GMSH Type for a 3 node triangle + if(el.GetNP() == 6) elType = GMSH_TRIG6; //// GMSH Type for a 6 node triangle + if(el.GetNP() == 4) elType = GMSH_QUAD; //// GMSH Type for a 4 node quadrangle + if(el.GetNP() == 8) elType = GMSH_QUAD8; //// GMSH Type for an 8 node quadrangle + if(elType == 0) + { + cout << " Invalid surface element type for Gmsh 2.0 2D-Mesh Export Format !\n"; + return; + } + + outfile << k; + outfile << " "; + outfile << elType; + outfile << " "; + outfile << "2"; + outfile << " "; + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + /// that means that physical entity = elementary entity (arbitrary approach) + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + for (l = 1; l <= el.GetNP(); l++) + { + outfile << " "; + if((elType == GMSH_TRIG) || (elType == GMSH_TRIG6)) + { + outfile << el.PNum(triGmsh[l]); + } + else if((elType == GMSH_QUAD) || (elType == GMSH_QUAD8)) + { + outfile << el.PNum(quadGmsh[l]); + } + } + outfile << "\n"; + } + outfile << "$EndElements\n"; + } + /* + * End of 2D section + */ + + else + { + cout << " Invalid element type for Gmsh v2.xx Export Format !\n"; + } + } // End: WriteGmsh2Format +} // End: namespace netgen + + diff --git a/libsrc/interface/writejcm.cpp b/libsrc/interface/writejcm.cpp new file mode 100644 index 00000000..7517b179 --- /dev/null +++ b/libsrc/interface/writejcm.cpp @@ -0,0 +1,430 @@ +// +// Write JCMwave file +// 07.07.2005, Sven Burger, ZIB Berlin +// + + +#include +#include +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + +void WriteJCMFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + if (mesh.GetDimension() != 3) + { + cout <<"\n Error: Dimension 3 only supported by this output format!"< identmap1, identmap2, identmap3; + mesh.GetIdentifications().GetMap(1, identmap1); + mesh.GetIdentifications().GetMap(2, identmap2); + mesh.GetIdentifications().GetMap(3, identmap3); + + // number of volume elements + int ne = mesh.GetNE(); + int ntets = 0; + int nprisms = 0; + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (el.GetNP() == 4) + { + ntets++; + // Check that no two points on a tetrahedron are identified with each other + for (j = 1; j <= 4; j++) + for (jj = 1; jj <=4; jj++) + { + if (identmap1.Elem(el.PNum(j)) == el.PNum(jj)) + { + cout << "\n Error: two points on a tetrahedron identified (1) with each other" + << "\n REFINE MESH !" << endl; + return; + } + if (identmap2.Elem(el.PNum(j)) == el.PNum(jj)) + { + cout << "\n Error: two points on a tetrahedron identified (2) with each other" + << "\n REFINE MESH !" << endl; + return; + } + if (identmap3.Elem(el.PNum(j)) == el.PNum(jj)) + { + cout << "\n Error: two points on a tetrahedron identified (3) with each other" + << "\n REFINE MESH !" << endl; + return; + } + } + + } + else if (el.GetNP() == 6) + nprisms++; + } + if ( ne != (ntets+nprisms)) + { + cout<< "\n Error in determining number of volume elements!\n" + << "\n Prisms and tetrahedra only implemented in the JCMwave format!\n"< 0) + cout << " Please note: Boundaries at infinity have to carry the bc-attribute '-bc=" + << bc_at_infinity <<"'."< pointsOnTetras; + pointsOnTetras.SetSize (mesh.GetNP()); + pointsOnTetras = 0; + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (el.GetNP() == 4) + { + for (j = 1; j <= 4; j++) + pointsOnTetras.Set(int (el.PNum(j)),1); + } + } + + // number of boundary triangles and boundary quadrilaterals + for (i = 1; i <= nse; i++) + { + Element2d el = mesh.SurfaceElement(i); + if (el.GetNP() == 3 && + ( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 || + mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) ) + nbtri++; + else if (el.GetNP() == 4 && + ( mesh.GetFaceDescriptor (el.GetIndex()).DomainIn()==0 || + mesh.GetFaceDescriptor (el.GetIndex()).DomainOut()==0 ) ) + nbquad++; + } + + ofstream outfile (filename.c_str()); + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + outfile << "/* \n"; + outfile << "__BLOBTYPE__=Grid\n"; + outfile << "__OWNER__=JCMwave\n"; + outfile << "SpaceDim=3\n"; + outfile << "ManifoldDim=3\n"; + outfile << "NRefinementSteps=0\n"; + outfile << "NPoints="<NTetrahedra="<NPrisms="<NBoundaryTriangles="<NBoundaryQuadrilaterals="< & p = mesh.Point(i); + outfile << i << "\n"; + outfile << p(0) << "e-6\n"; + outfile << p(1) << "e-6\n"; + outfile << p(2) << "e-6\n\n"; + } + + outfile << "\n"; + outfile << "# Tetrahedra\n"; + counter = 0; + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (el.GetNP() == 4) + { + counter++; + dx1 = mesh.Point(el.PNum(2))(0) - mesh.Point(el.PNum(1))(0); + dx2 = mesh.Point(el.PNum(3))(0) - mesh.Point(el.PNum(1))(0); + dx3 = mesh.Point(el.PNum(4))(0) - mesh.Point(el.PNum(1))(0); + dy1 = mesh.Point(el.PNum(2))(1) - mesh.Point(el.PNum(1))(1); + dy2 = mesh.Point(el.PNum(3))(1) - mesh.Point(el.PNum(1))(1); + dy3 = mesh.Point(el.PNum(4))(1) - mesh.Point(el.PNum(1))(1); + dz1 = mesh.Point(el.PNum(2))(2) - mesh.Point(el.PNum(1))(2); + dz2 = mesh.Point(el.PNum(3))(2) - mesh.Point(el.PNum(1))(2); + dz3 = mesh.Point(el.PNum(4))(2) - mesh.Point(el.PNum(1))(2); + vol = (dy1*dz2-dz1*dy2)*dx3 + (dz1*dx2-dx1*dz2)*dy3 + (dx1*dy2-dy1*dx2)*dz3; + + if ( vol > 0 ) + for (j = 1; j <= 4; j++) + outfile << el.PNum(j)<<"\n"; + else + { + for (j = 2; j >= 1; j--) + outfile << el.PNum(j)<<"\n"; + for (j = 3; j <= 4; j++) + outfile << el.PNum(j)<<"\n"; + } + outfile << el.GetIndex() << "\n\n"; + } + } + if ( counter != ntets) + { + cout<< "\n Error in determining number of tetras!\n"< 0) + for (j = 1; j <= 6; j++) + outfile << el.PNum(j)<<"\n"; + else + { + for (j = 3; j >= 1; j--) + outfile << el.PNum(j)<<"\n"; + for (j = 6; j >= 4; j--) + outfile << el.PNum(j)<<"\n"; + } + } + else if ( pointsOnTetras.Get(el.PNum(4)) && + pointsOnTetras.Get(el.PNum(5)) && + pointsOnTetras.Get(el.PNum(6)) ) + { + if ( vol < 0 ) + { + for (j = 4; j <= 6; j++) + outfile << el.PNum(j)<<"\n"; + for (j = 1; j <= 3; j++) + outfile << el.PNum(j)<<"\n"; + } + else + { + for (j = 6; j >= 4; j--) + outfile << el.PNum(j)<<"\n"; + for (j = 3; j >= 1; j--) + outfile << el.PNum(j)<<"\n"; + } + } + else + { + cout << "\n Error in determining prism point numbering!\n"<= 5 ) + jj = jj - 4; + outfile << el.PNum(jj)<<"\n"; + } + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << "\n"; + if (mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() == bc_at_infinity) + { + outfile << "-2\n\n"; + cout << "\nWarning: Quadrilateral at infinity found (this should not occur)!"<= 5 ) + jj = jj - 4; + outfile << identmap1.Elem(el.PNum(jj))<<"\n"; + } + outfile << "\n"; + } + else if ( identmap2.Elem(el.PNum(1)) && + identmap2.Elem(el.PNum(2)) && + identmap2.Elem(el.PNum(3)) && + identmap2.Elem(el.PNum(4)) ) + { + outfile << "-1\n"; + for (j = 1; j <= 4; j++) + { + jj = j + ct; + if ( jj >= 5 ) + jj = jj - 4; + outfile << identmap2.Elem(el.PNum(jj))<<"\n"; + } + outfile << "\n"; + } + else if ( identmap3.Elem(el.PNum(1)) && + identmap3.Elem(el.PNum(2)) && + identmap3.Elem(el.PNum(3)) && + identmap3.Elem(el.PNum(4)) ) + { + outfile << "-1\n"; + for (j = 1; j <= 4; j++) + { + jj = j + ct; + if ( jj >= 5 ) + jj = jj - 4; + outfile << identmap3.Elem(el.PNum(jj))<<"\n"; + } + outfile << "\n"; + } + else + outfile << "1\n\n"; + } + } + + cout << " JCMwave grid file written." << endl; +} + +} + diff --git a/libsrc/interface/writepermas.cpp b/libsrc/interface/writepermas.cpp new file mode 100644 index 00000000..fc46e87c --- /dev/null +++ b/libsrc/interface/writepermas.cpp @@ -0,0 +1,208 @@ +// +// Write Permas file +// for Intes GmbH, Stuttgart +// + +#include + +#include +#include +#include +#include + +#include + +using namespace std; + +namespace netgen +{ +#include "writeuser.hpp" + // Forward declarations (don't know, where to define them, sorry) + int addComponent(string &strComp, string &strSitu, ofstream &out); + + + // This should be the new function to export a PERMAS file + void WritePermasFormat (const Mesh &mesh, const string &filename, + string &strComp, string &strSitu) + { + ofstream outfile (filename.c_str()); + addComponent(strComp, strSitu, outfile); + WritePermasFormat ( mesh, filename); + } + + void WritePermasFormat (const Mesh &mesh, const string &filename) + { + string strComp, strSitu; + ofstream outfile (filename.c_str()); + + outfile.precision(8); + + strSitu = strComp = ""; + if (addComponent(strComp, strSitu, outfile) == 1) { + printf("Error while exporting PERMAS dat!\n"); + return; + } + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int i, j, k; + + if (ne == 0) + { + // pure surface mesh + cout << "\nWrite Permas Surface Mesh" << endl; + + int elnr = 0; + for (j = 1; j <= 2; j++) + { + int nelp(0); + switch (j) + { + case 1: + nelp = 3; + outfile << "$ELEMENT TYPE = TRIA3 ESET = ALLQUAD" << endl; + break; + case 2: + nelp = 4; + outfile << "$ELEMENT TYPE = QUAD4 ESET = ALLQUAD" << endl; + break; + } + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (el.GetNP() != nelp) + continue; + + elnr++; + outfile << elnr << " "; + for (k = 1; k <= nelp; k++) + outfile << " " << el.PNum(k); + outfile << endl; + + } + } + } + else + { + cout << "\nWrite Permas Volume Mesh" << endl; + + int secondorder = (mesh.VolumeElement(1).GetNP() == 10); + + if (!secondorder) + { + outfile << "$ELEMENT TYPE = TET4 ESET = ALLTET" << endl; + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + outfile << i + << " " << el.PNum(1) + << " " << el.PNum(2) + << " " << el.PNum(3) + << " " << el.PNum(4) << endl; + } + } + else + { + outfile << "$ELEMENT TYPE = TET10 ESET = ALLTET" << endl; + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + outfile << i + << " " << el.PNum(1) + << " " << el.PNum(5) + << " " << el.PNum(2) + << " " << el.PNum(8) + << " " << el.PNum(3) + << " " << el.PNum(6) << endl << "& " + << " " << el.PNum(7) + << " " << el.PNum(9) + << " " << el.PNum(10) + << " " << el.PNum(4) << endl; + } + } + + outfile << endl << endl; + + + outfile << "$SURFACE GEO SURFID = 1 SFSET = ALLSUR" << endl; + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (el.GetNP() == 3) + outfile << "STRIA3" + << " " << el.PNum(1) + << " " << el.PNum(2) + << " " << el.PNum(3) << endl; + } + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (el.GetNP() == 4) + outfile << "SQUAD4" + << " " << el.PNum(1) + << " " << el.PNum(2) + << " " << el.PNum(3) + << " " << el.PNum(4) << endl; + } + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (el.GetNP() == 6) + outfile << "STRIA6" + << " " << el.PNum(1) + << " " << el.PNum(4) + << " " << el.PNum(2) + << " " << el.PNum(5) + << " " << el.PNum(3) + << " " << el.PNum(6) << endl; + } + } + + + outfile << endl << endl; + + outfile << "$COOR NSET = ALLNODES" << endl; + + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + for (i = 1; i <= np; i++) + { + outfile << i << " "; + outfile << mesh.Point(i)(0) << " "; + outfile << mesh.Point(i)(1) << " "; + outfile << mesh.Point(i)(2) << "\n"; + } + } + ////////////////////////////////////////////////////////////////////////////////// + // \brief Writes PERMAS configuration header into export file + // Returns >0 in case of errors + // \par string &strComp : Reference to component description + // \par string &strComp : Reference to situation description + ////////////////////////////////////////////////////////////////////////////////// + int addComponent(string &strComp, string &strSitu, ofstream &out) + { + if (strComp.size() > 12 || strSitu > 12) + return 1; + + if (0 == strComp.size()) + strComp = "KOMPO1"; + + if (0 == strSitu.size()) + strSitu = "SIT1"; + + // Writing description header of configuration + out << "$ENTER COMPONENT NAME = " << strComp << " DOFTYPE = DISP MATH" << endl << endl; + out << " $SITUATION NAME = " << strSitu << endl; + out << " $END SITUATION" << endl << endl; + out << " $STRUCTURE" << endl; + + return 0; + } + +} diff --git a/libsrc/interface/writetecplot.cpp b/libsrc/interface/writetecplot.cpp new file mode 100644 index 00000000..4730b983 --- /dev/null +++ b/libsrc/interface/writetecplot.cpp @@ -0,0 +1,127 @@ +// +// +// TECPLOT file by Jawor Georgiew +// +#include + +#include +#include +#include +#include + + + +namespace netgen +{ +#include "writeuser.hpp" + +void WriteTecPlotFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + INDEX i; + int j, k, e, z; + Vec<3> n; + + INDEX np = mesh.GetNP(); + INDEX ne = mesh.GetNE(); + INDEX nse = mesh.GetNSE(); + + Array sn(np); + ofstream outfile(filename.c_str()); + + outfile << "TITLE=\" " << filename << "\"" << endl; + + // fill hashtable + + INDEX_3_HASHTABLE face2volelement(ne); + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + INDEX_3 i3; + int l; + for (j = 1; j <= 4; j++) // loop over faces of tet + { + l = 0; + for (k = 1; k <= 4; k++) + if (k != j) + { + l++; + i3.I(l) = el.PNum(k); + } + i3.Sort(); + face2volelement.Set (i3, i); + } + } + + + for (j = 1; j <= geom.GetNSurf(); j++) /* Flaeche Nummer j */ + { + for (i = 1; i <= np; i++) + sn.Elem(i) = 0; + + e = 0; + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (j == mesh.GetFaceDescriptor (el.GetIndex ()).SurfNr()) + { + for (k = 1; k <= 3; k++) + sn.Elem(el.PNum(k)) = 1; + e++; /* e= Anzahl der neuen Elemente */ + } + } + + z = 0; + for (i = 1; i <= np; i++) + if (sn.Elem(i) == 1) + sn.Elem(i) = ++z; + + outfile << "ZONE T=\" Surface " << j << " \", N=" << z + << ", E=" << e << ", ET=TRIANGLE, F=FEPOINT" << endl; + + for (i = 1; i <= np; i++) + if (sn.Elem(i) != 0) + { + n = geom.GetSurface(j) -> GetNormalVector ( mesh.Point(i) ); + + outfile << mesh.Point(i)(0) << " " /* Knoten Koordinaten */ + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << " " + << n(0) << " " + << n(1) << " " + << n(2) << " " + << i << endl; + } + + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (j == mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr()) + /* FlaechenKnoten (3) */ + outfile << sn.Get(el.PNum(1)) << " " + << sn.Get(el.PNum(2)) << " " + << sn.Get(el.PNum(3)) << endl; + + /// Hier soll noch die Ausgabe der Nummer des angrenzenden + /// Vol.elements erfolgen ! + + for (k = 1; k <= nse; k++) + { + const Element2d & sel = mesh.SurfaceElement(k); + INDEX_3 i3; + for (j = 1; j <= 3; j++) + i3.I(j) = sel.PNum(j); + i3.Sort(); + + //int elind = face2volelement.Get(i3); + } + } + } +} + + +} diff --git a/libsrc/interface/writetet.cpp b/libsrc/interface/writetet.cpp new file mode 100644 index 00000000..bcab41c2 --- /dev/null +++ b/libsrc/interface/writetet.cpp @@ -0,0 +1,1096 @@ + +#include + +#include +#include +#include +#include +#include + +namespace netgen +{ + +#include "writeuser.hpp" + + + void WriteTETFormat (const Mesh & mesh, + const string & filename)//, const string& problemType ) + { + string problemType = ""; + if(!mesh.PureTetMesh()) + throw NgException("Can only export pure tet mesh in this format"); + + cout << "starting .tet export to file " << filename << endl; + + + Array point_ids,edge_ids,face_ids; + Array elnum(mesh.GetNE()); + elnum = -1; + + + Array userdata_int; + Array userdata_double; + Array ports; + + Array uid_to_group_3D, uid_to_group_2D, uid_to_group_1D, uid_to_group_0D; + + int pos_int = 0; + int pos_double = 0; + + bool haveuserdata = + (mesh.GetUserData("TETmesh:double",userdata_double) && + mesh.GetUserData("TETmesh:int",userdata_int) && + mesh.GetUserData("TETmesh:ports",ports) && + mesh.GetUserData("TETmesh:point_id",point_ids,PointIndex::BASE) && + mesh.GetUserData("TETmesh:uid_to_group_3D",uid_to_group_3D) && + mesh.GetUserData("TETmesh:uid_to_group_2D",uid_to_group_2D) && + mesh.GetUserData("TETmesh:uid_to_group_1D",uid_to_group_1D) && + mesh.GetUserData("TETmesh:uid_to_group_0D",uid_to_group_0D)); + + + int version,subversion; + + if(haveuserdata) + { + version = int(userdata_double[0]); + subversion = int(10*(userdata_double[0] - version)); + pos_double++; + } + else + { + version = 2; + subversion = 0; + } + + + if(version >= 2) + { + // test if ids are disjunct, if not version 2.0 not possible + int maxbc(-1),mindomain(-1); + + for(ElementIndex i=0; i maxbc) + maxbc = mesh.GetFaceDescriptor(i).BCProperty(); + + if(maxbc >= mindomain) + { + cout << "WARNING: writing version " << version << "." << subversion << " tetfile not possible, "; + version = 1; subversion = 1; + cout << "using version " << version << "." << subversion << endl; + } + } + + + + int startsize = point_ids.Size(); + point_ids.SetSize(mesh.GetNP()+1); + for(int i=startsize; i edgenumbers(6*mesh.GetNE()+3*mesh.GetNSE());; + INDEX_3_CLOSED_HASHTABLE facenumbers(4*mesh.GetNE()+mesh.GetNSE()); + + Array edge2node; + Array face2edge; + Array element2face; + + int numelems(0),numfaces(0),numedges(0),numnodes(0); + + for(SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + const Segment & seg = mesh[si]; + INDEX_2 i2(seg[0],seg[1]); + i2.Sort(); + if(edgenumbers.Used(i2)) + continue; + + numedges++; + edgenumbers.Set(i2,numedges); + edge2node.Append(i2); + + edge_ids.Append(seg.edgenr); + + if(point_ids[seg[0]] == -1) + point_ids[seg[0]] = (version >= 2) ? seg.edgenr : 0; + if(point_ids[seg[1]] == -1) + point_ids[seg[1]] = (version >= 2) ? seg.edgenr : 0; + } + + for(SurfaceElementIndex si = 0; si < mesh.GetNSE(); si++) + { + if(mesh[si].IsDeleted()) + continue; + + const Element2d & elem = mesh[si]; + + numfaces++; + INDEX_3 i3(elem[0], elem[1], elem[2]); + + int min = i3[0]; + int minpos = 0; + for(int j=1; j<3; j++) + if(i3[j] < min) + { + min = i3[j]; minpos = j; + } + if(minpos == 1) + { + int aux = i3[0]; i3[0] = i3[1]; i3[1] = i3[2]; i3[2] = aux; + } + else if(minpos == 2) + { + int aux = i3[0]; i3[0] = i3[2]; i3[2] = i3[1]; i3[1] = aux; + } + facenumbers.Set(i3,numfaces); + + int bc = mesh.GetFaceDescriptor(elem.GetIndex()).BCProperty(); + face_ids.Append(bc); + + for(int j=0; j<3; j++) + if(point_ids[elem[j]] == -1) + point_ids[elem[j]] = (version >= 2) ? bc : 0; + + INDEX_2 i2a,i2b; + INDEX_3 f_to_n; + for(int j=0; j<3; j++) + { + i2a = INDEX_2(i3[j],i3[(j+1)%3]); + i2b[0] = i2a[1]; i2b[1] = i2a[0]; + if(edgenumbers.Used(i2a)) + f_to_n[j] = edgenumbers.Get(i2a); + else if(edgenumbers.Used(i2b)) + f_to_n[j] = -edgenumbers.Get(i2b); + else + { + numedges++; + edgenumbers.Set(i2a,numedges); + edge2node.Append(i2a); + f_to_n[j] = numedges; + if(version >= 2) + edge_ids.Append(bc); + else + edge_ids.Append(0); + } + } + face2edge.Append(f_to_n); + } + + for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + if(el.IsDeleted()) + continue; + + numelems++; + elnum[ei] = numelems; + + static int tetfaces[4][3] = + { { 0, 2, 1 }, + { 0, 1, 3 }, + { 1, 2, 3 }, + { 2, 0, 3 } }; + + for(int j=0; j<4; j++) + if(point_ids[el[j]] == -1) + point_ids[el[j]] = (version >= 2) ? el.GetIndex() : 0; + + INDEX_4 e_to_f; + + for(int i = 0; i < 4; i++) + { + INDEX_3 i3a(el[tetfaces[i][0]],el[tetfaces[i][1]],el[tetfaces[i][2]]); + + int min = i3a[0]; + int minpos = 0; + for(int j=1; j<3; j++) + if(i3a[j] < min) + { + min = i3a[j]; minpos = j; + } + if(minpos == 1) + { + int aux = i3a[0]; i3a[0] = i3a[1]; i3a[1] = i3a[2]; i3a[2] = aux; + } + else if(minpos == 2) + { + int aux = i3a[0]; i3a[0] = i3a[2]; i3a[2] = i3a[1]; i3a[1] = aux; + } + INDEX_3 i3b(i3a[0],i3a[2],i3a[1]); + + + if(facenumbers.Used(i3a)) + e_to_f[i] = facenumbers.Get(i3a); + else if(facenumbers.Used(i3b)) + e_to_f[i] = -facenumbers.Get(i3b); + else + { + numfaces++; + facenumbers.Set(i3a,numfaces); + e_to_f[i] = numfaces; + if(version >= 2) + face_ids.Append(el.GetIndex()); + else + face_ids.Append(0); + + INDEX_2 i2a,i2b; + INDEX_3 f_to_n; + for(int j=0; j<3; j++) + { + i2a = INDEX_2(i3a[j],i3a[(j+1)%3]); + i2b[0] = i2a[1]; i2b[1] = i2a[0]; + if(edgenumbers.Used(i2a)) + f_to_n[j] = edgenumbers.Get(i2a); + else if(edgenumbers.Used(i2b)) + f_to_n[j] = -edgenumbers.Get(i2b); + else + { + numedges++; + edgenumbers.Set(i2a,numedges); + edge2node.Append(i2a); + f_to_n[j] = numedges; + if(version >= 2) + edge_ids.Append(el.GetIndex()); + else + edge_ids.Append(0); + } + } + face2edge.Append(f_to_n); + } + } + element2face.Append(e_to_f); + } + + + + + ofstream outfile(filename.c_str()); + + outfile.precision(16); + + int unitcode; + double tolerance; + double dS1,dS2, alphaDeg; + double x3D,y3D,z3D; + int modelverts(0), modeledges(0), modelfaces(0), modelcells(0); + + int numObj0D,numObj1D,numObj2D,numObj3D; + int numports = ports.Size(); + + Array nodenum(point_ids.Size()+1); + + nodenum = -1; + + + + numnodes = 0; + for(int i=0; i* > idmaps; + for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + idmaps.Append(new Array); + mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true); + } + } + + Array id_num,id_type; + Array< Array *> id_groups; + + + // sst 2008-03-12: Write problem class... + { + std::string block; + block = "// CST Tetrahedral "; + block += !problemType.empty() ? problemType : "High Frequency"; + block += " Mesh, Version no.:\n"; + + size_t size = block.size()-3; + block += "// "; + block.append( size, '^' ); + block += "\n"; + + outfile + << block + << version << "." << subversion << "\n\n"; + } + + outfile + << "// User Units Code (1=CM 2=MM 3=M 4=MIC 5=NM 6=FT 7=IN 8=MIL):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << unitcode << "\n\n" \ + << "// Geometric coord \"zero\" tolerance threshold:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << tolerance << "\n\n" \ + << "// Periodic UnitCell dS1 , dS2 , alphaDeg:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << dS1 << " " << dS2 << " " << alphaDeg <<"\n\n" \ + << "// Periodic UnitCell origin in global coords (x3D,y3D,z3D):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << x3D << " " << y3D << " " << z3D << "\n" << endl; + + if(version == 2) + { + outfile << "// Model entity count: Vertices, Edges, Faces, Cells:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << modelverts << " " << modeledges << " " << modelfaces << " " << modelcells << endl << endl; + } + + + outfile << "// Topological mesh-entity counts (#elements,#faces,#edges,#nodes):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + outfile << numelems << " " + << numfaces << " " + << numedges << " " + << numnodes << endl << endl; + + outfile << "// NodeID, X, Y, Z, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<< uidpid <<":\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + + + + id_num.SetSize(mesh.GetNP()+1); + id_type.SetSize(mesh.GetNP()+1); + id_num = 0; + id_type = 0; + + int n2,n4,n8; + n2 = n4 = n8 = 0; + + + for(int i=PointIndex::BASE; i group; + group.Append(i); + for(int j=0; j 1) + { + id_groups.Append(new Array(group)); + if(group.Size() == 2) + { + id_type[i] = 1; + id_type[group[1]] = 2; + n2++; + } + else if(group.Size() == 4) + { + id_type[i] = 3; + for(int j=1; jSize() != 2) + continue; + + for(int j=0; jSize(); j++) + outfile << nodenum[(*id_groups[i])[j]] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + outfile << "// Number of Corner Periodic Master Nodes:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << n4 << "\n" \ + << "\n" \ + << "// MasterNodeID, 3-SlaveNodeID's, 3-TranslCodes (1=dS1 2=dS2 3=dS1+dS2):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + + + for(int i=0; iSize() != 4) + continue; + + for(int j=0; jSize(); j++) + outfile << nodenum[(*id_groups[i])[j]] << " "; + for(int j=1; jSize(); j++) + { + outfile << id_num[(*id_groups[i])[j]] << " "; + } + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + outfile << "// Number of Cubic Periodic Master Nodes:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << n8 << "\n" \ + << "\n" \ + << "// MasterNodeID, 7-SlaveNodeID's, TranslCodes:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() != 8) + continue; + + for(int j=0; jSize(); j++) + outfile << nodenum[(*id_groups[i])[j]] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + + + outfile << "// EdgeID, NodeID0, NodeID1, Type (0=Reg 1=PMaster 2=PSlave 3=CPMaster 4=CPSlave), "<* > vertex_to_edge(mesh.GetNP()+1); + for(int i=0; i<=mesh.GetNP(); i++) + vertex_to_edge[i] = new Array; + + Array< Array* > idmaps_edge(idmaps.Size()); + for(int i=0; i(numedges); + (*idmaps_edge[i]) = 0; + } + + Array possible; + for(int i=0; i 0) + { + cerr << "ERROR: too many possible edge identifications" << endl; + (*testout) << "ERROR: too many possible edge identifications" << endl + << "*vertex_to_edge["<Append(i+1); + vertex_to_edge[v[1]]->Append(i+1); + } + + + for(int i=0; i group; + group.Append(i); + for(int j=0; j 1) + { + id_num[i] = 1; + id_groups.Append(new Array(group)); + if(group.Size() == 2) + { + id_type[i] = 1; + id_type[group[1]] = 2; + n2++; + } + else if(group.Size() == 4) + { + id_type[i] = 3; + for(int j=1; j group; + group.Append(i); + for(int j=0; j 1) + { + id_num[i] = 1; + id_groups.Append(new Array(group)); + if(group.Size() == 2) + { + id_type[i] = 1; + id_type[group[1]] = 2; + n2++; + } + else if(group.Size() == 4) + { + id_type[i] = 3; + for(int j=1; jSize() != 2) + continue; + + for(int j=0; jSize(); j++) + outfile << (*id_groups[i])[j] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + outfile << "// Number of Corner Periodic Master Edges:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"\ + << n4 << "\n" \ + << "\n"\ + << "// MasterEdgeID, 3 SlaveEdgeID's, 3 TranslCode (1=dS1 2=dS2 3=dS1+dS2):\n"\ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() != 4) + continue; + + for(int j=0; jSize(); j++) + outfile << (*id_groups[i])[j] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + id_groups[i] = NULL; + } + outfile << endl; + + + outfile << "// FaceID, EdgeID0, EdgeID1, EdgeID2, FaceType (0=Reg 1=PMaster 2=PSlave), "<* > edge_to_face(numedges+1); + for(int i=0; i; + + + for(int i=0; iSetSize(numfaces); + (*idmaps[i]) = 0; + } + + + for(int i=0; i 0) + cerr << "ERROR: too many possible face identifications" << endl; + } + } + + edge_to_face[abs(face2edge[i][0])]->Append(i+1); + edge_to_face[abs(face2edge[i][1])]->Append(i+1); + edge_to_face[abs(face2edge[i][2])]->Append(i+1); + } + + for(int i=0; i group; + group.Append(i); + for(int j=0; j 1) + { + id_num[i] = -1; + id_groups.Append(new Array(group)); + if(group.Size() == 2) + n2++; + else + cerr << "ERROR: face identification group size = " << group.Size() << endl; + } + + } + + + for(int i=0; iSize() != 2) + continue; + + for(int j=0; jSize(); j++) + outfile << (*id_groups[i])[j] << " "; + for(int j=1; jSize(); j++) + outfile << id_num[(*id_groups[i])[j]] << " "; + outfile << "\n"; + + delete id_groups[i]; + } + outfile << endl; + + + + + outfile << "// ElemID, FaceID0, FaceID1, FaceID2, FaceID3, "<= 0) + { + outfile << elnum[i] << " "; + for(int j=0; j<4; j++) + outfile << element2face[elnum[i]-1][j] << " "; + + outfile << mesh[i].GetIndex() << "\n"; + } + } + outfile << endl; + + outfile << "// ElemID, NodeID0, NodeID1, NodeID2, NodeID3:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + + + for(ElementIndex i=0; i= 0) + outfile << elnum[i] << " " + << nodenum[mesh[i][1]] << " " << nodenum[mesh[i][0]] << " " << nodenum[mesh[i][2]] << " " << nodenum[mesh[i][3]] << "\n"; + } + outfile << endl; + + + + + outfile << "// Physical Object counts (#Obj3D,#Obj2D,#Obj1D,#Obj0D):\n" + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + << " "<< numObj3D << " " << numObj2D << " " << numObj1D << " " << numObj0D << "\n" \ + << "\n" \ + << "// Number of Ports (Ports are a subset of Object2D list):\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" \ + << numports << "\n" \ + << endl; + + + Array< Array * > groups; + + int maxg = -1; + for(int i = 0; i maxg) + maxg = uid_to_group_3D[i]; + for(int i = 0; i maxg) + maxg = uid_to_group_2D[i]; + for(int i = 0; i maxg) + maxg = uid_to_group_1D[i]; + for(int i = 0; i maxg) + maxg = uid_to_group_0D[i]; + + groups.SetSize(maxg+1); + for(int i=0; i; + + for(ElementIndex i=0; i= 0) + groups[uid_to_group_3D[mesh[i].GetIndex()]]->Append(i+1); + + + + + outfile << "// Object3D GroupID, #Elems ElemID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + outfile << (*groups[i])[j] << "\n"; + } + + for(int i=0; iSetSize(0); + + for(int i=0; i= 0) + groups[uid_to_group_2D[face_ids[i]]]->Append(i+1); + + + outfile << "// Object2D GroupID, #Faces FaceID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + { + outfile << (*groups[i])[j]; + if(ports.Contains(face_ids[(*groups[i])[j]-1])) + outfile << " P"; + outfile << "\n"; + } + } + outfile << endl; + + + for(int i=0; iSetSize(0); + + for(int i=0; i= 0) + groups[uid_to_group_1D[edge_ids[i]]]->Append(i+1); + + + + outfile << "// Object1D GroupID, #Edges EdgeID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + outfile << (*groups[i])[j] << "\n"; + } + outfile << endl; + + + for(int i=0; iSetSize(0); + for(PointIndex i = mesh.Points().Begin(); i < mesh.Points().End(); i++) + { + if(i-PointIndex::BASE < point_ids.Size()) + { + if(uid_to_group_0D[point_ids[i]] >= 0) + groups[uid_to_group_0D[point_ids[i]]]->Append(i+1-PointIndex::BASE); + } + else + groups[uid_to_group_0D[0]]->Append(i+1-PointIndex::BASE); + } + + + outfile << "// Object0D GroupID, #Nodes NodeID List:\n" \ + << "// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; + for(int i=0; iSize() << "\n"; + for(int j=0; jSize(); j++) + outfile << (*groups[i])[j] << "\n"; + } + outfile << endl; + + for(int i=0; i + +#include +#include +#include +#include + + +namespace netgen +{ +#include "writeuser.hpp" + + +void WriteTochnogFormat (const Mesh & mesh, + const string & filename) +{ + cout << "\nWrite Tochnog Volume Mesh" << endl; + + ofstream outfile (filename.c_str()); + + outfile << "(Nodes and Elements generated with NETGEN" << endl; + outfile << " " << filename << ")" << endl; + + outfile.precision(8); + + outfile << "(Nodes)" << endl; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int i, j; + + for (i = 1; i <= np; i++) + { + outfile << "node " << " " << i << " "; + outfile << mesh.Point(i)(0) << " "; + outfile << mesh.Point(i)(1) << " "; + outfile << mesh.Point(i)(2) << "\n"; + } + + int elemcnt = 0; //element counter + int finished = 0; + int indcnt = 1; //index counter + + while (!finished) + { + int actcnt = 0; + const Element & el1 = mesh.VolumeElement(1); + int non = el1.GetNP(); + if (non == 4) + { + outfile << "(Elements, type=-tet4)" << endl; + } + else + { + cout << "unsupported Element type!!!" << endl; + } + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + + if (el.GetIndex() == indcnt) + { + actcnt++; + if (el.GetNP() != non) + { + cout << "different element-types in a subdomain are not possible!!!" << endl; + continue; + } + + elemcnt++; + outfile << "element " << elemcnt << " -tet4 "; + if (non == 4) + { + outfile << el.PNum(1) << " "; + outfile << el.PNum(2) << " "; + outfile << el.PNum(4) << " "; + outfile << el.PNum(3) << "\n"; + } + else + { + cout << "unsupported Element type!!!" << endl; + for (j = 1; j <= el.GetNP(); j++) + { + outfile << el.PNum(j); + if (j != el.GetNP()) outfile << ", "; + } + outfile << "\n"; + } + } + } + indcnt++; + if (elemcnt == ne) {finished = 1; cout << "all elements found by Index!" << endl;} + if (actcnt == 0) {finished = 1;} + } + + cout << "done" << endl; +} + +} diff --git a/libsrc/interface/writeuser.cpp b/libsrc/interface/writeuser.cpp new file mode 100644 index 00000000..92ee1bf8 --- /dev/null +++ b/libsrc/interface/writeuser.cpp @@ -0,0 +1,1040 @@ +// +// Write user dependent output file +// + +#include + +#include +#include +#include +#include +#include + +namespace netgen +{ +#include "writeuser.hpp" + + + void RegisterUserFormats (Array & names, + Array & extensions) + +{ + const char *types[] = + { + "Neutral Format", ".mesh", + "Surface Mesh Format", ".mesh" , + "DIFFPACK Format", ".mesh", + "TecPlot Format", ".mesh", + "Tochnog Format", ".mesh", + "Abaqus Format", ".mesh", + "Fluent Format", ".mesh", + "Permas Format", ".mesh", + "FEAP Format", ".mesh", + "Elmer Format", "*", + "STL Format", ".stl", + "STL Extended Format", ".stl", + "VRML Format", ".*", + "Gmsh Format", ".gmsh", + "Gmsh2 Format", ".gmsh2", + "OpenFOAM 1.5+ Format", "*", + "OpenFOAM 1.5+ Compressed", "*", + "JCMwave Format", ".jcm", + "TET Format", ".tet", + // { "Chemnitz Format" }, + 0 + }; + + for (int i = 0; types[2*i]; i++) + { + names.Append (types[2*i]); + extensions.Append (types[2*i+1]); + } +} + + + +bool WriteUserFormat (const string & format, + const Mesh & mesh, + const NetgenGeometry & hgeom, + const string & filename) +{ + const CSGeometry & geom = *dynamic_cast (&hgeom); + + PrintMessage (1, "Export mesh to file ", filename, + ", format is ", format); + + if (format == "Neutral Format") + WriteNeutralFormat (mesh, geom, filename); + + else if (format == "Surface Mesh Format") + WriteSurfaceFormat (mesh, filename); + + else if (format == "DIFFPACK Format") + WriteDiffPackFormat (mesh, geom, filename); + + else if (format == "Tochnog Format") + WriteTochnogFormat (mesh, filename); + + else if (format == "TecPlot Format") + cerr << "ERROR: TecPlot format currently out of order" << endl; + // WriteTecPlotFormat (mesh, geom, filename); + + else if (format == "Abaqus Format") + WriteAbaqusFormat (mesh, filename); + + else if (format == "Fluent Format") + WriteFluentFormat (mesh, filename); + + else if (format == "Permas Format") + WritePermasFormat (mesh, filename); + + else if (format == "FEAP Format") + WriteFEAPFormat (mesh, filename); + + else if (format == "Elmer Format") + WriteElmerFormat (mesh, filename); + + else if (format == "STL Format") + WriteSTLFormat (mesh, filename); + + // Philippose - 16 August 2010 + // Added additional STL Export in which + // each face of the geometry is treated + // as a separate "solid" entity + else if (format == "STL Extended Format") + WriteSTLExtFormat (mesh, filename); + + else if (format == "VRML Format") + WriteVRMLFormat (mesh, 1, filename); + + else if (format == "Fepp Format") + WriteFEPPFormat (mesh, geom, filename); + + else if (format == "EdgeElement Format") + WriteEdgeElementFormat (mesh, geom, filename); + + else if (format == "Chemnitz Format") + WriteUserChemnitz (mesh, filename); + + else if (format == "Gmsh Format") + WriteGmshFormat (mesh, geom, filename); + + // Philippose - 29/01/2009 + // Added Gmsh v2.xx Mesh export capability + else if (format == "Gmsh2 Format") + WriteGmsh2Format (mesh, geom, filename); + + // Philippose - 25/10/2009 + // Added OpenFOAM 1.5+ Mesh export capability + else if (format == "OpenFOAM 1.5+ Format") + WriteOpenFOAM15xFormat (mesh, filename, false); + + else if (format == "OpenFOAM 1.5+ Compressed") + WriteOpenFOAM15xFormat (mesh, filename, true); + + else if (format == "JCMwave Format") + WriteJCMFormat (mesh, geom, filename); + +#ifdef OLIVER + else if (format == "TET Format") + WriteTETFormat( mesh, filename);//, "High Frequency" ); +#endif + + else + { + return 1; + } + + return 0; +} + + + + +/* + * Neutral mesh format + * points, elements, surface elements + */ + +void WriteNeutralFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + cout << "write neutral, new" << endl; + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int nseg = mesh.GetNSeg(); + int i, j; + + int inverttets = mparam.inverttets; + int invertsurf = mparam.inverttrigs; + + ofstream outfile (filename.c_str()); + + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + outfile << np << "\n"; + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + + outfile.width(10); + outfile << p.X() << " "; + outfile.width(9); + outfile << p.Y() << " "; + if (mesh.GetDimension() == 3) + { + outfile.width(9); + outfile << p.Z(); + } + outfile << "\n"; + } + + if (mesh.GetDimension() == 3) + { + outfile << ne << "\n"; + for (i = 1; i <= ne; i++) + { + Element el = mesh.VolumeElement(i); + if (inverttets) + el.Invert(); + outfile.width(4); + outfile << el.GetIndex() << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile.width(8); + outfile << el.PNum(j); + } + outfile << "\n"; + } + } + + outfile << nse << "\n"; + for (i = 1; i <= nse; i++) + { + Element2d el = mesh.SurfaceElement(i); + if (invertsurf) + el.Invert(); + outfile.width(4); + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile.width(8); + outfile << el.PNum(j); + } + outfile << "\n"; + } + + + if (mesh.GetDimension() == 2) + { + outfile << nseg << "\n"; + for (i = 1; i <= nseg; i++) + { + const Segment & seg = mesh.LineSegment(i); + outfile.width(4); + outfile << seg.si << " "; + + outfile << " "; + outfile.width(8); + outfile << seg[0]; + outfile << " "; + outfile.width(8); + outfile << seg[1]; + + outfile << "\n"; + } + } +} + + + + + + + + + +void WriteSurfaceFormat (const Mesh & mesh, + const string & filename) +{ + // surface mesh + int i, j; + + cout << "Write Surface Mesh" << endl; + + ofstream outfile (filename.c_str()); + + outfile << "surfacemesh" << endl; + + outfile << mesh.GetNP() << endl; + for (i = 1; i <= mesh.GetNP(); i++) + { + for (j = 0; j < 3; j++) + { + outfile.width(10); + outfile << mesh.Point(i)(j) << " "; + } + outfile << endl; + } + outfile << mesh.GetNSE() << endl; + for (i = 1; i <= mesh.GetNSE(); i++) + { + for (j = 1; j <= 3; j++) + { + outfile.width(8); + outfile << mesh.SurfaceElement(i).PNum(j); + } + outfile << endl; + } +} + + + + + +/* + * save surface mesh as STL file + */ + +void WriteSTLFormat (const Mesh & mesh, + const string & filename) +{ + cout << "\nWrite STL Surface Mesh" << endl; + + ostream *outfile; + + if(filename.substr(filename.length()-3,3) == ".gz") + outfile = new ogzstream(filename.c_str()); + else + outfile = new ofstream(filename.c_str()); + + int i; + + outfile->precision(10); + + *outfile << "solid" << endl; + + for (i = 1; i <= mesh.GetNSE(); i++) + { + *outfile << "facet normal "; + const Point3d& p1 = mesh.Point(mesh.SurfaceElement(i).PNum(1)); + const Point3d& p2 = mesh.Point(mesh.SurfaceElement(i).PNum(2)); + const Point3d& p3 = mesh.Point(mesh.SurfaceElement(i).PNum(3)); + + Vec3d normal = Cross(p2-p1,p3-p1); + if (normal.Length() != 0) + { + normal /= (normal.Length()); + } + + *outfile << normal.X() << " " << normal.Y() << " " << normal.Z() << "\n"; + *outfile << "outer loop\n"; + + *outfile << "vertex " << p1.X() << " " << p1.Y() << " " << p1.Z() << "\n"; + *outfile << "vertex " << p2.X() << " " << p2.Y() << " " << p2.Z() << "\n"; + *outfile << "vertex " << p3.X() << " " << p3.Y() << " " << p3.Z() << "\n"; + + *outfile << "endloop\n"; + *outfile << "endfacet\n"; + } + *outfile << "endsolid" << endl; +} + + + + + +/* + * Philippose - 16 August 2010 + * Save surface mesh as STL file + * with a separate solid definition + * for each face + * - This helps in splitting up the + * STL into named boundary faces + * when using a third-party mesher + */ +void WriteSTLExtFormat (const Mesh & mesh, + const string & filename) +{ + cout << "\nWrite STL Surface Mesh (with separated boundary faces)" << endl; + + ostream *outfile; + + if(filename.substr(filename.length()-3,3) == ".gz") + outfile = new ogzstream(filename.c_str()); + else + outfile = new ofstream(filename.c_str()); + + outfile->precision(10); + + int numBCs = 0; + + Array faceBCs; + TABLE faceBCMapping; + + faceBCs.SetSize(mesh.GetNFD()); + faceBCMapping.SetSize(mesh.GetNFD()); + + faceBCs = -1; + + // Collect the BC numbers used in the mesh + for(int faceNr = 1; faceNr <= mesh.GetNFD(); faceNr++) + { + int bcNum = mesh.GetFaceDescriptor(faceNr).BCProperty(); + + if(faceBCs.Pos(bcNum) < 0) + { + numBCs++; + faceBCs.Set(numBCs,bcNum); + faceBCMapping.Add1(numBCs,faceNr); + } + else + { + faceBCMapping.Add1(faceBCs.Pos(bcNum)+1,faceNr); + } + } + + faceBCs.SetSize(numBCs); + faceBCMapping.ChangeSize(numBCs); + + // Now actually write the data to file + for(int bcInd = 1; bcInd <= faceBCs.Size(); bcInd++) + { + *outfile << "solid Boundary_" << faceBCs.Elem(bcInd) << "\n"; + + for(int faceNr = 1;faceNr <= faceBCMapping.EntrySize(bcInd); faceNr++) + { + Array faceSei; + mesh.GetSurfaceElementsOfFace(faceBCMapping.Get(bcInd,faceNr),faceSei); + + for (int i = 0; i < faceSei.Size(); i++) + { + *outfile << "facet normal "; + const Point3d& p1 = mesh.Point(mesh.SurfaceElement(faceSei[i]).PNum(1)); + const Point3d& p2 = mesh.Point(mesh.SurfaceElement(faceSei[i]).PNum(2)); + const Point3d& p3 = mesh.Point(mesh.SurfaceElement(faceSei[i]).PNum(3)); + + Vec3d normal = Cross(p2-p1,p3-p1); + if (normal.Length() != 0) + { + normal /= (normal.Length()); + } + + *outfile << normal.X() << " " << normal.Y() << " " << normal.Z() << "\n"; + *outfile << "outer loop\n"; + + *outfile << "vertex " << p1.X() << " " << p1.Y() << " " << p1.Z() << "\n"; + *outfile << "vertex " << p2.X() << " " << p2.Y() << " " << p2.Z() << "\n"; + *outfile << "vertex " << p3.X() << " " << p3.Y() << " " << p3.Z() << "\n"; + + *outfile << "endloop\n"; + *outfile << "endfacet\n"; + } + } + *outfile << "endsolid Boundary_" << faceBCs.Elem(bcInd) << "\n"; + } +} + + + + +/* + * + * write surface mesh as VRML file + * + */ + +void WriteVRMLFormat (const Mesh & mesh, + bool faces, + const string & filename) +{ + + if (faces) + + { + // Output in VRML, IndexedFaceSet is used + // Bartosz Sawicki + + int np = mesh.GetNP(); + int nse = mesh.GetNSE(); + int i, j; + + ofstream outfile (filename.c_str()); + + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + outfile << "#VRML V2.0 utf8 \n" + "Background {\n" + " skyColor [1 1 1]\n" + " groundColor [1 1 1]\n" + "}\n" + "Group{ children [\n" + "Shape{ \n" + "appearance Appearance { material Material { }} \n" + "geometry IndexedFaceSet { \n" + "coord Coordinate { point [ \n"; + + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + outfile.width(10); + outfile << p.X() << " "; + outfile << p.Y() << " "; + outfile << p.Z() << " \n"; + } + + outfile << " ] } \n" + "coordIndex [ \n"; + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + + for (j = 1; j <= 3; j++) + { + outfile.width(8); + outfile << el.PNum(j)-1; + } + outfile << " -1 \n"; + } + + outfile << " ] \n"; + + //define number and RGB definitions of colors + outfile << "color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0]} \n" + "colorIndex [\n"; + + for (i = 1; i <= nse; i++) + { + outfile << mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex ()).BCProperty(); + outfile << endl; + } + + outfile << " ] \n" + "colorPerVertex FALSE \n" + "creaseAngle 0 \n" + "solid FALSE \n" + "ccw FALSE \n" + "convex TRUE \n" + "} } # end of Shape\n" + "] }\n"; + + } /* end of VRMLFACES */ + + + else + + { + // Output in VRML, IndexedLineSet is used + // Bartosz Sawicki + + int np = mesh.GetNP(); + int nse = mesh.GetNSE(); + int i, j; + + ofstream outfile (filename.c_str()); + + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + outfile << "#VRML V2.0 utf8 \n" + "Background {\n" + " skyColor [1 1 1]\n" + " groundColor [1 1 1]\n" + "}\n" + "Group{ children [\n" + "Shape{ \n" + "appearance Appearance { material Material { }} \n" + "geometry IndexedLineSet { \n" + "coord Coordinate { point [ \n"; + + + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + outfile.width(10); + outfile << p.X() << " "; + outfile << p.Y() << " "; + outfile << p.Z() << " \n"; + } + + outfile << " ] } \n" + "coordIndex [ \n"; + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + + for (j = 1; j <= 3; j++) + { + outfile.width(8); + outfile << el.PNum(j)-1; + } + outfile.width(8); + outfile << el.PNum(1)-1; + outfile << " -1 \n"; + } + + outfile << " ] \n"; + +/* Uncomment if you want color mesh + outfile << "color Color { color [1 1 1, 0 1 0, 0 0 1, 1 1 0]} \n" + "colorIndex [\n"; + + for (i = 1; i <= nse; i++) + { + outfile << mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex ()).BCProperty(); + outfile << endl; + } + + outfile << " ] \n" +*/ + outfile << "colorPerVertex FALSE \n" + "} } #end of Shape\n" + "] } \n"; + + } + +} + + + + + + +/* + * FEPP .. a finite element package developed at University Linz, Austria + */ +void WriteFEPPFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + + ofstream outfile (filename.c_str()); + + if (mesh.GetDimension() == 3) + + { + + // output for FEPP + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int ns = mesh.GetNFD(); + int i, j; + + outfile.precision(5); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + outfile << "volumemesh4" << endl; + outfile << nse << endl; + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + + // int facenr = mesh.facedecoding.Get(el.GetIndex()).surfnr; + outfile.width(4); + outfile << el.GetIndex() << " "; + outfile.width(4); + // outfile << mesh.GetFaceDescriptor(el.GetIndex()).BCProperty() << " "; + outfile << mesh.GetFaceDescriptor(el.GetIndex()).BCProperty() << " "; + outfile.width(4); + outfile << el.GetNP() << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile.width(8); + outfile << el.PNum(j); + } + outfile << "\n"; + } + + + outfile << ne << "\n"; + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + outfile.width(4); + outfile << el.GetIndex() << " "; + outfile.width(4); + outfile << el.GetNP() << " "; + for (j = 1; j <= el.GetNP(); j++) + { + outfile.width(8); + outfile << el.PNum(j); + } + outfile << "\n"; + } + + outfile << np << "\n"; + for (i = 1; i <= np; i++) + { + const Point3d & p = mesh.Point(i); + + outfile.width(10); + outfile << p.X() << " "; + outfile.width(9); + outfile << p.Y() << " "; + outfile.width(9); + outfile << p.Z() << "\n"; + } + + /* + if (typ == WRITE_FEPPML) + { + int nbn = mesh.mlbetweennodes.Size(); + outfile << nbn << "\n"; + for (i = 1; i <= nbn; i++) + outfile << mesh.mlbetweennodes.Get(i).I1() << " " + << mesh.mlbetweennodes.Get(i).I2() << "\n"; + + + // int ncon = mesh.connectedtonode.Size(); + // outfile << ncon << "\n"; + // for (i = 1; i <= ncon; i++) + // outfile << i << " " << mesh.connectedtonode.Get(i) << endl; + } + */ + + + // write CSG surfaces + if (&geom && geom.GetNSurf() >= ns) + { + outfile << ns << endl; + for (i = 1; i <= ns; i++) + geom.GetSurface(mesh.GetFaceDescriptor(i).SurfNr())->Print(outfile); + } + else + outfile << "0" << endl; + } + + + else + + { // 2D fepp format + + ; + /* + extern SplineGeometry2d * geometry2d; + if (geometry2d) + Save2DMesh (mesh, &geometry2d->GetSplines(), outfile); + else + Save2DMesh (mesh, 0, outfile); + */ + } +} + + + + + + +/* + * Edge element mesh format + * points, elements, edges + */ + +void WriteEdgeElementFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename) +{ + cout << "write edge element format" << endl; + + const MeshTopology * top = &mesh.GetTopology(); + int npoints = mesh.GetNP(); + int nelements = mesh.GetNE(); + int nsurfelem = mesh.GetNSE(); + int nedges = top->GetNEdges(); + int i, j; + + int inverttets = mparam.inverttets; + int invertsurf = mparam.inverttrigs; + Array edges; + + ofstream outfile (filename.c_str()); + + outfile.precision(6); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + + // vertices with coordinates + outfile << npoints << "\n"; + for (i = 1; i <= npoints; i++) + { + const Point3d & p = mesh.Point(i); + + outfile.width(10); + outfile << p.X() << " "; + outfile.width(9); + outfile << p.Y() << " "; + outfile.width(9); + outfile << p.Z() << "\n"; + } + + // element - edge - list + outfile << nelements << " " << nedges << "\n"; + for (i = 1; i <= nelements; i++) + { + Element el = mesh.VolumeElement(i); + if (inverttets) + el.Invert(); + outfile.width(4); + outfile << el.GetIndex() << " "; + outfile.width(8); + outfile << el.GetNP(); + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile.width(8); + outfile << el.PNum(j); + } + + top->GetElementEdges(i,edges); + outfile << endl << " "; + outfile.width(8); + outfile << edges.Size(); + for (j=1; j <= edges.Size(); j++) + { + outfile << " "; + outfile.width(8); + outfile << edges[j-1]; + } + outfile << "\n"; + + // orientation: + top->GetElementEdgeOrientations(i,edges); + outfile << " "; + for (j=1; j <= edges.Size(); j++) + { + outfile << " "; + outfile.width(8); + outfile << edges[j-1]; + } + outfile << "\n"; + } + + // surface element - edge - list (with boundary conditions) + outfile << nsurfelem << "\n"; + for (i = 1; i <= nsurfelem; i++) + { + Element2d el = mesh.SurfaceElement(i); + if (invertsurf) + el.Invert(); + outfile.width(4); + outfile << mesh.GetFaceDescriptor (el.GetIndex()).BCProperty() << " "; + outfile.width(8); + outfile << el.GetNP(); + for (j = 1; j <= el.GetNP(); j++) + { + outfile << " "; + outfile.width(8); + outfile << el.PNum(j); + } + + top->GetSurfaceElementEdges(i,edges); + outfile << endl << " "; + outfile.width(8); + outfile << edges.Size(); + for (j=1; j <= edges.Size(); j++) + { + outfile << " "; + outfile.width(8); + outfile << edges[j-1]; + } + outfile << "\n"; + } + + + int v1, v2; + // edge - vertex - list + outfile << nedges << "\n"; + for (i=1; i <= nedges; i++) + { + top->GetEdgeVertices(i,v1,v2); + outfile.width(4); + outfile << v1; + outfile << " "; + outfile.width(8); + outfile << v2 << endl; + } +} + + + + + + + + + +#ifdef OLDSTYLE_WRITE + + +void WriteFile (int typ, + const Mesh & mesh, + const CSGeometry & geom, + const char * filename, + const char * geomfile, + double h) +{ + + + int inverttets = mparam.inverttets; + int invertsurf = mparam.inverttrigs; + + + + + + + + + if (typ == WRITE_EDGEELEMENT) + { + // write edge element file + // Peter Harscher, ETHZ + + cout << "Write Edge-Element Format" << endl; + + ofstream outfile (filename); + + int i, j; + int ned; + + // hash table representing edges; + INDEX_2_HASHTABLE edgeht(mesh.GetNP()); + + // list of edges + Array edgelist; + + // edge (point) on boundary ? + BitArray bedge, bpoint(mesh.GetNP()); + + static int eledges[6][2] = { { 1, 2 } , { 1, 3 } , { 1, 4 }, + { 2, 3 } , { 2, 4 } , { 3, 4 } }; + + // fill hashtable (point1, point2) ----> edgenr + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement (i); + INDEX_2 edge; + for (j = 1; j <= 6; j++) + { + edge.I1() = el.PNum (eledges[j-1][0]); + edge.I2() = el.PNum (eledges[j-1][1]); + edge.Sort(); + + if (!edgeht.Used (edge)) + { + edgelist.Append (edge); + edgeht.Set (edge, edgelist.Size()); + } + } + } + + + // set bedges, bpoints + bedge.SetSize (edgelist.Size()); + bedge.Clear(); + bpoint.Clear(); + + for (i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + for (j = 1; j <= 3; j++) + { + bpoint.Set (sel.PNum(j)); + + INDEX_2 edge; + edge.I1() = sel.PNum(j); + edge.I2() = sel.PNum(j%3+1); + edge.Sort(); + + bedge.Set (edgeht.Get (edge)); + } + } + + + + outfile << mesh.GetNE() << endl; + // write element ---> point + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement(i); + + outfile.width(8); + outfile << i; + for (j = 1; j <= 4; j++) + { + outfile.width(8); + outfile << el.PNum(j); + } + outfile << endl; + } + + // write element ---> edge + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement (i); + INDEX_2 edge; + for (j = 1; j <= 6; j++) + { + edge.I1() = el.PNum (eledges[j-1][0]); + edge.I2() = el.PNum (eledges[j-1][1]); + edge.Sort(); + + outfile.width(8); + outfile << edgeht.Get (edge); + } + outfile << endl; + } + + // write points + outfile << mesh.GetNP() << endl; + outfile.precision (6); + for (i = 1; i <= mesh.GetNP(); i++) + { + const Point3d & p = mesh.Point(i); + + for (j = 1; j <= 3; j++) + { + outfile.width(8); + outfile << p.X(j); + } + outfile << " " + << (bpoint.Test(i) ? "1" : 0) << endl; + } + + // write edges + outfile << edgelist.Size() << endl; + for (i = 1; i <= edgelist.Size(); i++) + { + outfile.width(8); + outfile << edgelist.Get(i).I1(); + outfile.width(8); + outfile << edgelist.Get(i).I2(); + outfile << " " + << (bedge.Test(i) ? "1" : "0") << endl; + } + } + + + + +} +#endif +} + diff --git a/libsrc/interface/writeuser.hpp b/libsrc/interface/writeuser.hpp new file mode 100644 index 00000000..7021a5f6 --- /dev/null +++ b/libsrc/interface/writeuser.hpp @@ -0,0 +1,166 @@ +#ifndef WRITEUSER +#define WRITEUSER + +/**************************************************************************/ +/* File: writeuser.hh */ +/* Authors: many */ +/* Date: 10. Dec. 97 */ +/**************************************************************************/ + + +extern +void WriteFile (int typ, + const Mesh & mesh, + const CSGeometry & geom, + const char * filename, + const char * geomfile = NULL, + double h = 0); + + + +extern +void ReadFile (Mesh & mesh, + const string & filename); + + + + + + +extern +void WriteNeutralFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + +extern +void WriteSurfaceFormat (const Mesh & mesh, + const string & filename); + +extern +void WriteSTLFormat (const Mesh & mesh, + const string & filename); + + +// Philippose - 16 August 2010 +// Added the STL Extended format in which +// each face of the geometry is treated as +// a separate "solid" entity in the STL file +extern +void WriteSTLExtFormat (const Mesh & mesh, + const string & filename); + + +extern +void WriteVRMLFormat (const Mesh & mesh, + bool faces, + const string & filename); + +extern +void WriteFEPPFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + +extern +void WriteGmshFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + + +// Philippose - 29/01/2009 +// Added GMSH v2.xx Mesh Export support +void WriteGmsh2Format (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + + +// Philippose - 25/10/2009 +// Added OpenFOAM 1.5+ Mesh Export support +extern +void WriteOpenFOAM15xFormat (const Mesh & mesh, + const string & casename, + const bool compressed); + + +extern +void WriteUserChemnitz (const Mesh & mesh, + const string & filename); + +extern +void WriteJCMFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + + +extern +void WriteDiffPackFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + +extern +void WriteTochnogFormat (const Mesh & mesh, + const string & filename); + +extern +void WriteTecPlotFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + +extern +void WriteAbaqusFormat (const Mesh & mesh, + const string & filename); + +extern +void WriteFluentFormat (const Mesh & mesh, + const string & filename); + +extern +void WritePermasFormat (const Mesh & mesh, + const string & filename); + +extern +void WriteFEAPFormat (const Mesh & mesh, + const string & filename); + +extern +void WriteElmerFormat (const Mesh & mesh, + const string & filename); + + +extern +void WriteEdgeElementFormat (const Mesh & mesh, + const CSGeometry & geom, + const string & filename); + + + +#ifdef OLIVER +extern +void WriteTETFormat (const Mesh & mesh, + const string & filename); + +#endif + +extern void ReadTETFormat (Mesh & mesh, + const string & filename); + + +extern void ReadFNFFormat (Mesh & mesh, + const string & filename); + + + +void WriteDolfinFormat (const Mesh & mesh, + const string & filename); + + +extern void RegisterUserFormats (Array & names, + Array & extensions); + + +extern bool WriteUserFormat (const string & format, + const Mesh & mesh, + const NetgenGeometry & geom, + const string & filename); + +#endif + diff --git a/libsrc/interface/wuchemnitz.cpp b/libsrc/interface/wuchemnitz.cpp new file mode 100644 index 00000000..8641a8cd --- /dev/null +++ b/libsrc/interface/wuchemnitz.cpp @@ -0,0 +1,317 @@ +// Write Chemnitz file format + + +#include + +#include + +#include +#include +#include + +namespace netgen +{ + + class POINT3D + { + public: + POINT3D () { }; + double x, y, z; + }; + + class VOLELEMENT + { + public: + int domnr, p1, p2, p3, p4; + int faces[4]; + + VOLELEMENT () + { for (int i = 0; i < 4; i++) faces[i] = 0; } + }; + + class SURFELEMENT + { + public: + SURFELEMENT () { }; + int snr, p1, p2, p3; + }; + + + class FACE + { + public: + int p1, p2, p3; + int edges[3]; + + FACE () + { for (int i = 0; i < 3; i++) edges[i] = 0; } + }; + + class EDGE + { + public: + EDGE () { }; + int p1, p2; + }; + + static Array points; + static Array volelements; + static Array surfelements; + + static Array faces; + static Array edges; + + + void ReadFile (char * filename) + { + int i, n; + ifstream infile(filename); + char reco[100]; + + + infile >> reco; // file format recognition + + infile >> n; // number of surface elements + cout << n << " Surface elements" << endl; + + for (i = 1; i <= n; i++) + { + SURFELEMENT sel; + infile >> sel.snr >> sel.p1 >> sel.p2 >> sel.p3; + surfelements.Append (sel); + } + + infile >> n; // number of volume elements + cout << n << " Volume elements" << endl; + + for (i = 1; i <= n; i++) + { + VOLELEMENT el; + infile >> el.p1 >> el.p2 >> el.p3 >> el.p4; + volelements.Append (el); + } + + infile >> n; // number of points + cout << n << " Points" << endl; + + for (i = 1; i <= n; i++) + { + POINT3D p; + infile >> p.x >> p.y >> p.z; + points.Append (p); + } + } + + + + void ReadFileMesh (const Mesh & mesh) + { + int i, n; + + n = mesh.GetNSE(); // number of surface elements + cout << n << " Surface elements" << endl; + + for (i = 1; i <= n; i++) + { + SURFELEMENT sel; + const Element2d & el = mesh.SurfaceElement(i); + sel.snr = el.GetIndex(); + sel.p1 = el.PNum(1); + sel.p2 = el.PNum(2); + sel.p3 = el.PNum(3); + surfelements.Append (sel); + } + + n = mesh.GetNE(); // number of volume elements + cout << n << " Volume elements" << endl; + + for (i = 1; i <= n; i++) + { + VOLELEMENT el; + const Element & nel = mesh.VolumeElement(i); + el.p1 = nel.PNum(1); + el.p2 = nel.PNum(2); + el.p3 = nel.PNum(3); + el.p4 = nel.PNum(4); + // infile >> el.p1 >> el.p2 >> el.p3 >> el.p4; + volelements.Append (el); + } + + n = mesh.GetNP(); // number of points + cout << n << " Points" << endl; + + for (i = 1; i <= n; i++) + { + POINT3D p; + Point3d mp = mesh.Point(i); + p.x = mp.X(); + p.y = mp.Y(); + p.z = mp.Z(); + // infile >> p.x >> p.y >> p.z; + points.Append (p); + } + } + + + + + void Convert () + { + int i, j, facei, edgei; + INDEX_3 i3; + INDEX_2 i2; + + INDEX_3_HASHTABLE faceindex(volelements.Size()/5 + 1); + INDEX_2_HASHTABLE edgeindex(volelements.Size()/5 + 1); + + for (i = 1; i <= volelements.Size(); i++) + { + for (j = 1; j <= 4; j++) + { + switch (j) + { + case 1: + i3.I1() = volelements.Get(i).p2; + i3.I2() = volelements.Get(i).p3; + i3.I3() = volelements.Get(i).p4; + break; + case 2: + i3.I1() = volelements.Get(i).p1; + i3.I2() = volelements.Get(i).p3; + i3.I3() = volelements.Get(i).p4; + break; + case 3: + i3.I1() = volelements.Get(i).p1; + i3.I2() = volelements.Get(i).p2; + i3.I3() = volelements.Get(i).p4; + break; + case 4: + i3.I1() = volelements.Get(i).p1; + i3.I2() = volelements.Get(i).p2; + i3.I3() = volelements.Get(i).p3; + break; + default: + i3.I1()=i3.I2()=i3.I3()=0; + } + i3.Sort(); + if (faceindex.Used (i3)) + facei = faceindex.Get(i3); + else + { + FACE fa; + fa.p1 = i3.I1(); + fa.p2 = i3.I2(); + fa.p3 = i3.I3(); + facei = faces.Append (fa); + faceindex.Set (i3, facei); + } + + volelements.Elem(i).faces[j-1] = facei; + } + + } + + + for (i = 1; i <= faces.Size(); i++) + { + for (j = 1; j <= 3; j++) + { + switch (j) + { + case 1: + i2.I1() = faces.Get(i).p2; + i2.I2() = faces.Get(i).p3; + break; + case 2: + i2.I1() = faces.Get(i).p1; + i2.I2() = faces.Get(i).p3; + break; + case 3: + i2.I1() = faces.Get(i).p1; + i2.I2() = faces.Get(i).p2; + break; + default: + i2.I1()=i2.I2()=0; + } + if (i2.I1() > i2.I2()) swap (i2.I1(), i2.I2()); + if (edgeindex.Used (i2)) + edgei = edgeindex.Get(i2); + else + { + EDGE ed; + ed.p1 = i2.I1(); + ed.p2 = i2.I2(); + edgei = edges.Append (ed); + edgeindex.Set (i2, edgei); + } + + faces.Elem(i).edges[j-1] = edgei; + } + + } + + } + + + void WriteFile (ostream & outfile) + { + int i; + + outfile + << "#VERSION: 1.0" << endl + << "#PROGRAM: NETGEN" << endl + << "#EQN_TYPE: POISSON" << endl + << "#DIMENSION: 3D" << endl + << "#DEG_OF_FREE: 1" << endl + << "#DESCRIPTION: I don't know" << endl + << "##RENUM: not done" << endl + << "#USER: Kleinzen" << endl + << "DATE: 10.06.1996" << endl; + + outfile << "#HEADER: 8" << endl + << points.Size() << " " << edges.Size() << " " + << faces.Size() << " " << volelements.Size() << " 0 0 0 0" << endl; + + outfile << "#VERTEX: " << points.Size() << endl; + for (i = 1; i <= points.Size(); i++) + outfile << " " << i << " " << points.Get(i).x << " " << points.Get(i).y + << " " << points.Get(i).z << endl; + + outfile << "#EDGE: " << edges.Size() << endl; + for (i = 1; i <= edges.Size(); i++) + outfile << " " << i << " 1 " + << edges.Get(i).p1 << " " + << edges.Get(i).p2 + << " 0" << endl; + + outfile << "#FACE: " << faces.Size() << endl; + for (i = 1; i <= faces.Size(); i++) + outfile << " " << i << " 1 3 " + << faces.Get(i).edges[0] << " " + << faces.Get(i).edges[1] << " " + << faces.Get(i).edges[2] << endl; + + outfile << "#SOLID: " << volelements.Size() << endl; + for (i = 1; i <= volelements.Size(); i++) + outfile << " " << i << " 1 4 " + << volelements.Get(i).faces[0] << " " + << volelements.Get(i).faces[1] << " " + << volelements.Get(i).faces[2] << " " + << volelements.Get(i).faces[3] << endl; + + outfile << "#END_OF_DATA" << endl; + } + + + void WriteUserChemnitz (const Mesh & mesh, + const string & filename) + { + ofstream outfile (filename.c_str()); + + ReadFileMesh (mesh); + Convert (); + + WriteFile (outfile); + cout << "Wrote Chemnitz standard file" << endl; + } +} diff --git a/libsrc/linalg/Makefile.am b/libsrc/linalg/Makefile.am new file mode 100644 index 00000000..c6f7c4d8 --- /dev/null +++ b/libsrc/linalg/Makefile.am @@ -0,0 +1,9 @@ +noinst_HEADERS = densemat.hpp linalg.hpp polynomial.hpp vector.hpp opti.hpp +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LTLIBRARIES = libla.la +libla_la_SOURCES = densemat.cpp polynomial.cpp bfgs.cpp linopt.cpp linsearch.cpp + +# vector.cpp + +# libla_la_LDFLAGS = -rdynamic diff --git a/libsrc/linalg/Makefile.in b/libsrc/linalg/Makefile.in new file mode 100644 index 00000000..e8445908 --- /dev/null +++ b/libsrc/linalg/Makefile.in @@ -0,0 +1,545 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc/linalg +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libla_la_LIBADD = +am_libla_la_OBJECTS = densemat.lo polynomial.lo bfgs.lo linopt.lo \ + linsearch.lo +libla_la_OBJECTS = $(am_libla_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libla_la_SOURCES) +DIST_SOURCES = $(libla_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = densemat.hpp linalg.hpp polynomial.hpp vector.hpp opti.hpp +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include +METASOURCES = AUTO +noinst_LTLIBRARIES = libla.la +libla_la_SOURCES = densemat.cpp polynomial.cpp bfgs.cpp linopt.cpp linsearch.cpp +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/linalg/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/linalg/Makefile +.PRECIOUS: 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)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libla.la: $(libla_la_OBJECTS) $(libla_la_DEPENDENCIES) $(EXTRA_libla_la_DEPENDENCIES) + $(CXXLINK) $(libla_la_OBJECTS) $(libla_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bfgs.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/densemat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linopt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linsearch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polynomial.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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 all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags 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 uninstall uninstall-am + + +# vector.cpp + +# libla_la_LDFLAGS = -rdynamic + +# 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/libsrc/linalg/bfgs.cpp b/libsrc/linalg/bfgs.cpp new file mode 100644 index 00000000..65189dee --- /dev/null +++ b/libsrc/linalg/bfgs.cpp @@ -0,0 +1,409 @@ +/***************************************************************************/ +/* */ +/* Vorlesung Optimierung I, Gfrerer, WS94/95 */ +/* BFGS-Verfahren zur Lösung freier nichtlinearer Optimierungsprobleme */ +/* */ +/* Programmautor: Joachim Schöberl */ +/* Matrikelnummer: 9155284 */ +/* */ +/***************************************************************************/ + +#include +#include + +#include +#include "opti.hpp" + + +namespace netgen +{ + +void Cholesky (const DenseMatrix & a, + DenseMatrix & l, Vector & d) +{ + // Factors A = L D L^T + + double x; + + int n = a.Height(); + + // (*testout) << "a = " << a << endl; + + l = a; + + for (int i = 1; i <= n; i++) + { + for (int j = i; j <= n; j++) + { + x = l.Get(i, j); + + for (int k = 1; k < i; k++) + x -= l.Get(i, k) * l.Get(j, k) * d(k-1); + + if (i == j) + { + d(i-1) = x; + } + else + { + l.Elem(j, i) = x / d(i-1); + } + } + } + + for (int i = 1; i <= n; i++) + { + l.Elem(i, i) = 1; + for (int j = i+1; j <= n; j++) + l.Elem(i, j) = 0; + } + + /* + // Multiply: + (*testout) << "multiplied factors: " << endl; + for (i = 1; i <= n; i++) + for (j = 1; j <= n; j++) + { + x = 0; + for (k = 1; k <= n; k++) + x += l.Get(i, k) * l.Get(j, k) * d.Get(k); + (*testout) << x << " "; + } + (*testout) << endl; + */ +} + + +void MultLDLt (const DenseMatrix & l, const Vector & d, const Vector & g, Vector & p) +{ + /* + int i, j, n; + double val; + + n = l.Height(); + p = g; + for (i = 1; i <= n; i++) + { + val = 0; + for (j = i; j <= n; j++) + val += p.Get(j) * l.Get(j, i); + p.Set(i, val); + } + for (i = 1; i <= n; i++) + p.Elem(i) *= d.Get(i); + + for (i = n; i >= 1; i--) + { + val = 0; + for (j = 1; j <= i; j++) + val += p.Get(j) * l.Get(i, j); + p.Set(i, val); + } + */ + + + + double val; + + int n = l.Height(); + p = g; + + for (int i = 0; i < n; i++) + { + val = 0; + for (int j = i; j < n; j++) + val += p(j) * l(j, i); + p(i) = val; + } + + for (int i = 0; i < n; i++) + p(i) *= d(i); + + for (int i = n-1; i >= 0; i--) + { + val = 0; + for (int j = 0; j <= i; j++) + val += p(j) * l(i, j); + p(i) = val; + } +} + +void SolveLDLt (const DenseMatrix & l, const Vector & d, const Vector & g, Vector & p) +{ + double val; + + int n = l.Height(); + p = g; + + for (int i = 0; i < n; i++) + { + val = 0; + for (int j = 0; j < i; j++) + val += p(j) * l(i,j); + p(i) -= val; + } + + for (int i = 0; i < n; i++) + p(i) /= d(i); + + for (int i = n-1; i >= 0; i--) + { + val = 0; + for (int j = i+1; j < n; j++) + val += p(j) * l(j, i); + p(i) -= val; + } +} + +int LDLtUpdate (DenseMatrix & l, Vector & d, double a, const Vector & u) +{ + // Bemerkung: Es wird a aus R erlaubt + // Rueckgabewert: 0 .. D bleibt positiv definit + // 1 .. sonst + + int n = l.Height(); + + Vector v(n); + double t, told, xi; + + told = 1; + v = u; + + for (int j = 1; j <= n; j++) + { + t = told + a * sqr (v(j-1)) / d(j-1); + + if (t <= 0) + { + (*testout) << "update err, t = " << t << endl; + return 1; + } + + xi = a * v(j-1) / (d(j-1) * t); + + d(j-1) *= t / told; + + for (int i = j + 1; i <= n; i++) + { + v(i-1) -= v(j-1) * l.Elem(i, j); + l.Elem(i, j) += xi * v(i-1); + } + + told = t; + } + + return 0; +} + + +double BFGS ( + Vector & x, // i: Startwert + // o: Loesung, falls IFAIL = 0 + const MinFunction & fun, + const OptiParameters & par, + double eps + ) + + +{ + int n = x.Size(); + long it; + char a1crit, a3acrit; + + + Vector d(n), g(n), p(n), temp(n), bs(n), xneu(n), y(n), s(n), x0(n); + DenseMatrix l(n); + DenseMatrix hesse(n); + + double /* normg, */ alphahat, hd, fold; + double a1, a2; + const double mu1 = 0.1, sigma = 0.1, xi1 = 1, xi2 = 10; + const double tau = 0.1, tau1 = 0.1, tau2 = 0.6; + + Vector typx(x.Size()); // i: typische Groessenordnung der Komponenten + double f, f0; + double typf; // i: typische Groessenordnung der Loesung + double fmin = -1e5; // i: untere Schranke fuer Funktionswert + // double eps = 1e-8; // i: Abbruchschranke fuer relativen Gradienten + double tauf = 0.1; // i: Abbruchschranke fuer die relative Aenderung der + // Funktionswerte + int ifail; // o: 0 .. Erfolg + // -1 .. Unterschreitung von fmin + // 1 .. kein Erfolg bei Liniensuche + // 2 .. Ãœberschreitung von itmax + + typx = par.typx; + typf = par.typf; + + + l = 0; + for (int i = 1; i <= n; i++) + l.Elem(i, i) = 1; + + f = fun.FuncGrad (x, g); + f0 = f; + x0 = x; + + it = 0; + do + { + // Restart + // cout << "it " << it << "f = " << f << endl; + if (it % (5 * n) == 0) + { + + for (int i = 1; i <= n; i++) + d(i-1) = typf/ sqr (typx(i-1)); // 1; + for (int i = 2; i <= n; i++) + for (int j = 1; j < i; j++) + l.Elem(i, j) = 0; + + /* + hesse = 0; + for (i = 1; i <= n; i++) + hesse.Elem(i, i) = typf / sqr (typx.Get(i)); + + fun.ApproximateHesse (x, hesse); + + Cholesky (hesse, l, d); + */ + } + + it++; + if (it > par.maxit_bfgs) + { + ifail = 2; + break; + } + + + // Solve with factorized B + + SolveLDLt (l, d, g, p); + + // (*testout) << "l " << l << endl +// << "d " << d << endl +// << "g " << g << endl +// << "p " << p << endl; + + + p *= -1; + y = g; + + fold = f; + + // line search + + alphahat = 1; + lines (x, xneu, p, f, g, fun, par, alphahat, fmin, + mu1, sigma, xi1, xi2, tau, tau1, tau2, ifail); + + if(ifail == 1) + (*testout) << "no success with linesearch" << endl; + + /* + // if (it > par.maxit_bfgs/2) + { + (*testout) << "x = " << x << endl; + (*testout) << "xneu = " << xneu << endl; + (*testout) << "f = " << f << endl; + (*testout) << "g = " << g << endl; + } + */ + + // (*testout) << "it = " << it << " f = " << f << endl; + // if (ifail != 0) break; + + s.Set2 (1, xneu, -1, x); + y *= -1; + y.Add (1,g); // y += g; + + x = xneu; + + // BFGS Update + + MultLDLt (l, d, s, bs); + + a1 = y * s; + a2 = s * bs; + + if (a1 > 0 && a2 > 0) + { + if (LDLtUpdate (l, d, 1 / a1, y) != 0) + { + cerr << "BFGS update error1" << endl; + (*testout) << "BFGS update error1" << endl; + (*testout) << "l " << endl << l << endl + << "d " << d << endl; + ifail = 1; + break; + } + + if (LDLtUpdate (l, d, -1 / a2, bs) != 0) + { + cerr << "BFGS update error2" << endl; + (*testout) << "BFGS update error2" << endl; + (*testout) << "l " << endl << l << endl + << "d " << d << endl; + ifail = 1; + break; + } + } + + // Calculate stop conditions + + hd = eps * max2 (typf, fabs (f)); + a1crit = 1; + for (int i = 1; i <= n; i++) + if ( fabs (g(i-1)) * max2 (typx(i-1), fabs (x(i-1))) > hd) + a1crit = 0; + + + a3acrit = (fold - f <= tauf * max2 (typf, fabs (f))); + + // testout << "g = " << g << endl; + // testout << "a1crit, a3crit = " << int(a1crit) << ", " << int(a3acrit) << endl; + + /* + // Output for tests + + normg = sqrt (g * g); + + testout << "it =" << setw (5) << it + << " f =" << setw (12) << setprecision (5) << f + << " |g| =" << setw (12) << setprecision (5) << normg; + + testout << " x = (" << setw (12) << setprecision (5) << x.Elem(1); + for (i = 2; i <= n; i++) + testout << "," << setw (12) << setprecision (5) << x.Elem(i); + testout << ")" << endl; + */ + + //(*testout) << "it = " << it << " f = " << f << " x = " << x << endl + // << " g = " << g << " p = " << p << endl << endl; + + // (*testout) << "|g| = " << g.L2Norm() << endl; + + if (g.L2Norm() < fun.GradStopping (x)) break; + + } + while (!a1crit || !a3acrit); + + /* + (*testout) << "it = " << it << " g = " << g << " f = " << f + << " fail = " << ifail << endl; + */ + if (f0 < f || (ifail == 1)) + { + (*testout) << "fail, f = " << f << " f0 = " << f0 << endl; + f = f0; + x = x0; + } + + // cout << endl; + + // (*testout) << "x = " << x << ", x0 = " << x0 << endl; + return f; +} + +} diff --git a/libsrc/linalg/densemat.cpp b/libsrc/linalg/densemat.cpp new file mode 100644 index 00000000..a0066e8f --- /dev/null +++ b/libsrc/linalg/densemat.cpp @@ -0,0 +1,1384 @@ +#include + +#include + + +namespace netgen +{ + DenseMatrix :: DenseMatrix () + { + data = NULL; + height = 0; + width = 0; + } + + DenseMatrix :: DenseMatrix (int h, int w) + { + if (!w) w = h; + width = w; + height = h; + if (h*w) + data = new double[h*w]; + else + data = 0; + + for (int i = 0 ; i < (h * w); i++) + data[i] = 0; + } + + /* + DenseMatrix :: DenseMatrix (int h, int w, const double * d) + : BaseMatrix (h, w) + { + int size = h * w; + int i; + + if (size) + { + data = new double[size]; + for (i = 0; i < size; i++) + data[i] = d[i]; + } + else + data = NULL; + } + */ + + DenseMatrix :: DenseMatrix (const DenseMatrix & m2) + { + data = NULL; height = width = 0; + SetSize (m2.Height(), m2.Width()); + memcpy (data, m2.data, sizeof(double) * Height() * Width()); + } + + DenseMatrix :: ~DenseMatrix () + { + delete [] data; + } + + + void DenseMatrix :: SetSize (int h, int w) + { + if (!w) w = h; + if (height == h && width == w) + return; + + height = h; + width = w; + + delete[] data; + + if (h*w) + data = new double[h*w]; + else + data = NULL; + } + + + /* + DenseMatrix & DenseMatrix :: operator= (const BaseMatrix & m2) + { + int i, j; + + SetSize (m2.Height(), m2.Width()); + + if (data) + for (i = 1; i <= Height(); i++) + for (j = 1; j <= Width(); j++) + Set (i, j, m2(i, j)); + else + (*myerr) << "DenseMatrix::Operator=: Matrix not allocated" << endl; + + return *this; + } + */ + + + DenseMatrix & DenseMatrix :: operator= (const DenseMatrix & m2) + { + SetSize (m2.Height(), m2.Width()); + + if (data) memcpy (data, m2.data, sizeof(double) * m2.Height() * m2.Width()); + return *this; + } + + + DenseMatrix & DenseMatrix :: operator+= (const DenseMatrix & m2) + { + int i; + double * p, * q; + + if (Height() != m2.Height() || Width() != m2.Width()) + { + (*myerr) << "DenseMatrix::Operator+=: Sizes don't fit" << endl; + return *this; + } + + if (data) + { + p = data; + q = m2.data; + for (i = Width() * Height(); i > 0; i--) + { + *p += *q; + p++; + q++; + } + } + else + (*myerr) << "DenseMatrix::Operator+=: Matrix not allocated" << endl; + + return *this; + } + + + DenseMatrix & DenseMatrix :: operator-= (const DenseMatrix & m2) + { + int i; + double * p, * q; + + if (Height() != m2.Height() || Width() != m2.Width()) + { + (*myerr) << "DenseMatrix::Operator-=: Sizes don't fit" << endl; + return *this; + } + + if (data) + { + p = data; + q = m2.data; + for (i = Width() * Height(); i > 0; i--) + { + *p -= *q; + p++; + q++; + } + } + else + (*myerr) << "DenseMatrix::Operator-=: Matrix not allocated" << endl; + + return *this; + } + + DenseMatrix & DenseMatrix :: operator= (double v) + { + double * p = data; + + if (data) + for (int i = width*height; i > 0; i--, p++) + *p = v; + + return *this; + } + + + + DenseMatrix & DenseMatrix :: operator*= (double v) + { + double * p = data; + + if (data) + for (int i = width*height; i > 0; i--, p++) + *p *= v; + + return *this; + } + + + double DenseMatrix :: Det () const + { + if (width != height) + { + (*myerr) << "DenseMatrix :: Det: width != height" << endl; + return 0; + } + + switch (width) + { + case 1: return data[0]; + case 2: return data[0] * data[3] - data[1] * data[2]; + case 3: return data[0] * data[4] * data[8] + + data[1] * data[5] * data[6] + + data[2] * data[3] * data[7] + - data[0] * data[5] * data[7] + - data[1] * data[3] * data[8] + - data[2] * data[4] * data[6]; + default: + { + (*myerr) << "Matrix :: Det: general size not implemented (size=" << width << ")" << endl; + return 0; + } + } + } + + + void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2) + { + double det; + + if (m1.Width() != m1.Height()) + { + (*myerr) << "CalcInverse: matrix not symmetric" << endl; + return; + } + if (m1.Width() != m2.Width() || m1.Height() != m2.Height()) + { + (*myerr) << "CalcInverse: dim(m2) != dim(m1)" << endl; + return; + } + + + if (m1.Width() <= 3) + { + det = m1.Det(); + if (det == 0) + { + (*myerr) << "CalcInverse: Matrix singular" << endl; + (*testout) << "CalcInverse: Matrix singular" << endl; + return; + } + + det = 1.0 / det; + switch (m1.Width()) + { + case 1: + { + m2(0,0) = det; + return; + } + case 2: + { + m2(0,0) = det * m1(3); + m2(1,1) = det * m1(0); + m2(0,1) = -det * m1(1); + m2(1,0) = - det * m1(2); + return; + } + case 3: + { + m2(0, 0) = det * (m1(4) * m1(8) - m1(5) * m1(7)); + m2(1, 0) = -det * (m1(3) * m1(8) - m1(5) * m1(6)); + m2(2, 0) = det * (m1(3) * m1(7) - m1(4) * m1(6)); + + m2(0, 1) = -det * (m1(1) * m1(8) - m1(2) * m1(7)); + m2(1, 1) = det * (m1(0) * m1(8) - m1(2) * m1(6)); + m2(2, 1) = -det * (m1(0) * m1(7) - m1(1) * m1(6)); + + m2(0, 2) = det * (m1(1) * m1(5) - m1(2) * m1(4)); + m2(1, 2) = -det * (m1(0) * m1(5) - m1(2) * m1(3)); + m2(2, 2) = det * (m1(0) * m1(4) - m1(1) * m1(3)); + return; + } + } + } + + else + { + int i, j, k, n; + n = m1.Height(); + + +#ifdef CHOL + int dots = (n > 200); + + // Cholesky + + double x; + Vector p(n); + + m2 = m1; + /* + m2.SetSymmetric(); + if (!m2.Symmetric()) + cerr << "m should be symmetric for Cholesky" << endl; + */ + + for (i = 1; i <= n; i++) + for (j = 1; j < i; j++) + m2.Elem(j, i) = m2.Get(i, j); + + for (i = 1; i <= n; i++) + { + if (dots && i % 10 == 0) + (*mycout) << "." << flush; + + for (j = i; j <= n; j++) + { + x = m2.Get(i, j); + + const double * pik = &m2.Get(i, 1); + const double * pjk = &m2.Get(j, 1); + + for (k = i-2; k >= 0; --k, ++pik, ++pjk) + x -= (*pik) * (*pjk); + + // for (k = i-1; k >= 1; --k) + // x -= m2.Get(j, k) * m2.Get(i, k); + + if (i == j) + { + if (x <= 0) + { + cerr << "Matrix indefinite 1" << endl; + return; + } + + p.Elem(i) = 1 / sqrt(x); + } + else + { + m2.Elem(j, i) = x * p.Get(i); + } + } + } + + for (i = 1; i <= n; i++) + m2.Elem(i, i) = 1 / p.Get(i); + + // check: A = L L^t + + // for (i = 1; i <= n; i++) + // for (j = 1; j <= n; j++) + // { + // x = 0; + // for (k = 1; k <= i && k <= j; k++) + // x += m2.Get(i, k) * m2.Get(j, k); + // (*testout) << "err " << i << "," << j << " = " << (m1.Get(i, j) - x) << endl; + // } + + + + // calc L^{-1}, store upper triangle + + // DenseMatrix hm(n); + // hm = m2; + + for (i = 1; i <= n; i++) + { + if (dots && i % 10 == 0) + (*mycout) << "+" << flush; + + for (j = i; j <= n; j++) + { + x = 0; + if (j == i) x = 1; + + const double * pjk = &m2.Get(j, i); + const double * pik = &m2.Get(i, i); + for (k = i; k < j; k++, ++pjk, ++pik) + x -= *pik * *pjk; + + // for (k = i; k < j; k++) + // x -= m2.Get(j, k) * m2.Get(i, k); + + m2.Elem(i, j) = x / m2.Get(j, j); + } + } + + // (*testout) << "check L^-1" << endl; + // for (i = 1; i <= n; i++) + // for (j = 1; j <= n; j++) + // { + // x = 0; + // for (k = j; k <= i; k++) + // x += hm.Get(i, k) * m2.Get(j, k); + // (*testout) << "i, j = " << i << "," << j << " x = " << x << endl; + // } + + + // calc A^-1 = L^-T * L^-1 + + for (i = 1; i <= n; i++) + { + if (dots && i % 10 == 0) + (*mycout) << "-" << flush; + + for (j = 1; j <= i; j++) + { + x = 0; + k = i; + if (j > i) k = j; + + const double * pik = &m2.Get(i, k); + const double * pjk = &m2.Get(j, k); + + for ( ; k <= n; ++k, ++pik, ++pjk) + x += *pik * *pjk; + // for ( ; k <= n; k++) + // x += m2.Get(i, k) * m2.Get(j, k); + + m2.Elem(i, j) = x; + } + } + + for (i = 1; i <= n; i++) + for (j = 1; j < i; j++) + m2.Elem(j, i) = m2.Get(i, j); + + if (dots) (*mycout) << endl; +#endif + + + + // Gauss - Jordan - algorithm + + int r, hi; + double max, hr; + + + Array p(n); // pivot-permutation + Vector hv(n); + + + m2 = m1; + + /* + if (m2.Symmetric()) + for (i = 1; i <= n; i++) + for (j = 1; j < i; j++) + m2.Elem(j, i) = m2.Get(i, j); + */ + + // Algorithm of Stoer, Einf. i. d. Num. Math, S 145 + + for (j = 1; j <= n; j++) + p.Set(j, j); + + for (j = 1; j <= n; j++) + { + // pivot search + + max = fabs(m2.Get(j, j)); + r = j; + + for (i = j+1; i <= n ;i++) + if (fabs (m2.Get(i, j)) > max) + { + r = i; + max = fabs (m2.Get(i, j)); + } + + if (max < 1e-20) + { + cerr << "Inverse matrix: matrix singular" << endl; + *testout << "Inverse matrix: matrix singular" << endl; + return; + } + + r = j; + + // exchange rows + if (r > j) + { + for (k = 1; k <= n; k++) + { + hr = m2.Get(j, k); + m2.Elem(j, k) = m2.Get(r, k); + m2.Elem(r, k) = hr; + } + hi = p.Get(j); + p.Elem(j) = p.Get(r); + p.Elem(r) = hi; + } + + + // transformation + + hr = 1 / m2.Get(j, j); + for (i = 1; i <= n; i++) + m2.Elem(i, j) *= hr; + m2.Elem(j, j) = hr; + + for (k = 1; k <= n; k++) + if (k != j) + { + for (i = 1; i <= n; i++) + if (i != j) + m2.Elem(i, k) -= m2.Elem(i, j) * m2.Elem(j, k); + m2.Elem(j, k) *= -hr; + } + } + + // col exchange + + for (i = 1; i <= n; i++) + { + for (k = 1; k <= n; k++) + hv(p.Get(k)-1) = m2.Get(i, k); + for (k = 1; k <= n; k++) + m2.Elem(i, k) = hv(k-1); + } + + + + /* + if (m1.Symmetric()) + for (i = 1; i <= n; i++) + for (j = 1; j < i; j++) + m1.Elem(j, i) = m1.Get(i, j); + + m2 = 0; + + for (i = 1; i <= n; i++) + m2.Elem(i, i) = 1; + + for (i = 1; i <= n; i++) + { + // (*mycout) << '.' << flush; + q = m1.Get(i, i); + for (k = 1; k <= n; k++) + { + m1.Elem(i, k) /= q; + m2.Elem(i, k) /= q; + } + + for (j = i+1; j <= n; j++) + { + q = m1.Elem(j, i); + + double * m1pi = &m1.Elem(i, i); + double * m1pj = &m1.Elem(j, i); + + for (k = n; k >= i; --k, ++m1pi, ++m1pj) + *m1pj -= q * (*m1pi); + + double * m2pi = &m2.Elem(i, 1); + double * m2pj = &m2.Elem(j, 1); + + for (k = i; k > 0; --k, ++m2pi, ++m2pj) + *m2pj -= q * (*m2pi); + + // for (k = 1; k <= n; k++) + // { + // m1.Elem(j, k) -= q * m1.Elem(i, k); + // m2.Elem(j, k) -= q * m2.Elem(i, k); + // } + + } + } + + for (i = n; i >= 1; i--) + { + // (*mycout) << "+" << flush; + for (j = 1; j < i; j++) + { + q = m1.Elem(j, i); + + double * m2pi = &m2.Elem(i, 1); + double * m2pj = &m2.Elem(j, 1); + + for (k = n; k > 0; --k, ++m2pi, ++m2pj) + *m2pj -= q * (*m2pi); + + + // for (k = 1; k <= n; k++) + // { + // m1.Elem(j, k) -= q * m1.Elem(i, k); + // m2.Elem(j, k) -= q * m2.Elem(i, k); + // } + } + } + + if (m2.Symmetric()) + { + for (i = 1; i <= n; i++) + for (j = 1; j < i; j++) + m2.Elem(i, j) = m2.Elem(j, i); + } + */ + } + } + + + void CalcAAt (const DenseMatrix & a, DenseMatrix & m2) + { + int n1 = a.Height(); + int n2 = a.Width(); + int i, j, k; + double sum; + const double *p, *q, *p0; + + if (m2.Height() != n1 || m2.Width() != n1) + { + (*myerr) << "CalcAAt: sizes don't fit" << endl; + return; + } + + for (i = 1; i <= n1; i++) + { + sum = 0; + p = &a.ConstElem(i, 1); + for (k = 1; k <= n2; k++) + { + sum += *p * *p; + p++; + } + m2.Set(i, i, sum); + + p0 = &a.ConstElem(i, 1); + q = a.data; + for (j = 1; j < i; j++) + { + sum = 0; + p = p0; + + for (k = 1; k <= n2; k++) + { + sum += *p * *q; + p++; + q++; + } + m2.Set(i, j, sum); + m2.Set(j, i, sum); + } + } + } + + + + void CalcAtA (const DenseMatrix & a, DenseMatrix & m2) + { + int n1 = a.Height(); + int n2 = a.Width(); + int i, j, k; + double sum; + + if (m2.Height() != n2 || m2.Width() != n2) + { + (*myerr) << "CalcAtA: sizes don't fit" << endl; + return; + } + + for (i = 1; i <= n2; i++) + for (j = 1; j <= n2; j++) + { + sum = 0; + for (k = 1; k <= n1; k++) + sum += a.Get(k, i) * a.Get(k, j); + m2.Elem(i, j) = sum; + } + } + + + + void CalcABt (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2) + { + int n1 = a.Height(); + int n2 = a.Width(); + int n3 = b.Height(); + int i, j, k; + double sum; + + if (m2.Height() != n1 || m2.Width() != n3 || b.Width() != n2) + { + (*myerr) << "CalcABt: sizes don't fit" << endl; + return; + } + + double * pm2 = &m2.Elem(1, 1); + const double * pa1 = &a.Get(1, 1); + + for (i = 1; i <= n1; i++) + { + const double * pb = &b.Get(1, 1); + for (j = 1; j <= n3; j++) + { + sum = 0; + const double * pa = pa1; + + for (k = 1; k <= n2; k++) + { + sum += *pa * *pb; + pa++; pb++; + } + + *pm2 = sum; + pm2++; + } + pa1 += n2; + } + } + + + void CalcAtB (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2) + { + int n1 = a.Height(); + int n2 = a.Width(); + int n3 = b.Width(); + int i, j, k; + + if (m2.Height() != n2 || m2.Width() != n3 || b.Height() != n1) + { + (*myerr) << "CalcAtB: sizes don't fit" << endl; + return; + } + + for (i = 1; i <= n2 * n3; i++) + m2.data[i-1] = 0; + + for (i = 1; i <= n1; i++) + for (j = 1; j <= n2; j++) + { + const double va = a.Get(i, j); + double * pm2 = &m2.Elem(j, 1); + const double * pb = &b.Get(i, 1); + + for (k = 1; k <= n3; ++k, ++pm2, ++pb) + *pm2 += va * *pb; + // for (k = 1; k <= n3; k++) + // m2.Elem(j, k) += va * b.Get(i, k); + } + /* + for (i = 1; i <= n2; i++) + for (j = 1; j <= n3; j++) + { + sum = 0; + for (k = 1; k <= n1; k++) + sum += a.Get(k, i) * b.Get(k, j); + m2.Elem(i, j) = sum; + } + */ + } + + + + + + + + DenseMatrix operator* (const DenseMatrix & m1, const DenseMatrix & m2) + { + DenseMatrix temp (m1.Height(), m2.Width()); + + if (m1.Width() != m2.Height()) + { + (*myerr) << "DenseMatrix :: operator*: Matrix Size does not fit" << endl; + } + else if (temp.Height() != m1.Height()) + { + (*myerr) << "DenseMatrix :: operator*: temp not allocated" << endl; + } + else + { + Mult (m1, m2, temp); + } + return temp; + } + + + void Mult (const DenseMatrix & m1, const DenseMatrix & m2, DenseMatrix & m3) + { + double sum; + double *p1, *p1s, *p1sn, *p1snn, *p2, *p2s, *p2sn, *p3; + + if (m1.Width() != m2.Height() || m1.Height() != m3.Height() || + m2.Width() != m3.Width() ) + { + (*myerr) << "DenseMatrix :: Mult: Matrix Size does not fit" << endl; + (*myerr) << "m1: " << m1.Height() << " x " << m1.Width() << endl; + (*myerr) << "m2: " << m2.Height() << " x " << m2.Width() << endl; + (*myerr) << "m3: " << m3.Height() << " x " << m3.Width() << endl; + return; + } + /* + else if (m1.Symmetric() || m2.Symmetric() || m3.Symmetric()) + { + (*myerr) << "DenseMatrix :: Mult: not implemented for symmetric matrices" << endl; + return; + } + */ + else + { + // int i, j, k; + int n1 = m1.Height(); + int n2 = m2.Width(); + int n3 = m1.Width(); + + /* + for (i = n1 * n2-1; i >= 0; --i) + m3.data[i] = 0; + + const double * pm1 = &m1.Get(1, 1); + for (i = 1; i <= n1; i++) + { + const double * pm2 = &m2.Get(1, 1); + double * pm3i = &m3.Elem(i, 1); + + for (j = 1; j <= n3; j++) + { + const double vm1 = *pm1; + ++pm1; + // const double vm1 = m1.Get(i, j); + double * pm3 = pm3i; + // const double * pm2 = &m2.Get(j, 1); + + for (k = 0; k < n2; k++) + { + *pm3 += vm1 * *pm2; + ++pm2; + ++pm3; + } + + // for (k = 1; k <= n2; k++) + // m3.Elem(i, k) += m1.Get(i, j) * m2.Get(j, k); + } + } + */ + + /* + for (i = 1; i <= n1; i++) + for (j = 1; j <= n2; j++) + { + sum = 0; + for (k = 1; k <= n3; k++) + sum += m1.Get(i, k) * m2.Get(k, j); + m3.Set(i, j, sum); + } + */ + + + /* + for (i = 1; i <= n1; i++) + { + const double pm1i = &m1.Get(i, 1); + const double pm2j = &m2.Get(1, 1); + + for (j = 1; j <= n2; j++) + { + double sum = 0; + const double * pm1 = pm1i; + const double * pm2 = pm2j; + pm2j++; + + for (k = 1; k <= n3; k++) + { + sum += *pm1 * *pm2; + ++pm1; + pm2 += n2; + } + + m3.Set (i, j, sum); + } + } + */ + + + p3 = m3.data; + p1s = m1.data; + p2sn = m2.data + n2; + p1snn = p1s + n1 * n3; + + while (p1s != p1snn) + { + p1sn = p1s + n3; + p2s = m2.data; + + while (p2s != p2sn) + { + sum = 0; + p1 = p1s; + p2 = p2s; + p2s++; + + while (p1 != p1sn) + { + sum += *p1 * *p2; + p1++; + p2 += n2; + } + *p3++ = sum; + } + p1s = p1sn; + } + } + } + + + + DenseMatrix operator+ (const DenseMatrix & m1, const DenseMatrix & m2) + { + DenseMatrix temp (m1.Height(), m1.Width()); + int i, j; + + if (m1.Width() != m2.Width() || m1.Height() != m2.Height()) + { + (*myerr) << "BaseMatrix :: operator+: Matrix Size does not fit" << endl; + } + else if (temp.Height() != m1.Height()) + { + (*myerr) << "BaseMatrix :: operator+: temp not allocated" << endl; + } + else + { + for (i = 1; i <= m1.Height(); i++) + for (j = 1; j <= m1.Width(); j++) + { + temp.Set(i, j, m1.Get(i, j) + m2.Get(i, j)); + } + } + return temp; + } + + + + + void Transpose (const DenseMatrix & m1, DenseMatrix & m2) + { + int w = m1.Width(); + int h = m1.Height(); + int i, j; + + m2.SetSize (w, h); + + double * pm2 = &m2.Elem(1, 1); + for (j = 1; j <= w; j++) + { + const double * pm1 = &m1.Get(1, j); + for (i = 1; i <= h; i++) + { + *pm2 = *pm1; + pm2 ++; + pm1 += w; + } + } + } + + + /* + void DenseMatrix :: Mult (const Vector & v, Vector & prod) const + { + double sum, val; + const double * mp, * sp; + double * dp; + // const Vector & v = bv.CastToVector(); + // Vector & prod = bprod.CastToVector(); + + + int n = Height(); + int m = Width(); + + if (prod.Size() != n) + prod.SetSize (n); + + #ifdef DEVELOP + if (!n) + { + cout << "DenseMatrix::Mult mheight = 0" << endl; + } + if (!m) + { + cout << "DenseMatrix::Mult mwidth = 0" << endl; + } + + if (m != v.Size()) + { + (*myerr) << "\nMatrix and Vector don't fit" << endl; + } + else if (Height() != prod.Size()) + { + (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; + } + else + #endif + { + if (Symmetric()) + { + int i, j; + + + for (i = 1; i <= n; i++) + { + sp = &v.Get(1); + dp = &prod.Elem(1); + mp = &Get(i, 1); + + val = v.Get(i); + sum = Get(i, i) * val; + + for (j = 1; j < i; ++j, ++mp, ++sp, ++dp) + { + sum += *mp * *sp; + *dp += val * *mp; + } + + prod.Elem(i) = sum; + } + } + else + { + mp = data; + dp = &prod.Elem(1); + for (int i = 1; i <= n; i++) + { + sum = 0; + sp = &v.Get(1); + + for (int j = 1; j <= m; j++) + { + // sum += Get(i,j) * v.Get(j); + sum += *mp * *sp; + mp++; + sp++; + } + + // prod.Set (i, sum); + *dp = sum; + dp++; + } + } + } + } + */ + + void DenseMatrix :: MultTrans (const Vector & v, Vector & prod) const + { + // const Vector & v = (const Vector&)bv; // .CastToVector(); + // Vector & prod = (Vector & )bprod; // .CastToVector(); + + /* + if (Height() != v.Size()) + { + (*myerr) << "\nMatrix and Vector don't fit" << endl; + } + else if (Width() != prod.Size()) + { + (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; + } + else + */ + { + int i, j; + int w = Width(), h = Height(); + if (prod.Size() != w) + prod.SetSize (w); + + const double * pmat = &Get(1, 1); + const double * pv = &v(0); + + prod = 0; + + for (i = 1; i <= h; i++) + { + double val = *pv; + ++pv; + + double * pprod = &prod(0); + + for (j = w-1; j >= 0; --j, ++pmat, ++pprod) + { + *pprod += val * *pmat; + } + } + + /* + double sum; + + for (i = 1; i <= Width(); i++) + { + sum = 0; + + for (int j = 1; j <= Height(); j++) + sum += Get(j, i) * v.Get(j); + + prod.Set (i, sum); + } + */ + } + } + + + void DenseMatrix :: Residuum (const Vector & x, const Vector & b, + Vector & res) const + { + double sum; + // const Vector & x = bx.CastToVector(); + // const Vector & b = bb.CastToVector(); + // Vector & res = bres.CastToVector(); + + res.SetSize (Height()); + + if (Width() != x.Size() || Height() != b.Size()) + { + (*myerr) << "\nMatrix and Vector don't fit" << endl; + } + else if (Height() != res.Size()) + { + (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; + } + else + { + int h = Height(); + int w = Width(); + const double * mp = &Get(1, 1); + + for (int i = 1; i <= h; i++) + { + sum = b(i-1); + const double * xp = &x(0); + + for (int j = 1; j <= w; ++j, ++mp, ++xp) + sum -= *mp * *xp; + + res(i-1) = sum; + } + } + } + +#ifdef ABC + double DenseMatrix :: EvaluateBilinearform (const Vector & hx) const + { + double sum = 0, hsum; + // const Vector & hx = x.CastToVector(); + int i, j; + + if (Width() != hx.Size() || Height() != hx.Size()) + { + (*myerr) << "Matrix::EvaluateBilinearForm: sizes don't fit" << endl; + } + else + { + for (i = 1; i <= Height(); i++) + { + hsum = 0; + for (j = 1; j <= Height(); j++) + { + hsum += Get(i, j) * hx.Get(j); + } + sum += hsum * hx.Get(i); + } + } + + // testout << "sum = " << sum << endl; + return sum; + } + + + void DenseMatrix :: MultElementMatrix (const Array & pnum, + const Vector & hx, Vector & hy) + { + int i, j; + // const Vector & hx = x.CastToVector(); + // Vector & hy = y.CastToVector(); + + if (Symmetric()) + { + for (i = 1; i <= Height(); i++) + { + for (j = 1; j < i; j++) + { + hy.Elem(pnum.Get(i)) += Get(i, j) * hx.Get(pnum.Get(j)); + hy.Elem(pnum.Get(j)) += Get(i, j) * hx.Get(pnum.Get(i)); + } + hy.Elem(pnum.Get(j)) += Get(i, i) * hx.Get(pnum.Get(i)); + } + } + else + for (i = 1; i <= Height(); i++) + for (j = 1; j <= Width(); j++) + hy.Elem(pnum.Get(i)) += Get(i, j) * hx.Get(pnum.Get(j)); + + } + + void DenseMatrix :: MultTransElementMatrix (const Array & pnum, + const Vector & hx, Vector & hy) + { + int i, j; + // const Vector & hx = x.CastToVector(); + // Vector & hy = y.CastToVector(); + + if (Symmetric()) + MultElementMatrix (pnum, hx, hy); + else + for (i = 1; i <= Height(); i++) + for (j = 1; j <= Width(); j++) + hy.Elem(pnum.Get(i)) += Get(j, i) * hx.Get(pnum.Get(j)); + } +#endif + + + void DenseMatrix :: Solve (const Vector & v, Vector & sol) const + { + DenseMatrix temp (*this); + temp.SolveDestroy (v, sol); + } + + + void DenseMatrix :: SolveDestroy (const Vector & v, Vector & sol) + { + double q; + + if (Width() != Height()) + { + (*myerr) << "SolveDestroy: Matrix not square"; + return; + } + if (Width() != v.Size()) + { + (*myerr) << "SolveDestroy: Matrix and Vector don't fit"; + return; + } + + sol = v; + if (Height() != sol.Size()) + { + (*myerr) << "SolveDestroy: Solution Vector not ok"; + return; + } + + + if (0 /* Symmetric() */) + { + + // Cholesky factorization + + int i, j, k, n; + n = Height(); + + // Cholesky + + double x; + Vector p(n); + + for (i = 1; i <= n; i++) + for (j = 1; j < i; j++) + Elem(j, i) = Get(i, j); + + for (i = 1; i <= n; i++) + { + // (*mycout) << "." << flush; + for (j = i; j <= n; j++) + { + x = Get(i, j); + + const double * pik = &Get(i, 1); + const double * pjk = &Get(j, 1); + + for (k = i-2; k >= 0; --k, ++pik, ++pjk) + x -= (*pik) * (*pjk); + + // for (k = i-1; k >= 1; --k) + // x -= Get(j, k) * Get(i, k); + + if (i == j) + { + if (x <= 0) + { + cerr << "Matrix indefinite" << endl; + return; + } + + p(i-1) = 1 / sqrt(x); + } + else + { + Elem(j, i) = x * p(i-1); + } + } + } + + for (int i = 1; i <= n; i++) + Elem(i, i) = 1 / p(i-1); + + // A = L L^t + // L stored in left-lower triangle + + + sol = v; + + // Solve L sol = sol + + for (int i = 1; i <= n; i++) + { + double val = sol(i-1); + + const double * pij = &Get(i, 1); + const double * solj = &sol(0); + + for (int j = 1; j < i; j++, ++pij, ++solj) + val -= *pij * *solj; + // for (j = 1; j < i; j++) + // val -= Get(i, j) * sol.Get(j); + + sol(i-1) = val / Get(i, i); + } + + // Solve L^t sol = sol + + for (int i = n; i >= 1; i--) + { + double val = sol(i-1) / Get(i, i); + sol(i-1) = val; + + double * solj = &sol(0); + const double * pij = &Get(i, 1); + + for (j = 1; j < i; ++j, ++pij, ++solj) + *solj -= val * *pij; + // for (j = 1; j < i; j++) + // sol.Elem(j) -= Get(i, j) * val; + } + + + } + else + { + // (*mycout) << "gauss" << endl; + int n = Height(); + for (int i = 1; i <= n; i++) + { + for (int j = i+1; j <= n; j++) + { + q = Get(j,i) / Get(i,i); + if (q) + { + const double * pik = &Get(i, i+1); + double * pjk = &Elem(j, i+1); + + for (int k = i+1; k <= n; ++k, ++pik, ++pjk) + *pjk -= q * *pik; + + // for (k = i+1; k <= Height(); k++) + // Elem(j, k) -= q * Get(i,k); + + + sol(j-1) -= q * sol(i-1); + } + } + } + + for (int i = n; i >= 1; i--) + { + q = sol(i-1); + for (int j = i+1; j <= n; j++) + q -= Get(i,j) * sol(j-1); + + sol(i-1) = q / Get(i,i); + } + } + } + + + /* + BaseMatrix * DenseMatrix :: Copy () const + { + return new DenseMatrix (*this); + } + */ + + + + + ostream & operator<< (ostream & ost, const DenseMatrix & m) + { + for (int i = 0; i < m.Height(); i++) + { + for (int j = 0; j < m.Width(); j++) + ost << m.Get(i+1,j+1) << " "; + ost << endl; + } + return ost; + } + + + +} diff --git a/libsrc/linalg/densemat.hpp b/libsrc/linalg/densemat.hpp new file mode 100644 index 00000000..5d721b5a --- /dev/null +++ b/libsrc/linalg/densemat.hpp @@ -0,0 +1,277 @@ +#ifndef FILE_DENSEMAT +#define FILE_DENSEMAT + +/**************************************************************************/ +/* File: densemat.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Oct. 94 */ +/**************************************************************************/ + +/** + Data type dense matrix +*/ + + +class DenseMatrix +{ +protected: + int height; + int width; + double * data; + +public: + /// + DLL_HEADER DenseMatrix (); + /// + DLL_HEADER DenseMatrix (int h, int w = 0); + /// + DLL_HEADER DenseMatrix (const DenseMatrix & m2); + /// + DLL_HEADER ~DenseMatrix (); + + /// + DLL_HEADER void SetSize (int h, int w = 0); + + int Height() const { return height; } + int Width() const {return width; } + + double & operator() (int i, int j) { return data[i*width+j]; } + double operator() (int i, int j) const { return data[i*width+j]; } + double & operator() (int i) { return data[i]; } + double operator() (int i) const { return data[i]; } + + /// + DLL_HEADER DenseMatrix & operator= (const DenseMatrix & m2); + /// + DLL_HEADER DenseMatrix & operator+= (const DenseMatrix & m2); + /// + DLL_HEADER DenseMatrix & operator-= (const DenseMatrix & m2); + + /// + DLL_HEADER DenseMatrix & operator= (double v); + /// + DLL_HEADER DenseMatrix & operator*= (double v); + + /// + DLL_HEADER void Mult (const FlatVector & v, FlatVector & prod) const + { + double sum; + const double * mp, * sp; + double * dp; + +#ifdef DEBUG + if (prod.Size() != height) + { + (*myerr) << "Mult: wrong vector size " << endl; + } + if (!height) + { + cout << "DenseMatrix::Mult height = 0" << endl; + } + if (!width) + { + cout << "DenseMatrix::Mult width = 0" << endl; + } + + if (width != v.Size()) + { + (*myerr) << "\nMatrix and Vector don't fit" << endl; + } + else if (Height() != prod.Size()) + { + (*myerr) << "Base_Matrix::operator*(Vector): prod vector not ok" << endl; + } + else +#endif + { + mp = data; + dp = &prod(0); + for (int i = 0; i < height; i++) + { + sum = 0; + sp = &v(0); + + for (int j = 0; j < width; j++) + { + // sum += Get(i,j) * v.Get(j); + sum += *mp * *sp; + mp++; + sp++; + } + + *dp = sum; + dp++; + } + } + } + + /// + DLL_HEADER void MultTrans (const Vector & v, Vector & prod) const; + /// + DLL_HEADER void Residuum (const Vector & x, const Vector & b, Vector & res) const; + /// + DLL_HEADER double Det () const; + + /// + friend DenseMatrix operator* (const DenseMatrix & m1, const DenseMatrix & m2); + /// + friend DenseMatrix operator+ (const DenseMatrix & m1, const DenseMatrix & m2); + + /// + friend void Transpose (const DenseMatrix & m1, DenseMatrix & m2); + /// + friend void Mult (const DenseMatrix & m1, const DenseMatrix & m2, DenseMatrix & m3); + /// +// friend void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2); + /// + friend void CalcAAt (const DenseMatrix & a, DenseMatrix & m2); + /// +// friend void CalcAtA (const DenseMatrix & a, DenseMatrix & m2); + /// + friend void CalcABt (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2); + /// + friend void CalcAtB (const DenseMatrix & a, const DenseMatrix & b, DenseMatrix & m2); + /// + DLL_HEADER void Solve (const Vector & b, Vector & x) const; + /// + void SolveDestroy (const Vector & b, Vector & x); + /// + const double & Get(int i, int j) const { return data[(i-1)*width+j-1]; } + /// + const double & Get(int i) const { return data[i-1]; } + /// + void Set(int i, int j, double v) { data[(i-1)*width+j-1] = v; } + /// + double & Elem(int i, int j) { return data[(i-1)*width+j-1]; } + /// + const double & ConstElem(int i, int j) const { return data[(i-1)*width+j-1]; } +}; + + +extern ostream & operator<< (ostream & ost, const DenseMatrix & m); + + + +template +class MatrixFixWidth +{ +protected: + int height; + double * data; + +public: + /// + MatrixFixWidth () + { height = 0; data = 0; } + /// + MatrixFixWidth (int h) + { height = h; data = new double[WIDTH*height]; } + /// + ~MatrixFixWidth () + { delete [] data; } + + void SetSize (int h) + { + if (h != height) + { + delete data; + height = h; + data = new double[WIDTH*height]; + } + } + + /// + int Height() const { return height; } + + /// + int Width() const { return WIDTH; } + + /// + MatrixFixWidth & operator= (double v) + { + for (int i = 0; i < height*WIDTH; i++) + data[i] = v; + return *this; + } + + /// + void Mult (const FlatVector & v, FlatVector & prod) const + { + double sum; + const double * mp, * sp; + double * dp; + + /* + if (prod.Size() != height) + { + cerr << "MatrixFixWidth::Mult: wrong vector size " << endl; + assert (1); + } + */ + + mp = data; + dp = &prod[0]; + for (int i = 0; i < height; i++) + { + sum = 0; + sp = &v[0]; + + for (int j = 0; j < WIDTH; j++) + { + sum += *mp * *sp; + mp++; + sp++; + } + + *dp = sum; + dp++; + } + } + + double & operator() (int i, int j) + { return data[i*WIDTH+j]; } + + const double & operator() (int i, int j) const + { return data[i*WIDTH+j]; } + + + MatrixFixWidth & operator*= (double v) + { + if (data) + for (int i = 0; i < height*WIDTH; i++) + data[i] *= v; + return *this; + } + + + + const double & Get(int i, int j) const { return data[(i-1)*WIDTH+j-1]; } + /// + const double & Get(int i) const { return data[i-1]; } + /// + void Set(int i, int j, double v) { data[(i-1)*WIDTH+j-1] = v; } + /// + double & Elem(int i, int j) { return data[(i-1)*WIDTH+j-1]; } + /// + const double & ConstElem(int i, int j) const { return data[(i-1)*WIDTH+j-1]; } +}; + + +template +extern ostream & operator<< (ostream & ost, const MatrixFixWidth & m) +{ + for (int i = 0; i < m.Height(); i++) + { + for (int j = 0; j < m.Width(); j++) + ost << m.Get(i+1,j+1) << " "; + ost << endl; + } + return ost; +}; + + +extern DLL_HEADER void CalcAtA (const DenseMatrix & a, DenseMatrix & m2); +extern DLL_HEADER void CalcInverse (const DenseMatrix & m1, DenseMatrix & m2); + + +#endif diff --git a/libsrc/linalg/linalg.hpp b/libsrc/linalg/linalg.hpp new file mode 100644 index 00000000..95d0c823 --- /dev/null +++ b/libsrc/linalg/linalg.hpp @@ -0,0 +1,32 @@ +#ifndef FILE_LINALG +#define FILE_LINALG + +/* *************************************************************************/ +/* File: linalg.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Oct. 94 */ +/* *************************************************************************/ + +/* + + Data types for basic linear algebra + + The basic concepts include the data types + + Vector + SparseMatrix + DenseMatrix + +*/ + + +#include "../include/myadt.hpp" +namespace netgen +{ +#include "vector.hpp" +#include "densemat.hpp" +#include "polynomial.hpp" +} +#endif + + diff --git a/libsrc/linalg/linopt.cpp b/libsrc/linalg/linopt.cpp new file mode 100644 index 00000000..dc5b53fa --- /dev/null +++ b/libsrc/linalg/linopt.cpp @@ -0,0 +1,73 @@ +#include +#include + +#include +#include "opti.hpp" + +namespace netgen +{ + +void LinearOptimize (const DenseMatrix & a, const Vector & b, + const Vector & c, Vector & x) + + { + int i1, i2, i3, j; + DenseMatrix m(3), inv(3); + Vector rs(3), hx(3), res(a.Height()), res2(3); + double f, fmin; + int nrest; + + if (a.Width() != 3) + { + cerr << "LinearOptimize only implemented for 3 unknowns" << endl; + return; + } + + fmin = 1e10; + x = 0; + nrest = a.Height(); + for (i1 = 1; i1 <= nrest; i1++) + for (i2 = i1 + 1; i2 <= nrest; i2++) + for (i3 = i2 + 1; i3 <= nrest; i3++) + { + for (j = 1; j <= 3; j++) + { + m.Elem(1, j) = a.Get(i1, j); + m.Elem(2, j) = a.Get(i2, j); + m.Elem(3, j) = a.Get(i3, j); + } + + rs(0) = b(i1-1); + rs(1) = b(i2-1); + rs(2) = b(i3-1); + + if (fabs (m.Det()) < 1e-12) continue; + + CalcInverse (m, inv); + inv.Mult (rs, hx); + + a.Residuum (hx, b, res); +// m.Residuum (hx, rs, res2); + f = c * hx; + +/* + testout -> precision(12); + (*testout) << "i = (" << i1 << "," << i2 << "," << i3 + << "), f = " << f << " x = " << x << " res = " << res + << " resmin = " << res.Min() + << " res2 = " << res2 << " prod = " << prod << endl; +*/ + + + double rmin = res(0); + for (int hi = 1; hi < res.Size(); hi++) + if (res(hi) < rmin) rmin = res(hi); + + if ( (f < fmin) && rmin >= -1e-8) + { + fmin = f; + x = hx; + } + } + } +} diff --git a/libsrc/linalg/linsearch.cpp b/libsrc/linalg/linsearch.cpp new file mode 100644 index 00000000..c0c37c94 --- /dev/null +++ b/libsrc/linalg/linsearch.cpp @@ -0,0 +1,350 @@ +/***************************************************************************/ +/* */ +/* Problem: Liniensuche */ +/* */ +/* Programmautor: Joachim Schöberl */ +/* Matrikelnummer: 9155284 */ +/* */ +/* Algorithmus nach: */ +/* */ +/* Optimierung I, Gfrerer, WS94/95 */ +/* Algorithmus 2.1: Liniensuche Problem (ii) */ +/* */ +/***************************************************************************/ + + + +#include + +#include // min, max, sqr + +#include +#include "opti.hpp" + + +namespace netgen +{ +const double eps0 = 1E-15; + +// Liniensuche + + +double MinFunction :: Func (const Vector & /* x */) const +{ + cerr << "Func of MinFunction called" << endl; + return 0; +} + +void MinFunction :: Grad (const Vector & /* x */, Vector & /* g */) const +{ + cerr << "Grad of MinFunction called" << endl; +} + +double MinFunction :: FuncGrad (const Vector & x, Vector & g) const +{ + cerr << "Grad of MinFunction called" << endl; + return 0; + /* + int n = x.Size(); + + Vector xr(n); + Vector xl(n); + + double eps = 1e-6; + double fl, fr; + + for (int i = 1; i <= n; i++) + { + xr.Set (1, x); + xl.Set (1, x); + + xr.Elem(i) += eps; + fr = Func (xr); + + xl.Elem(i) -= eps; + fl = Func (xl); + + g.Elem(i) = (fr - fl) / (2 * eps); + } + + double f = Func(x); + // (*testout) << "f = " << f << " grad = " << g << endl; + return f; + */ +} + + +double MinFunction :: FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const +{ + Vector g(x.Size()); + double f = FuncGrad (x, g); + deriv = (g * dir); + + // (*testout) << "g = " << g << ", dir = " << dir << ", deriv = " << deriv << endl; + return f; +} + +void MinFunction :: ApproximateHesse (const Vector & x, + DenseMatrix & hesse) const +{ + int n = x.Size(); + int i, j; + + static Vector hx; + hx.SetSize(n); + + double eps = 1e-6; + double f, f11, f12, f21, f22; + + for (i = 0; i < n; i++) + { + for (j = 0; j < i; j++) + { + hx = x; + hx(i) = x(i) + eps; + hx(j) = x(j) + eps; + f11 = Func(hx); + hx(i) = x(i) + eps; + hx(j) = x(j) - eps; + f12 = Func(hx); + hx(i) = x(i) - eps; + hx(j) = x(j) + eps; + f21 = Func(hx); + hx(i) = x(i) - eps; + hx(j) = x(j) - eps; + f22 = Func(hx); + + hesse(i, j) = hesse(j, i) = + (f11 + f22 - f12 - f21) / (2 * eps * eps); + } + + hx = x; + f = Func(x); + hx(i) = x(i) + eps; + f11 = Func(hx); + hx(i) = x(i) - eps; + f22 = Func(hx); + + hesse(i, i) = (f11 + f22 - 2 * f) / (eps * eps); + } + // (*testout) << "hesse = " << hesse << endl; +} + + + + + + + +/// Line search, modified Mangasarien conditions +void lines (Vector & x, // i: initial point of line-search + Vector & xneu, // o: solution, if successful + Vector & p, // i: search direction + double & f, // i: function-value at x + // o: function-value at xneu, iff ifail = 0 + Vector & g, // i: gradient at x + // o: gradient at xneu, iff ifail = 0 + const MinFunction & fun, // function to minimize + const OptiParameters & par, + double & alphahat, // i: initial value for alpha_hat + // o: solution alpha iff ifail = 0 + double fmin, // i: lower bound for f + double mu1, // i: Parameter mu_1 of Alg.2.1 + double sigma, // i: Parameter sigma of Alg.2.1 + double xi1, // i: Parameter xi_1 of Alg.2.1 + double xi2, // i: Parameter xi_1 of Alg.2.1 + double tau, // i: Parameter tau of Alg.2.1 + double tau1, // i: Parameter tau_1 of Alg.2.1 + double tau2, // i: Parameter tau_2 of Alg.2.1 + int & ifail) // o: 0 on success + // -1 bei termination because lower limit fmin + // 1 bei illegal termination due to different reasons + +{ + double phi0, phi0prime, phi1, phi1prime, phihatprime; + double alpha1, alpha2, alphaincr, c; + char flag = 1; + long it; + + alpha1 = 0; + alpha2 = 1e50; + phi0 = phi1 = f; + + phi0prime = g * p; + + if (phi0prime > 0) + { + ifail = 1; + return; + } + + ifail = 1; // Markus + + phi1prime = phi0prime; + + // (*testout) << "phi0prime = " << phi0prime << endl; + + // it = 100000l; + it = 0; + + // cout << "lin: "; + while (it++ <= par.maxit_linsearch) + { + // cout << "i = " << it << " f = " << f << " "; + xneu.Set2 (1, x, alphahat, p); + + + // f = fun.FuncGrad (xneu, g); + // f = fun.Func (xneu); + f = fun.FuncDeriv (xneu, p, phihatprime); + + // (*testout) << "lines, f = " << f << " phip = " << phihatprime << endl; + + if (f < fmin) + { + ifail = -1; + break; + } + + + if (alpha2 - alpha1 < eps0 * alpha2) + { + ifail = 0; + break; + } + + // (*testout) << "i = " << it << " al = " << alphahat << " f = " << f << " fprime " << phihatprime << endl;; + + if (f - phi0 > mu1 * alphahat * phi1prime + eps0 * fabs (phi0)) + + { + + flag = 0; + alpha2 = alphahat; + + c = + (f - phi1 - phi1prime * (alphahat-alpha1)) / + sqr (alphahat-alpha1); + + alphahat = alpha1 - 0.5 * phi1prime / c; + + if (alphahat > alpha2) + alphahat = alpha1 + 1/(4*c) * + ( (sigma+mu1) * phi0prime - 2*phi1prime + + sqrt (sqr(phi1prime - mu1 * phi0prime) - + 4 * (phi1 - phi0 - mu1 * alpha1 * phi0prime) * c)); + + alphahat = max2 (alphahat, alpha1 + tau * (alpha2 - alpha1)); + alphahat = min2 (alphahat, alpha2 - tau * (alpha2 - alpha1)); + + // (*testout) << " if-branch" << endl; + + } + + else + + { + /* + f = fun.FuncGrad (xneu, g); + phihatprime = g * p; + */ + f = fun.FuncDeriv (xneu, p, phihatprime); + + if (phihatprime < sigma * phi0prime * (1 + eps0)) + + { + if (phi1prime < phihatprime) + // Approximationsfunktion ist konvex + + alphaincr = (alphahat - alpha1) * phihatprime / + (phi1prime - phihatprime); + + else + alphaincr = 1e99; // MAXDOUBLE; + + if (flag) + { + alphaincr = max2 (alphaincr, xi1 * (alphahat-alpha1)); + alphaincr = min2 (alphaincr, xi2 * (alphahat-alpha1)); + } + else + { + alphaincr = max2 (alphaincr, tau1 * (alpha2 - alphahat)); + alphaincr = min2 (alphaincr, tau2 * (alpha2 - alphahat)); + } + + alpha1 = alphahat; + alphahat += alphaincr; + phi1 = f; + phi1prime = phihatprime; + } + + else + + { + ifail = 0; // Erfolg !! + break; + } + + // (*testout) << " else, " << endl; + + } + + } + + // (*testout) << "linsearch: it = " << it << " ifail = " << ifail << endl; + // cout << endl; + fun.FuncGrad (xneu, g); + + + if (it < 0) + ifail = 1; + + // (*testout) << "fail = " << ifail << endl; +} + + + + + + + + + + + + + + + + + + + +void SteepestDescent (Vector & x, const MinFunction & fun, + const OptiParameters & par) +{ + int it, n = x.Size(); + Vector xnew(n), p(n), g(n), g2(n); + double val, alphahat; + int fail; + + val = fun.FuncGrad(x, g); + + alphahat = 1; + // testout << "f = "; + for (it = 0; it < 10; it++) + { + // testout << val << " "; + + // p = -g; + p.Set (-1, g); + + lines (x, xnew, p, val, g, fun, par, alphahat, -1e5, + 0.1, 0.1, 1, 10, 0.1, 0.1, 0.6, fail); + + x = xnew; + } + // testout << endl; +} +} diff --git a/libsrc/linalg/opti.hpp b/libsrc/linalg/opti.hpp new file mode 100644 index 00000000..98757869 --- /dev/null +++ b/libsrc/linalg/opti.hpp @@ -0,0 +1,142 @@ +#ifndef FILE_OPTI +#define FILE_OPTI + +/**************************************************************************/ +/* File: opti.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Jun. 95 */ +/**************************************************************************/ + + + +namespace netgen +{ + + /** + Function to be minimized. + */ + class MinFunction + { + public: + /// + virtual double Func (const Vector & x) const; + /// + virtual void Grad (const Vector & x, Vector & g) const; + /// function and gradient + virtual double FuncGrad (const Vector & x, Vector & g) const; + /// directional derivative + virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; + /// if |g| < gradaccuray, then stop bfgs + virtual double GradStopping (const Vector & /* x */) const { return 0; } + + /// + virtual void ApproximateHesse (const Vector & /* x */, + DenseMatrix & /* hesse */) const; + }; + + + class OptiParameters + { + public: + int maxit_linsearch; + int maxit_bfgs; + double typf; + double typx; + + OptiParameters () + { + maxit_linsearch = 100; + maxit_bfgs = 100; + typf = 1; + typx = 1; + } + }; + + + /** Implementation of BFGS method. + Efficient method for non-linear minimiztion problems. + @param x initial value and solution + @param fun function to be minimized + */ + extern double BFGS (Vector & x, const MinFunction & fun, + const OptiParameters & par, + double eps = 1e-8); + + /** Steepest descent method. + Simple method for non-linear minimization problems. + @param x initial value and solution + @param fun function to be minimized + */ + void SteepestDescent (Vector & x, const MinFunction & fun, + const OptiParameters & par); + + + extern void lines ( + Vector & x, // i: Ausgangspunkt der Liniensuche + Vector & xneu, // o: Loesung der Liniensuche bei Erfolg + Vector & p, // i: Suchrichtung + double & f, // i: Funktionswert an der Stelle x + // o: Funktionswert an der Stelle xneu, falls ifail = 0 + Vector & g, // i: Gradient an der Stelle x + // o: Gradient an der Stelle xneu, falls ifail = 0 + + const MinFunction & fun, // function to minmize + const OptiParameters & par, // parameters + double & alphahat, // i: Startwert für alpha_hat + // o: Loesung falls ifail = 0 + double fmin, // i: untere Schranke für f + double mu1, // i: Parameter mu_1 aus Alg.2.1 + double sigma, // i: Parameter sigma aus Alg.2.1 + double xi1, // i: Parameter xi_1 aus Alg.2.1 + double xi2, // i: Parameter xi_1 aus Alg.2.1 + double tau, // i: Parameter tau aus Alg.2.1 + double tau1, // i: Parameter tau_1 aus Alg.2.1 + double tau2, // i: Parameter tau_2 aus Alg.2.1 + int & ifail); // o: 0 bei erfolgreicher Liniensuche + // -1 bei Abbruch wegen Unterschreiten von fmin + // 1 bei Abbruch, aus sonstigen Gründen + + + + + /** + Solver for linear programming problem. + + \begin{verbatim} + min c^t x + A x <= b + \end{verbatim} + */ + extern void LinearOptimize (const DenseMatrix & a, const Vector & b, + const Vector & c, Vector & x); + + +#ifdef NONE + + /** + Simple projection iteration. + + find $u = argmin_{v >= 0} 0.5 u A u - f u$ + */ + extern void ApproxProject (const BaseMatrix & a, Vector & u, + const Vector & f, + double tau, int its); + + + /** + CG Algorithm for quadratic programming problem. + See: Dostal ... + + d ... diag(A) ^{-1} + */ + extern void ApproxProjectCG (const BaseMatrix & a, Vector & x, + const Vector & b, const class DiagMatrix & d, + double gamma, int & steps, int & changes); + +#endif + + +} + +#endif + diff --git a/libsrc/linalg/polynomial.cpp b/libsrc/linalg/polynomial.cpp new file mode 100644 index 00000000..cc515aac --- /dev/null +++ b/libsrc/linalg/polynomial.cpp @@ -0,0 +1,198 @@ +#include +#include + +namespace netgen +{ + +QuadraticPolynomial1V :: +QuadraticPolynomial1V (double ac, double acx, double acxx) +{ + c = ac; + cx = acx; + cxx = acxx; +} + +double QuadraticPolynomial1V :: +Value (double x) +{ + return c + cx * x + cxx * x * x; +} + +double QuadraticPolynomial1V :: MaxUnitInterval () +{ + // inner max + if (cxx < 0 && cx > 0 && cx < -2 * cxx) + { + return c - 0.25 * cx * cx / cxx; + } + + + if (cx + cxx > 0) // right edge + return c + cx + cxx; + + // left end + return c; +} + + + + +LinearPolynomial2V :: +LinearPolynomial2V (double ac, double acx, double acy) +{ + c = ac; + cx = acx; + cy = acy; +}; + + +QuadraticPolynomial2V :: +QuadraticPolynomial2V () +{ + ; +} + + +QuadraticPolynomial2V :: +QuadraticPolynomial2V (double ac, double acx, double acy, + double acxx, double acxy, double acyy) +{ + c = ac; + cx = acx; + cy = acy; + cxx = acxx; + cxy = acxy; + cyy = acyy; +} + +void QuadraticPolynomial2V :: +Square (const LinearPolynomial2V & lp) +{ + c = lp.c * lp.c; + cx = 2 * lp.c * lp.cx; + cy = 2 * lp.c * lp.cy; + + cxx = lp.cx * lp.cx; + cxy = 2 * lp.cx * lp.cy; + cyy = lp.cy * lp.cy; +} + +void QuadraticPolynomial2V :: +Add (double lam, const QuadraticPolynomial2V & qp2) +{ + c += lam * qp2.c; + cx += lam * qp2.cx; + cy += lam * qp2.cy; + cxx += lam * qp2.cxx; + cxy += lam * qp2.cxy; + cyy += lam * qp2.cyy; +} + +double QuadraticPolynomial2V :: +Value (double x, double y) +{ + return c + cx * x + cy * y + cxx * x * x + cxy * x * y + cyy * y * y; +} + +/* +double QuadraticPolynomial2V :: +MinUnitSquare () +{ + double x, y; + double minv = 1e8; + double val; + for (x = 0; x <= 1; x += 0.1) + for (y = 0; y <= 1; y += 0.1) + { + val = Value (x, y); + if (val < minv) + minv = val; + } + return minv; +}; +*/ + +double QuadraticPolynomial2V :: +MaxUnitSquare () +{ + // find critical point + + double maxv = c; + double hv; + + double det, x0, y0; + det = 4 * cxx * cyy - cxy * cxy; + + if (det > 0) + { + // definite surface + + x0 = (-2 * cyy * cx + cxy * cy) / det; + y0 = (cxy * cx -2 * cxx * cy) / det; + + if (x0 >= 0 && x0 <= 1 && y0 >= 0 && y0 <= 1) + { + hv = Value (x0, y0); + if (hv > maxv) maxv = hv; + } + } + + QuadraticPolynomial1V e1(c, cx, cxx); + QuadraticPolynomial1V e2(c, cy, cyy); + QuadraticPolynomial1V e3(c+cy+cyy, cx+cxy, cxx); + QuadraticPolynomial1V e4(c+cx+cxx, cy+cxy, cyy); + + hv = e1.MaxUnitInterval(); + if (hv > maxv) maxv = hv; + hv = e2.MaxUnitInterval(); + if (hv > maxv) maxv = hv; + hv = e3.MaxUnitInterval(); + if (hv > maxv) maxv = hv; + hv = e4.MaxUnitInterval(); + if (hv > maxv) maxv = hv; + + return maxv; +}; + + + + +double QuadraticPolynomial2V :: +MaxUnitTriangle () +{ + // find critical point + + double maxv = c; + double hv; + + double det, x0, y0; + det = 4 * cxx * cyy - cxy * cxy; + + if (cxx < 0 && det > 0) + { + // definite surface + + x0 = (-2 * cyy * cx + cxy * cy) / det; + y0 = (cxy * cx -2 * cxx * cy) / det; + + if (x0 >= 0 && y0 >= 0 && x0+y0 <= 1) + { + return Value (x0, y0); + } + } + + + QuadraticPolynomial1V e1(c, cx, cxx); + QuadraticPolynomial1V e2(c, cy, cyy); + QuadraticPolynomial1V e3(c+cy+cyy, cx-cy+cxy-2*cyy, cxx-cxy+cyy); + + hv = e1.MaxUnitInterval(); + if (hv > maxv) maxv = hv; + hv = e2.MaxUnitInterval(); + if (hv > maxv) maxv = hv; + hv = e3.MaxUnitInterval(); + if (hv > maxv) maxv = hv; + + return maxv; +} +} diff --git a/libsrc/linalg/polynomial.hpp b/libsrc/linalg/polynomial.hpp new file mode 100644 index 00000000..3108d4dd --- /dev/null +++ b/libsrc/linalg/polynomial.hpp @@ -0,0 +1,45 @@ +#ifndef FILE_POLYNOMIAL +#define FILE_POLYNOMIAL + +/* *************************************************************************/ +/* File: polynomial.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 25. Nov. 99 */ +/* *************************************************************************/ + + +class QuadraticPolynomial1V +{ + double c, cx, cxx; +public: + QuadraticPolynomial1V (double ac, double acx, double acxx); + double Value (double x); + double MaxUnitInterval (); +}; + +class LinearPolynomial2V +{ + double c, cx, cy; +public: + LinearPolynomial2V (double ac, double acx, double acy); + friend class QuadraticPolynomial2V; +}; + + +class QuadraticPolynomial2V +{ + double c, cx, cy, cxx, cxy, cyy; +public: + QuadraticPolynomial2V (); + QuadraticPolynomial2V (double ac, double acx, double acy, + double acxx, double acxy, double acyy); + void Square (const LinearPolynomial2V & lp); + void Add (double lam, const QuadraticPolynomial2V & qp); + + double Value (double x, double y); + // double MinUnitSquare (); + double MaxUnitSquare (); + double MaxUnitTriangle (); +}; + +#endif diff --git a/libsrc/linalg/vector.hpp b/libsrc/linalg/vector.hpp new file mode 100644 index 00000000..e7c52e81 --- /dev/null +++ b/libsrc/linalg/vector.hpp @@ -0,0 +1,161 @@ +#ifndef FILE_VECTOR +#define FILE_VECTOR + +/* *************************************************************************/ +/* File: vector.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Oct. 94 */ +/* *************************************************************************/ + + +class FlatVector +{ +protected: + int s; + double *data; +public: + FlatVector () { ; } + FlatVector (int as, double * adata) + { s = as; data = adata; } + + int Size () const + { return s; } + + FlatVector & operator= (const FlatVector & v) + { memcpy (data, v.data, s*sizeof(double)); return *this; } + + FlatVector & operator= (double scal) + { + for (int i = 0; i < s; i++) data[i] = scal; + return *this; + } + + double & operator[] (int i) { return data[i]; } + const double & operator[] (int i) const { return data[i]; } + double & operator() (int i) { return data[i]; } + const double & operator() (int i) const { return data[i]; } + + // double & Elem (int i) { return data[i-1]; } + // const double & Get (int i) const { return data[i-1]; } + // void Set (int i, double val) { data[i-1] = val; } + + FlatVector & operator*= (double scal) + { + for (int i = 0; i < s; i++) data[i] *= scal; + return *this; + } + + FlatVector & Add (double scal, const FlatVector & v2) + { + for (int i = 0; i < s; i++) + data[i] += scal * v2[i]; + return *this; + } + + FlatVector & Set (double scal, const FlatVector & v2) + { + for (int i = 0; i < s; i++) + data[i] = scal * v2[i]; + return *this; + } + + FlatVector & Set2 (double scal1, const FlatVector & v1, + double scal2, const FlatVector & v2) + { + for (int i = 0; i < s; i++) + data[i] = scal1 * v1[i] + scal2 * v2[i]; + return *this; + } + + double L2Norm() const + { + double sum = 0; + for (int i = 0; i < s; i++) + sum += data[i] * data[i]; + return sqrt (sum); + } + + friend double operator* (const FlatVector & v1, const FlatVector & v2); +}; + + + +class Vector : public FlatVector +{ + bool ownmem; +public: + Vector () + { s = 0; data = 0; ownmem = false; } + Vector (int as) + { s = as; data = new double[s]; ownmem = true; } + Vector (int as, double * mem) + { s = as; data = mem; ownmem = false; } + ~Vector () + { if (ownmem) delete [] data; } + + Vector & operator= (const FlatVector & v) + { memcpy (data, &v(0), s*sizeof(double)); return *this; } + + Vector & operator= (double scal) + { + for (int i = 0; i < s; i++) data[i] = scal; + return *this; + } + + void SetSize (int as) + { + if (s != as) + { + s = as; + if (ownmem) delete [] data; + data = new double [s]; + ownmem = true; + } + } + +}; + +template +class VectorMem : public Vector +{ + double mem[S]; +public: + VectorMem () : Vector(S, &mem[0]) { ; } + + VectorMem & operator= (const FlatVector & v) + { memcpy (data, &v(0), S*sizeof(double)); return *this; } + + VectorMem & operator= (double scal) + { + for (int i = 0; i < S; i++) data[i] = scal; + return *this; + } +}; + + + + + +inline double operator* (const FlatVector & v1, const FlatVector & v2) +{ + double sum = 0; + for (int i = 0; i < v1.s; i++) + sum += v1.data[i] * v2.data[i]; + return sum; +} + + + + +inline ostream & operator<< (ostream & ost, const FlatVector & v) +{ + for (int i = 0; i < v.Size(); i++) + ost << " " << setw(7) << v[i]; + return ost; +} + + + +#endif + + diff --git a/libsrc/meshing/Makefile.am b/libsrc/meshing/Makefile.am new file mode 100644 index 00000000..3ea043cc --- /dev/null +++ b/libsrc/meshing/Makefile.am @@ -0,0 +1,37 @@ +AM_CPPFLAGS = $(MPI_INCLUDES) -I$(top_srcdir)/libsrc/include + + +noinst_HEADERS = adfront2.hpp hpref_quad.hpp meshfunc.hpp ruler3.hpp \ +adfront3.hpp findip.hpp findip2.hpp hpref_segm.hpp meshing2.hpp \ +specials.hpp bisect.hpp geomsearch.hpp hpref_tet.hpp meshing3.hpp \ +topology.hpp boundarylayer.hpp global.hpp hpref_trig.hpp meshing.hpp \ +validate.hpp classifyhpel.hpp hpref_hex.hpp improve2.hpp meshtool.hpp \ +clusters.hpp hprefinement.hpp improve3.hpp meshtype.hpp \ + hpref_prism.hpp localh.hpp msghandler.hpp curvedelems.hpp \ + hpref_pyramid.hpp meshclass.hpp ruler2.hpp bcfunctions.hpp \ + basegeom.hpp + + + +METASOURCES = AUTO + +lib_LTLIBRARIES = libmesh.la + +libmesh_la_SOURCES = adfront2.cpp adfront3.cpp bisect.cpp boundarylayer.cpp \ + clusters.cpp curvedelems.cpp delaunay.cpp delaunay2d.cpp \ + geomsearch.cpp global.cpp hprefinement.cpp improve2.cpp \ + improve2gen.cpp improve3.cpp localh.cpp meshclass.cpp \ + meshfunc.cpp meshfunc2d.cpp meshing2.cpp meshing3.cpp \ + meshtool.cpp meshtype.cpp msghandler.cpp netrule2.cpp \ + netrule3.cpp parser2.cpp parser3.cpp prism2rls.cpp \ + pyramid2rls.cpp pyramidrls.cpp quadrls.cpp refine.cpp \ + ruler2.cpp ruler3.cpp secondorder.cpp smoothing2.5.cpp \ + smoothing2.cpp smoothing3.cpp specials.cpp tetrarls.cpp \ + topology.cpp triarls.cpp validate.cpp zrefine.cpp bcfunctions.cpp \ + parallelmesh.cpp paralleltop.cpp paralleltop.hpp basegeom.cpp + +libmesh_la_LIBADD = $(top_builddir)/libsrc/linalg/libla.la \ + $(top_builddir)/libsrc/gprim/libgprim.la \ + $(top_builddir)/libsrc/general/libgen.la \ + -lz + diff --git a/libsrc/meshing/Makefile.in b/libsrc/meshing/Makefile.in new file mode 100644 index 00000000..ba9d1c3c --- /dev/null +++ b/libsrc/meshing/Makefile.in @@ -0,0 +1,684 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc/meshing +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libmesh_la_DEPENDENCIES = $(top_builddir)/libsrc/linalg/libla.la \ + $(top_builddir)/libsrc/gprim/libgprim.la \ + $(top_builddir)/libsrc/general/libgen.la +am_libmesh_la_OBJECTS = adfront2.lo adfront3.lo bisect.lo \ + boundarylayer.lo clusters.lo curvedelems.lo delaunay.lo \ + delaunay2d.lo geomsearch.lo global.lo hprefinement.lo \ + improve2.lo improve2gen.lo improve3.lo localh.lo meshclass.lo \ + meshfunc.lo meshfunc2d.lo meshing2.lo meshing3.lo meshtool.lo \ + meshtype.lo msghandler.lo netrule2.lo netrule3.lo parser2.lo \ + parser3.lo prism2rls.lo pyramid2rls.lo pyramidrls.lo \ + quadrls.lo refine.lo ruler2.lo ruler3.lo secondorder.lo \ + smoothing2.5.lo smoothing2.lo smoothing3.lo specials.lo \ + tetrarls.lo topology.lo triarls.lo validate.lo zrefine.lo \ + bcfunctions.lo parallelmesh.lo paralleltop.lo basegeom.lo +libmesh_la_OBJECTS = $(am_libmesh_la_OBJECTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libmesh_la_SOURCES) +DIST_SOURCES = $(libmesh_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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@ +AM_CPPFLAGS = $(MPI_INCLUDES) -I$(top_srcdir)/libsrc/include +noinst_HEADERS = adfront2.hpp hpref_quad.hpp meshfunc.hpp ruler3.hpp \ +adfront3.hpp findip.hpp findip2.hpp hpref_segm.hpp meshing2.hpp \ +specials.hpp bisect.hpp geomsearch.hpp hpref_tet.hpp meshing3.hpp \ +topology.hpp boundarylayer.hpp global.hpp hpref_trig.hpp meshing.hpp \ +validate.hpp classifyhpel.hpp hpref_hex.hpp improve2.hpp meshtool.hpp \ +clusters.hpp hprefinement.hpp improve3.hpp meshtype.hpp \ + hpref_prism.hpp localh.hpp msghandler.hpp curvedelems.hpp \ + hpref_pyramid.hpp meshclass.hpp ruler2.hpp bcfunctions.hpp \ + basegeom.hpp + +METASOURCES = AUTO +lib_LTLIBRARIES = libmesh.la +libmesh_la_SOURCES = adfront2.cpp adfront3.cpp bisect.cpp boundarylayer.cpp \ + clusters.cpp curvedelems.cpp delaunay.cpp delaunay2d.cpp \ + geomsearch.cpp global.cpp hprefinement.cpp improve2.cpp \ + improve2gen.cpp improve3.cpp localh.cpp meshclass.cpp \ + meshfunc.cpp meshfunc2d.cpp meshing2.cpp meshing3.cpp \ + meshtool.cpp meshtype.cpp msghandler.cpp netrule2.cpp \ + netrule3.cpp parser2.cpp parser3.cpp prism2rls.cpp \ + pyramid2rls.cpp pyramidrls.cpp quadrls.cpp refine.cpp \ + ruler2.cpp ruler3.cpp secondorder.cpp smoothing2.5.cpp \ + smoothing2.cpp smoothing3.cpp specials.cpp tetrarls.cpp \ + topology.cpp triarls.cpp validate.cpp zrefine.cpp bcfunctions.cpp \ + parallelmesh.cpp paralleltop.cpp paralleltop.hpp basegeom.cpp + +libmesh_la_LIBADD = $(top_builddir)/libsrc/linalg/libla.la \ + $(top_builddir)/libsrc/gprim/libgprim.la \ + $(top_builddir)/libsrc/general/libgen.la \ + -lz + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/meshing/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/meshing/Makefile +.PRECIOUS: 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): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libmesh.la: $(libmesh_la_OBJECTS) $(libmesh_la_DEPENDENCIES) $(EXTRA_libmesh_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libmesh_la_OBJECTS) $(libmesh_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adfront2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adfront3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basegeom.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcfunctions.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bisect.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/boundarylayer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clusters.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curvedelems.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delaunay.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delaunay2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geomsearch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hprefinement.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improve2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improve2gen.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/improve3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshclass.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshfunc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshfunc2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshing2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshing3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshtool.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshtype.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msghandler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrule2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netrule3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallelmesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paralleltop.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parser3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prism2rls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyramid2rls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyramidrls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quadrls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refine.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ruler2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ruler3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/secondorder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smoothing2.5.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smoothing2.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smoothing3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/specials.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tetrarls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/topology.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/triarls.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/validate.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zrefine.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + 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-libLTLIBRARIES + +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: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES 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 uninstall uninstall-am uninstall-libLTLIBRARIES + + +# 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/libsrc/meshing/adfront2.cpp b/libsrc/meshing/adfront2.cpp new file mode 100644 index 00000000..8bb4cc87 --- /dev/null +++ b/libsrc/meshing/adfront2.cpp @@ -0,0 +1,495 @@ +/* + Advancing front class for surfaces +*/ + +#include +#include "meshing.hpp" + + +namespace netgen +{ + FrontPoint2 :: FrontPoint2 (const Point<3> & ap, PointIndex agi, + MultiPointGeomInfo * amgi, bool aonsurface) + { + p = ap; + globalindex = agi; + nlinetopoint = 0; + frontnr = INT_MAX-10; + onsurface = aonsurface; + + if (amgi) + { + mgi = new MultiPointGeomInfo (*amgi); + for (int i = 1; i <= mgi->GetNPGI(); i++) + if (mgi->GetPGI(i).trignum <= 0) + cout << "Add FrontPoint2, illegal geominfo = " << mgi->GetPGI(i).trignum << endl; + } + else + mgi = NULL; + } + + + AdFront2 :: AdFront2 (const Box3d & aboundingbox) + : boundingbox(aboundingbox), + linesearchtree(boundingbox.PMin(), boundingbox.PMax()), + pointsearchtree(boundingbox.PMin(), boundingbox.PMax()), + cpointsearchtree(boundingbox.PMin(), boundingbox.PMax()) + { + nfl = 0; + allflines = 0; + + minval = 0; + starti = lines.Begin(); + } + + AdFront2 :: ~AdFront2 () + { + delete allflines; + } + + + void AdFront2 :: PrintOpenSegments (ostream & ost) const + { + if (nfl > 0) + { + ost << nfl << " open front segments left:" << endl; + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + ost << i << ": " + << GetGlobalIndex (lines[i].L().I1()) << "-" + << GetGlobalIndex (lines[i].L().I2()) << endl; + } + } + + /* + void AdFront2 :: GetPoints (Array > & apoints) const + { + apoints.Append (points); + // for (int i = 0; i < points.Size(); i++) + // apoints.Append (points[i].P()); + } + */ + + + + int AdFront2 :: AddPoint (const Point<3> & p, PointIndex globind, + MultiPointGeomInfo * mgi, + bool pointonsurface) + { + // inserts at empty position or resizes array + int pi; + + if (delpointl.Size() != 0) + { + pi = delpointl.Last(); + delpointl.DeleteLast (); + + points[pi] = FrontPoint2 (p, globind, mgi, pointonsurface); + } + else + { + pi = points.Append (FrontPoint2 (p, globind, mgi, pointonsurface)) - 1; + } + + if (mgi) + cpointsearchtree.Insert (p, pi); + + if (pointonsurface) + pointsearchtree.Insert (p, pi); + + return pi; + } + + + int AdFront2 :: AddLine (int pi1, int pi2, + const PointGeomInfo & gi1, const PointGeomInfo & gi2) + { + int minfn; + int li; + + FrontPoint2 & p1 = points[pi1]; + FrontPoint2 & p2 = points[pi2]; + + + nfl++; + + p1.AddLine(); + p2.AddLine(); + + minfn = min2 (p1.FrontNr(), p2.FrontNr()); + p1.DecFrontNr (minfn+1); + p2.DecFrontNr (minfn+1); + + if (dellinel.Size() != 0) + { + li = dellinel.Last(); + dellinel.DeleteLast (); + lines[li] = FrontLine (INDEX_2(pi1, pi2)); + } + else + { + li = lines.Append(FrontLine (INDEX_2(pi1, pi2))) - 1; + } + + + if (!gi1.trignum || !gi2.trignum) + { + cout << "ERROR: in AdFront::AddLine, illegal geominfo" << endl; + } + + lines[li].SetGeomInfo (gi1, gi2); + + Box3d lbox; + lbox.SetPoint(p1.P()); + lbox.AddPoint(p2.P()); + + linesearchtree.Insert (lbox.PMin(), lbox.PMax(), li); + + if (allflines) + { + if (allflines->Used (INDEX_2 (GetGlobalIndex (pi1), + GetGlobalIndex (pi2)))) + { + cerr << "ERROR Adfront2::AddLine: line exists" << endl; + (*testout) << "ERROR Adfront2::AddLine: line exists" << endl; + } + + allflines->Set (INDEX_2 (GetGlobalIndex (pi1), + GetGlobalIndex (pi2)), 1); + } + + return li; + } + + + void AdFront2 :: DeleteLine (int li) + { + int pi; + + nfl--; + + for (int i = 1; i <= 2; i++) + { + pi = lines[li].L().I(i); + points[pi].RemoveLine(); + + if (!points[pi].Valid()) + { + delpointl.Append (pi); + if (points[pi].mgi) + { + cpointsearchtree.DeleteElement (pi); + delete points[pi].mgi; + points[pi].mgi = NULL; + } + + pointsearchtree.DeleteElement (pi); + } + } + + if (allflines) + { + allflines->Set (INDEX_2 (GetGlobalIndex (lines[li].L().I1()), + GetGlobalIndex (lines[li].L().I2())), 2); + } + + lines[li].Invalidate(); + linesearchtree.DeleteElement (li); + + dellinel.Append (li); + } + + + int AdFront2 :: ExistsLine (int pi1, int pi2) + { + if (!allflines) + return 0; + if (allflines->Used (INDEX_2(pi1, pi2))) + return allflines->Get (INDEX_2 (pi1, pi2)); + else + return 0; + } + + + int AdFront2 :: SelectBaseLine (Point<3> & p1, Point<3> & p2, + const PointGeomInfo *& geominfo1, + const PointGeomInfo *& geominfo2, + int & qualclass) + { + int baselineindex = -1; + + for (int i = starti; i < lines.End(); i++) + { + if (lines[i].Valid()) + { + int hi = lines[i].LineClass() + + points[lines[i].L().I1()].FrontNr() + + points[lines[i].L().I2()].FrontNr(); + + if (hi <= minval) + { + minval = hi; + baselineindex = i; + break; + } + } + } + + if (baselineindex == -1) + { + minval = INT_MAX; + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + { + int hi = lines[i].LineClass() + + points[lines[i].L().I1()].FrontNr() + + points[lines[i].L().I2()].FrontNr(); + + if (hi < minval) + { + minval = hi; + baselineindex = i; + } + } + } + starti = baselineindex+1; + + p1 = points[lines[baselineindex].L().I1()].P(); + p2 = points[lines[baselineindex].L().I2()].P(); + geominfo1 = &lines[baselineindex].GetGeomInfo(1); + geominfo2 = &lines[baselineindex].GetGeomInfo(2); + + qualclass = lines[baselineindex].LineClass(); + + return baselineindex; + } + + + + + int AdFront2 :: GetLocals (int baselineindex, + Array & locpoints, + Array & pgeominfo, + Array & loclines, // local index + Array & pindex, + Array & lindex, + double xh) + { + static int timer = NgProfiler::CreateTimer ("adfront2::GetLocals"); + NgProfiler::RegionTimer reg (timer); + + + int pstind; + Point<3> midp, p0; + + pstind = lines[baselineindex].L().I1(); + p0 = points[pstind].P(); + + loclines.Append(lines[baselineindex].L()); + lindex.Append(baselineindex); + + ArrayMem nearlines(0); + ArrayMem nearpoints(0); + + // dominating costs !! + linesearchtree.GetIntersecting (p0 - Vec3d(xh, xh, xh), + p0 + Vec3d(xh, xh, xh), + nearlines); + + pointsearchtree.GetIntersecting (p0 - Vec3d(xh, xh, xh), + p0 + Vec3d(xh, xh, xh), + nearpoints); + + for (int ii = 0; ii < nearlines.Size(); ii++) + { + int i = nearlines[ii]; + if (lines[i].Valid() && i != baselineindex) + { + loclines.Append(lines[i].L()); + lindex.Append(i); + } + } + + // static Array invpindex; + invpindex.SetSize (points.Size()); + // invpindex = -1; + for (int i = 0; i < nearpoints.Size(); i++) + invpindex[nearpoints[i]] = -1; + + for (int i = 0; i < loclines.Size(); i++) + { + invpindex[loclines[i].I1()] = 0; + invpindex[loclines[i].I2()] = 0; + } + + + for (int i = 0; i < loclines.Size(); i++) + { + for (int j = 0; j < 2; j++) + { + int pi = loclines[i][j]; + if (invpindex[pi] == 0) + { + pindex.Append (pi); + invpindex[pi] = pindex.Size(); + loclines[i][j] = locpoints.Append (points[pi].P()); + } + else + loclines[i][j] = invpindex[pi]; + } + } + + + // double xh2 = xh*xh; + for (int ii = 0; ii < nearpoints.Size(); ii++) + { + int i = nearpoints[ii]; + if (points[i].Valid() && + points[i].OnSurface() && + // Dist2 (points.Get(i).P(), p0) <= xh2 && + invpindex[i] <= 0) + { + invpindex[i] = locpoints.Append (points[i].P()); + pindex.Append(i); + } + } + /* + double xh2 = xh*xh; + for (i = 1; i <= points.Size(); i++) + { + if (points.Get(i).Valid() && + points.Get(i).OnSurface() && + Dist2 (points.Get(i).P(), p0) <= xh2 && + invpindex.Get(i) <= 0) + { + invpindex.Elem(i) = + locpoints.Append (points.Get(i).P()); + pindex.Append(i); + } + } + */ + + pgeominfo.SetSize (locpoints.Size()); + for (int i = 0; i < pgeominfo.Size(); i++) + pgeominfo[i].Init(); + + + for (int i = 0; i < loclines.Size(); i++) + for (int j = 0; j < 2; j++) + { + int lpi = loclines[i][j]; + + const PointGeomInfo & gi = + lines[lindex[i]].GetGeomInfo (j+1); + pgeominfo.Elem(lpi).AddPointGeomInfo (gi); + + /* + if (pgeominfo.Elem(lpi).cnt == MULTIPOINTGEOMINFO_MAX) + break; + + const PointGeomInfo & gi = + lines.Get(lindex.Get(i)).GetGeomInfo (j); + + PointGeomInfo * pgi = pgeominfo.Elem(lpi).mgi; + + int found = 0; + for (k = 0; k < pgeominfo.Elem(lpi).cnt; k++) + if (pgi[k].trignum == gi.trignum) + found = 1; + + if (!found) + { + pgi[pgeominfo.Elem(lpi).cnt] = gi; + pgeominfo.Elem(lpi).cnt++; + } + */ + } + + for (int i = 0; i < locpoints.Size(); i++) + { + int pi = pindex[i]; + + if (points[pi].mgi) + for (int j = 1; j <= points[pi].mgi->GetNPGI(); j++) + pgeominfo[i].AddPointGeomInfo (points[pi].mgi->GetPGI(j)); + } + + if (loclines.Size() == 1) + { + cout << "loclines.Size = 1" << endl; + (*testout) << "loclines.size = 1" << endl + << " h = " << xh << endl + << " nearline.size = " << nearlines.Size() << endl + << " p0 = " << p0 << endl; + } + + return lines[baselineindex].LineClass(); + } + + + + void AdFront2 :: SetStartFront () + { + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + for (int j = 1; j <= 2; j++) + points[lines[i].L().I(j)].DecFrontNr(0); + } + + + void AdFront2 :: Print (ostream & ost) const + { + ost << points.Size() << " Points: " << endl; + for (int i = points.Begin(); i < points.End(); i++) + if (points[i].Valid()) + ost << i << " " << points[i].P() << endl; + + ost << nfl << " Lines: " << endl; + for (int i = lines.Begin(); i < lines.End(); i++) + if (lines[i].Valid()) + ost << lines[i].L().I1() << " - " << lines[i].L().I2() << endl; + + ost << flush; + } + + + bool AdFront2 :: Inside (const Point<2> & p) const + { + int cnt; + Vec<2> n; + Vec<3> v1; + DenseMatrix a(2), ainv(2); + Vector b(2), u(2); + + // quasi-random numbers: + n(0) = 0.123871; + n(1) = 0.15432; + + cnt = 0; + for (int i = 0; i < lines.Size(); i++) + if (lines[i].Valid()) + { + const Point<3> & p1 = points[lines[i].L().I1()].P(); + const Point<3> & p2 = points[lines[i].L().I2()].P(); + + v1 = p2 - p1; + + a(0, 0) = v1(0); + a(1, 0) = v1(1); + + a(0, 1) = -n(0); + a(1, 1) = -n(1); + + b(0) = p(0) - p1(0); + b(1) = p(1) - p1(1); + + CalcInverse (a, ainv); + ainv.Mult (b, u); + + if (u(0) >= 0 && u(0) <= 1 && u(1) > 0) + cnt++; + } + + return ((cnt % 2) != 0); + } +} diff --git a/libsrc/meshing/adfront2.hpp b/libsrc/meshing/adfront2.hpp new file mode 100644 index 00000000..6a8158b9 --- /dev/null +++ b/libsrc/meshing/adfront2.hpp @@ -0,0 +1,282 @@ +#ifndef FILE_ADFRONT2 +#define FILE_ADFRONT2 + +/**************************************************************************/ +/* File: adfront2.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Okt. 95 */ +/**************************************************************************/ + + +/** + + Advancing front class for surfaces + +*/ + + /// + class FrontPoint2 + { + /// coordinates + Point<3> p; + /// global node index + PointIndex globalindex; + /// number of front lines connected to point + int nlinetopoint; + /// distance to original boundary + int frontnr; + + bool onsurface; + + public: + /// + MultiPointGeomInfo * mgi; + + /// + FrontPoint2 () + { + globalindex = -1; + nlinetopoint = 0; + frontnr = INT_MAX-10; // attention: overflow on calculating INT_MAX + 1 + mgi = NULL; + onsurface = true; + } + + /// + FrontPoint2 (const Point<3> & ap, PointIndex agi, + MultiPointGeomInfo * amgi, bool aonsurface = true); + /// + ~FrontPoint2 () { ; } + + /// + const Point<3> & P () const { return p; } + /// + operator const Point<3> & () const { return p; } + /// + PointIndex GlobalIndex () const { return globalindex; } + + /// + void AddLine () { nlinetopoint++; } + /// + void RemoveLine () + { + nlinetopoint--; + if (nlinetopoint == 0) + nlinetopoint = -1; + } + + /// + bool Valid () const + { return nlinetopoint >= 0; } + + /// + bool OnSurface() const + { return onsurface; } + + /// + void DecFrontNr (int afrontnr) + { + if (frontnr > afrontnr) frontnr = afrontnr; + } + + /// + int FrontNr () const { return frontnr; } + }; + + + /// + class FrontLine + { + private: + /// Point Indizes + INDEX_2 l; + /// quality class + int lineclass; + /// geometry specific data + PointGeomInfo geominfo[2]; + public: + + FrontLine () + { + lineclass = 1; + } + + /// + FrontLine (const INDEX_2 & al) + { + l = al; + lineclass = 1; + } + + + /// + const INDEX_2 & L () const + { + return l; + } + + /// + int LineClass() const + { + return lineclass; + } + + /// + void IncrementClass () + { + lineclass++; + } + /// + void ResetClass () + { + lineclass = 1; + } + + /// + bool Valid () const + { + return l.I1() != -1; + } + /// + void Invalidate () + { + l.I1() = -1; + l.I2() = -1; + lineclass = 1000; + } + + void SetGeomInfo (const PointGeomInfo & gi1, const PointGeomInfo & gi2) + { + geominfo[0] = gi1; + geominfo[1] = gi2; + } + + const PointGeomInfo * GetGeomInfo () const + { return geominfo; } + + const PointGeomInfo & GetGeomInfo (int endp) const + { return geominfo[endp-1]; } + + friend class AdFront2; + }; + + +class AdFront2 +{ + + /// + Array points; /// front points + Array lines; /// front lines + + Box3d boundingbox; + Box3dTree linesearchtree; /// search tree for lines + Point3dTree pointsearchtree; /// search tree for points + Point3dTree cpointsearchtree; /// search tree for cone points (not used ???) + + Array delpointl; /// list of deleted front points + Array dellinel; /// list of deleted front lines + + int nfl; /// number of front lines; + INDEX_2_HASHTABLE * allflines; /// all front lines ever have been + + Array invpindex; + + int minval; + int starti; + +public: + /// + // AdFront2 (); + AdFront2 (const Box3d & aboundingbox); + /// + ~AdFront2 (); + + /// + // void GetPoints (Array > & apoints) const; + /// + void Print (ostream & ost) const; + + /// + bool Empty () const + { + return nfl == 0; + } + /// + int GetNFL () const { return nfl; } + + const FrontLine & GetLine (int nr) { return lines[nr]; } + const FrontPoint2 & GetPoint (int nr) { return points[nr]; } + + + /// + int SelectBaseLine (Point<3> & p1, Point<3> & p2, + const PointGeomInfo *& geominfo1, + const PointGeomInfo *& geominfo2, + int & qualclass); + + /// + int GetLocals (int baseline, + Array & locpoints, + Array & pgeominfo, + Array & loclines, // local index + Array & pindex, + Array & lindex, + double xh); + + /// + void DeleteLine (int li); + /// + int AddPoint (const Point<3> & p, PointIndex globind, + MultiPointGeomInfo * mgi = NULL, + bool pointonsurface = true); + /// + int AddLine (int pi1, int pi2, + const PointGeomInfo & gi1, const PointGeomInfo & gi2); + /// + int ExistsLine (int gpi1, int gpi2); + + /// + void IncrementClass (int li) + { + lines[li].IncrementClass(); + } + + /// + void ResetClass (int li) + { + lines[li].ResetClass(); + } + + /// + const PointGeomInfo & GetLineGeomInfo (int li, int lend) const + { return lines[li].GetGeomInfo (lend); } + /// + + PointIndex GetGlobalIndex (int pi) const + { + return points[pi].GlobalIndex(); + } + + + /// is Point p inside Surface (flat geometry only) + bool Inside (const Point<2> & p) const; + + bool SameSide (const Point<2> & lp1, const Point<2> & lp2, + const Array * /* testfaces */ = NULL) const + { + return Inside (lp1) == Inside (lp2); + } + + + /// + void SetStartFront (); + /// + void PrintOpenSegments (ostream & ost) const; +}; + + + +#endif + + + diff --git a/libsrc/meshing/adfront3.cpp b/libsrc/meshing/adfront3.cpp new file mode 100644 index 00000000..1499b2a1 --- /dev/null +++ b/libsrc/meshing/adfront3.cpp @@ -0,0 +1,865 @@ +#include +#include "meshing.hpp" + + +/* ********************** FrontPoint ********************** */ + +namespace netgen +{ + +FrontPoint3 :: FrontPoint3 () +{ + globalindex = -1; + nfacetopoint = 0; + frontnr = 1000; + cluster = 0; +} + + +FrontPoint3 :: FrontPoint3 (const Point<3> & ap, PointIndex agi) +{ + p = ap; + globalindex = agi; + nfacetopoint = 0; + frontnr = 1000; + cluster = 0; +} + + + +/* ********************** FrontFace ********************** */ + +FrontFace :: FrontFace () +{ + qualclass = 1; + oldfront = 0; + hashvalue = 0; + cluster = 0; +} + +FrontFace :: FrontFace (const MiniElement2d & af) +{ + f = af; + oldfront = 0; + qualclass = 1; + hashvalue = 0; +} + +void FrontFace :: Invalidate () +{ + f.Delete(); + oldfront = 0; + qualclass = 1000; +} + + + + +/* ********************** AddFront ********************** */ + + +AdFront3 :: AdFront3 () +{ + nff = 0; + nff4 = 0; + vol = 0; + + hashon = 1; + hashcreated = 0; + if (hashon) + hashtable.Init(&points, &faces); + + facetree = NULL; + connectedpairs = NULL; + + rebuildcounter = -1; + lasti = 0; + minval = -1; +} + + +AdFront3 :: ~AdFront3 () +{ + delete facetree; + delete connectedpairs; +} + +void AdFront3 :: GetPoints (Array > & apoints) const +{ + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + + apoints.Append (points[pi].P()); +} + + +PointIndex AdFront3 :: AddPoint (const Point<3> & p, PointIndex globind) +{ + if (delpointl.Size()) + { + PointIndex pi = delpointl.Last(); + delpointl.DeleteLast (); + + points[pi] = FrontPoint3 (p, globind); + return pi; + } + else + { + points.Append (FrontPoint3 (p, globind)); + return --points.End(); + // return points.Size()-1+PointIndex::BASE; + } +} + + +INDEX AdFront3 :: AddFace (const MiniElement2d & aface) +{ + int i, minfn; + + nff++; + + for (i = 0; i < aface.GetNP(); i++) + points[aface[i]].AddFace(); + + const Point3d & p1 = points[aface[0]].P(); + const Point3d & p2 = points[aface[1]].P(); + const Point3d & p3 = points[aface[2]].P(); + + vol += 1.0/6.0 * (p1.X() + p2.X() + p3.X()) * + ( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) - + (p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) ); + + if (aface.GetNP() == 4) + { + nff4++; + const Point3d & p4 = points[aface[3]].P(); + vol += 1.0/6.0 * (p1.X() + p3.X() + p4.X()) * + ( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) - + (p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) ); + } + + + minfn = 1000; + for (i = 0; i < aface.GetNP(); i++) + { + int fpn = points[aface[i]].FrontNr(); + if (i == 0 || fpn < minfn) + minfn = fpn; + } + + + int cluster = 0; + for (i = 1; i <= aface.GetNP(); i++) + { + if (points[aface.PNum(i)].cluster) + cluster = points[aface.PNum(i)].cluster; + } + for (i = 1; i <= aface.GetNP(); i++) + points[aface.PNum(i)].cluster = cluster; + + + for (i = 1; i <= aface.GetNP(); i++) + points[aface.PNum(i)].DecFrontNr (minfn+1); + + int nfn = faces.Append(FrontFace (aface)); + faces.Elem(nfn).cluster = cluster; + + if (hashon && hashcreated) + hashtable.AddElem(aface, nfn); + + return nfn; +} + + + +void AdFront3 :: DeleteFace (INDEX fi) +{ + nff--; + + for (int i = 1; i <= faces.Get(fi).Face().GetNP(); i++) + { + PointIndex pi = faces.Get(fi).Face().PNum(i); + points[pi].RemoveFace(); + if (!points[pi].Valid()) + delpointl.Append (pi); + } + + const MiniElement2d & face = faces.Get(fi).Face(); + const Point3d & p1 = points[face.PNum(1)].P(); + const Point3d & p2 = points[face.PNum(2)].P(); + const Point3d & p3 = points[face.PNum(3)].P(); + + vol -= 1.0/6.0 * (p1.X() + p2.X() + p3.X()) * + ( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) - + (p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) ); + + if (face.GetNP() == 4) + { + const Point3d & p4 = points[face.PNum(4)].P(); + vol -= 1.0/6.0 * (p1.X() + p3.X() + p4.X()) * + ( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) - + (p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) ); + + nff4--; + } + + faces.Elem(fi).Invalidate(); +} + + +INDEX AdFront3 :: AddConnectedPair (const INDEX_2 & apair) +{ + if (!connectedpairs) + connectedpairs = new TABLE (GetNP()); + + connectedpairs->Add (apair.I1(), apair.I2()); + connectedpairs->Add (apair.I2(), apair.I1()); + + return 0; +} + + +void AdFront3 :: CreateTrees () +{ + int i, j; + PointIndex pi; + Point3d pmin, pmax; + + for (pi = PointIndex::BASE; + pi < GetNP()+PointIndex::BASE; pi++) + { + const Point<3> & p = GetPoint(pi); + if (pi == PointIndex::BASE) + { + pmin = p; + pmax = p; + } + else + { + pmin.SetToMin (p); + pmax.SetToMax (p); + } + } + + pmax = pmax + 0.5 * (pmax - pmin); + pmin = pmin + 0.5 * (pmin - pmax); + + delete facetree; + facetree = new Box3dTree (pmin, pmax); + + for (i = 1; i <= GetNF(); i++) + { + const MiniElement2d & el = GetFace(i); + pmin = GetPoint (el[0]); + pmax = pmin; + for (j = 1; j < 3; j++) + { + const Point<3> & p = GetPoint (el[j]); + pmin.SetToMin (p); + pmax.SetToMax (p); + } + pmax = pmax + 0.01 * (pmax - pmin); + pmin = pmin + 0.01 * (pmin - pmax); + // (*testout) << "insert " << i << ": " << pmin << " - " << pmax << "\n"; + facetree -> Insert (pmin, pmax, i); + } +} + + +void AdFront3 :: GetIntersectingFaces (const Point<3> & pmin, const Point<3> & pmax, + Array & ifaces) const +{ + facetree -> GetIntersecting (pmin, pmax, ifaces); +} + +void AdFront3 :: GetFaceBoundingBox (int i, Box3d & box) const +{ + const FrontFace & face = faces.Get(i); + box.SetPoint (points[face.f[0]].p); + box.AddPoint (points[face.f[1]].p); + box.AddPoint (points[face.f[2]].p); +} + +void AdFront3 :: RebuildInternalTables () +{ + static int timer_a = NgProfiler::CreateTimer ("Adfront3::RebuildInternal A"); + static int timer_b = NgProfiler::CreateTimer ("Adfront3::RebuildInternal B"); + static int timer_c = NgProfiler::CreateTimer ("Adfront3::RebuildInternal C"); + static int timer_d = NgProfiler::CreateTimer ("Adfront3::RebuildInternal D"); + + + NgProfiler::StartTimer (timer_a); + int hi = 0; + for (int i = 1; i <= faces.Size(); i++) + if (faces.Get(i).Valid()) + { + hi++; + if (hi < i) + faces.Elem(hi) = faces.Get(i); + } + + faces.SetSize (nff); + + int np = points.Size(); + + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + points[pi].cluster = pi; + + NgProfiler::StopTimer (timer_a); + NgProfiler::StartTimer (timer_b); + + int change; + do + { + change = 0; + for (int i = 1; i <= faces.Size(); i++) + { + const MiniElement2d & el = faces.Get(i).Face(); + + int mini = points[el.PNum(1)].cluster; + int maxi = mini; + + for (int j = 2; j <= 3; j++) + { + int ci = points[el.PNum(j)].cluster; + if (ci < mini) mini = ci; + if (ci > maxi) maxi = ci; + } + + if (mini < maxi) + { + change = 1; + for (int j = 1; j <= 3; j++) + points[el.PNum(j)].cluster = mini; + } + } + } + while (change); + + + NgProfiler::StopTimer (timer_b); + NgProfiler::StartTimer (timer_c); + + + + + BitArrayChar usecl(np); + usecl.Clear(); + for (int i = 1; i <= faces.Size(); i++) + { + usecl.Set (points[faces.Get(i).Face().PNum(1)].cluster); + faces.Elem(i).cluster = + points[faces.Get(i).Face().PNum(1)].cluster; + } + int cntcl = 0; + for (int i = PointIndex::BASE; + i < np+PointIndex::BASE; i++) + if (usecl.Test(i)) + cntcl++; + + Array clvol (np); + clvol = 0.0; + + for (int i = 1; i <= faces.Size(); i++) + { + const MiniElement2d & face = faces.Get(i).Face(); + + const Point3d p1 = points[face.PNum(1)].P(); + const Point3d p2 = points[face.PNum(2)].P(); + const Point3d p3 = points[face.PNum(3)].P(); + + double vi = 1.0/6.0 * (p1.X() + p2.X() + p3.X()) * + ( (p2.Y() - p1.Y()) * (p3.Z() - p1.Z()) - + (p2.Z() - p1.Z()) * (p3.Y() - p1.Y()) ); + + if (face.GetNP() == 4) + { + const Point3d p4 = points[face.PNum(4)].P(); + vi += 1.0/6.0 * (p1.X() + p3.X() + p4.X()) * + ( (p3.Y() - p1.Y()) * (p4.Z() - p1.Z()) - + (p3.Z() - p1.Z()) * (p4.Y() - p1.Y()) ); + } + + clvol[faces.Get(i).cluster] += vi; + } + + NgProfiler::StopTimer (timer_c); + NgProfiler::StartTimer (timer_d); + + + + int negvol = 0; + for (int i = PointIndex::BASE; + i < clvol.Size()+PointIndex::BASE; i++) + { + if (clvol[i] < 0) + negvol = 1; + } + + if (negvol) + { + for (int i = 1; i <= faces.Size(); i++) + faces.Elem(i).cluster = 1; + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + points[pi].cluster = 1; + } + + if (hashon) + hashtable.Create(); + + NgProfiler::StopTimer (timer_d); +} + + + +int AdFront3 :: SelectBaseElement () +{ + int i, hi, fstind; + + /* + static int minval = -1; + static int lasti = 0; + static int counter = 0; + */ + if (rebuildcounter <= 0) + { + RebuildInternalTables(); + rebuildcounter = nff / 10 + 1; + + lasti = 0; + } + rebuildcounter--; + + /* + if (faces.Size() > 2 * nff) + { + // compress facelist + + RebuildInternalTables (); + lasti = 0; + } + */ + + fstind = 0; + + for (i = lasti+1; i <= faces.Size() && !fstind; i++) + if (faces.Elem(i).Valid()) + { + hi = faces.Get(i).QualClass() + + points[faces.Get(i).Face().PNum(1)].FrontNr() + + points[faces.Get(i).Face().PNum(2)].FrontNr() + + points[faces.Get(i).Face().PNum(3)].FrontNr(); + + if (hi <= minval) + { + minval = hi; + fstind = i; + lasti = fstind; + } + } + + if (!fstind) + { + minval = INT_MAX; + for (i = 1; i <= faces.Size(); i++) + if (faces.Elem(i).Valid()) + { + hi = faces.Get(i).QualClass() + + points[faces.Get(i).Face().PNum(1)].FrontNr() + + points[faces.Get(i).Face().PNum(2)].FrontNr() + + points[faces.Get(i).Face().PNum(3)].FrontNr(); + + if (hi <= minval) + { + minval = hi; + fstind = i; + lasti = 0; + } + } + } + + + return fstind; +} + + + +int AdFront3 :: GetLocals (int fstind, + Array & locpoints, + Array & locfaces, // local index + Array & pindex, + Array & findex, + INDEX_2_HASHTABLE & getconnectedpairs, + float xh, + float relh, + INDEX& facesplit) +{ + static int timer = NgProfiler::CreateTimer ("AdFront3::GetLocals"); + NgProfiler::RegionTimer reg (timer); + + + if (hashon && faces.Size() < 500) { hashon=0; } + if (hashon && !hashcreated) + { + hashtable.Create(); + hashcreated=1; + } + + INDEX i, j; + PointIndex pstind; + Point3d midp, p0; + + // static Array invpindex; + + Array locfaces2; //all local faces in radius xh + Array locfaces3; // all faces in outer radius relh + Array findex2; + + locfaces2.SetSize(0); + locfaces3.SetSize(0); + findex2.SetSize(0); + + int cluster = faces.Get(fstind).cluster; + + pstind = faces.Get(fstind).Face().PNum(1); + p0 = points[pstind].P(); + + locfaces2.Append(faces.Get(fstind).Face()); + findex2.Append(fstind); + + + Box3d b1 (p0 - Vec3d(xh, xh, xh), p0 + Vec3d (xh, xh, xh)); + + if (hashon) + { + hashtable.GetLocals(locfaces2, findex2, fstind, p0, xh); + } + else + { + for (i = 1; i <= faces.Size(); i++) + { + const MiniElement2d & face = faces.Get(i).Face(); + if (faces.Get(i).cluster == cluster && faces.Get(i).Valid() && i != fstind) + { + Box3d b2; + b2.SetPoint (points[face[0]].P()); + b2.AddPoint (points[face[1]].P()); + b2.AddPoint (points[face[2]].P()); + + if (b1.Intersect (b2)) + { + locfaces2.Append(faces.Get(i).Face()); + findex2.Append(i); + } + } + } + } + + //local faces for inner radius: + for (i = 1; i <= locfaces2.Size(); i++) + { + const MiniElement2d & face = locfaces2.Get(i); + const Point3d & p1 = points[face[0]].P(); + const Point3d & p2 = points[face[1]].P(); + const Point3d & p3 = points[face[2]].P(); + + midp = Center (p1, p2, p3); + + if (Dist2 (midp, p0) <= relh * relh || i == 1) + { + locfaces.Append(locfaces2.Get(i)); + findex.Append(findex2.Get(i)); + } + else + locfaces3.Append (i); + } + + facesplit=locfaces.Size(); + + + //local faces for outer radius: + for (i = 1; i <= locfaces3.Size(); i++) + { + locfaces.Append (locfaces2.Get(locfaces3.Get(i))); + findex.Append (findex2.Get(locfaces3.Get(i))); + } + + + invpindex.SetSize (points.Size()); + for (i = 1; i <= locfaces.Size(); i++) + for (j = 1; j <= locfaces.Get(i).GetNP(); j++) + { + PointIndex pi = locfaces.Get(i).PNum(j); + invpindex[pi] = -1; + } + + for (i = 1; i <= locfaces.Size(); i++) + { + for (j = 1; j <= locfaces.Get(i).GetNP(); j++) + { + PointIndex pi = locfaces.Get(i).PNum(j); + if (invpindex[pi] == -1) + { + pindex.Append (pi); + invpindex[pi] = pindex.Size(); // -1+PointIndex::BASE; + locfaces.Elem(i).PNum(j) = locpoints.Append (points[pi].P()); + } + else + locfaces.Elem(i).PNum(j) = invpindex[pi]; + + } + } + + + + if (connectedpairs) + { + for (i = 1; i <= locpoints.Size(); i++) + { + int pind = pindex.Get(i); + if (pind >= 1 && pind <= connectedpairs->Size ()) + { + for (j = 1; j <= connectedpairs->EntrySize(pind); j++) + { + int oi = connectedpairs->Get(pind, j); + int other = invpindex.Get(oi); + if (other >= 1 && other <= pindex.Size() && + pindex.Get(other) == oi) + { + // INDEX_2 coned(i, other); + // coned.Sort(); + // (*testout) << "connected: " << locpoints.Get(i) << "-" << locpoints.Get(other) << endl; + getconnectedpairs.Set (INDEX_2::Sort (i, other), 1); + } + } + } + } + } + + + /* + // add isolated points + for (i = 1; i <= points.Size(); i++) + if (points.Elem(i).Valid() && Dist (points.Elem(i).P(), p0) <= xh) + { + if (!invpindex.Get(i)) + { + locpoints.Append (points.Get(i).P()); + pindex.Append (i); + invpindex.Elem(i) = pindex.Size(); + } + } + */ + return faces.Get(fstind).QualClass(); +} + + +// returns all points connected with fi +void AdFront3 :: GetGroup (int fi, + Array & grouppoints, + Array & groupelements, + Array & pindex, + Array & findex) +{ + // static Array pingroup; + int i, j, changed; + + pingroup.SetSize(points.Size()); + + pingroup = 0; + for (j = 1; j <= 3; j++) + pingroup.Elem (faces.Get(fi).Face().PNum(j)) = 1; + + do + { + changed = 0; + + for (i = 1; i <= faces.Size(); i++) + if (faces.Get(i).Valid()) + { + const MiniElement2d & face = faces.Get(i).Face(); + + int fused = 0; + for (j = 1; j <= 3; j++) + if (pingroup.Elem(face.PNum(j))) + fused++; + + if (fused >= 2) + for (j = 1; j <= 3; j++) + if (!pingroup.Elem(face.PNum(j))) + { + pingroup.Elem(face.PNum(j)) = 1; + changed = 1; + } + } + + } + while (changed); + + + // static Array invpindex; + invpindex.SetSize (points.Size()); + + + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + if (points.Get(i).Valid()) + { + grouppoints.Append (points[pi].P()); + pindex.Append (pi); + invpindex[pi] = pindex.Size(); + } + + for (i = 1; i <= faces.Size(); i++) + if (faces.Get(i).Valid()) + { + int fused = 0; + for (j = 1; j <= 3; j++) + if (pingroup.Get(faces.Get(i).Face().PNum(j))) + fused++; + + if (fused >= 2) + { + groupelements.Append (faces.Get(i).Face()); + findex.Append (i); + } + } + + for (i = 1; i <= groupelements.Size(); i++) + for (j = 1; j <= 3; j++) + { + groupelements.Elem(i).PNum(j) = + invpindex.Get(groupelements.Elem(i).PNum(j)); + } + + /* + for (i = 1; i <= groupelements.Size(); i++) + for (j = 1; j <= 3; j++) + for (k = 1; k <= grouppoints.Size(); k++) + if (pindex.Get(k) == groupelements.Get(i).PNum(j)) + { + groupelements.Elem(i).PNum(j) = k; + break; + } + */ +} + + +void AdFront3 :: SetStartFront (int /* baseelnp */) +{ + INDEX i; + int j; + + for (i = 1; i <= faces.Size(); i++) + if (faces.Get(i).Valid()) + { + const MiniElement2d & face = faces.Get(i).Face(); + for (j = 1; j <= 3; j++) + points[face.PNum(j)].DecFrontNr(0); + } + + /* + if (baseelnp) + { + for (i = 1; i <= faces.Size(); i++) + if (faces.Get(i).Valid() && faces.Get(i).Face().GetNP() != baseelnp) + faces.Elem(i).qualclass = 1000; + } + */ +} + + +bool AdFront3 :: Inside (const Point<3> & p) const +{ + int cnt; + Vec3d n, v1, v2; + DenseMatrix a(3), ainv(3); + Vector b(3), u(3); + + // random numbers: + n.X() = 0.123871; + n.Y() = 0.15432; + n.Z() = -0.43989; + + cnt = 0; + for (int i = 1; i <= faces.Size(); i++) + if (faces.Get(i).Valid()) + { + const Point<3> & p1 = points[faces.Get(i).Face().PNum(1)].P(); + const Point<3> & p2 = points[faces.Get(i).Face().PNum(2)].P(); + const Point<3> & p3 = points[faces.Get(i).Face().PNum(3)].P(); + + v1 = p2 - p1; + v2 = p3 - p1; + + a(0, 0) = v1.X(); + a(1, 0) = v1.Y(); + a(2, 0) = v1.Z(); + a(0, 1) = v2.X(); + a(1, 1) = v2.Y(); + a(2, 1) = v2.Z(); + a(0, 2) = -n.X(); + a(1, 2) = -n.Y(); + a(2, 2) = -n.Z(); + + b(0) = p(0) - p1(0); + b(1) = p(1) - p1(1); + b(2) = p(2) - p1(2); + + CalcInverse (a, ainv); + ainv.Mult (b, u); + + if (u(0) >= 0 && u(1) >= 0 && u(0)+u(1) <= 1 && + u(2) > 0) + { + cnt++; + } + } + + return ((cnt % 2) != 0); +} + + + + + +int AdFront3 :: SameSide (const Point<3> & lp1, const Point<3> & lp2, + const Array * testfaces) const +{ + const Point<3> *line[2]; + line[0] = &lp1; + line[1] = &lp2; + + + Point3d pmin(lp1); + Point3d pmax(lp1); + pmin.SetToMin (lp2); + pmax.SetToMax (lp2); + + ArrayMem aprif; + aprif.SetSize(0); + + if (!testfaces) + facetree->GetIntersecting (pmin, pmax, aprif); + else + for (int i = 1; i <= testfaces->Size(); i++) + aprif.Append (testfaces->Get(i)); + + int cnt = 0; + for (int ii = 1; ii <= aprif.Size(); ii++) + { + int i = aprif.Get(ii); + + if (faces.Get(i).Valid()) + { + const Point<3> *tri[3]; + tri[0] = &points[faces.Get(i).Face().PNum(1)].P(); + tri[1] = &points[faces.Get(i).Face().PNum(2)].P(); + tri[2] = &points[faces.Get(i).Face().PNum(3)].P(); + + if (IntersectTriangleLine (&tri[0], &line[0])) + cnt++; + } + } + + return ((cnt+1) % 2); +} +} diff --git a/libsrc/meshing/adfront3.hpp b/libsrc/meshing/adfront3.hpp new file mode 100644 index 00000000..11993733 --- /dev/null +++ b/libsrc/meshing/adfront3.hpp @@ -0,0 +1,320 @@ +#ifndef FILE_ADFRONT3 +#define FILE_ADFRONT3 + +/**************************************************************************/ +/* File: adfront3.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Okt. 95 */ +/**************************************************************************/ + +/* + Advancing front class for volume meshing +*/ + + + +/// Point in advancing front +class FrontPoint3 +{ + /// coordinates +Point<3> p; + /// global node index +PointIndex globalindex; + /// number of faces connected to point +int nfacetopoint; + /// distance to original boundary +int frontnr; + /// +int cluster; +public: + /// + FrontPoint3 (); + /// + FrontPoint3 (const Point<3> & ap, PointIndex agi); + + /// + const Point<3> & P () const + { return p; } + /// + PointIndex GlobalIndex () const + { return globalindex; } + + /// + void AddFace () + { nfacetopoint++; } + + /// + void RemoveFace() + { + nfacetopoint--; + if (nfacetopoint == 0) nfacetopoint = -1; + } + + /// + int Valid () const + { return nfacetopoint >= 0; } + + /// + void DecFrontNr (int afrontnr) + { + if (frontnr > afrontnr) frontnr = afrontnr; + } + + /// + int FrontNr () const + { return frontnr; } + + /// + friend class AdFront3; +}; + + + +class MiniElement2d +{ +protected: + int np; + PointIndex pnum[4]; + bool deleted; +public: + MiniElement2d () + { np = 3; deleted = 0; } + MiniElement2d (int anp) + { np = anp; deleted = 0; } + + int GetNP() const { return np; } + PointIndex & operator[] (int i) { return pnum[i]; } + const PointIndex operator[] (int i) const { return pnum[i]; } + + const PointIndex PNum (int i) const { return pnum[i-1]; } + PointIndex & PNum (int i) { return pnum[i-1]; } + const PointIndex PNumMod (int i) const { return pnum[(i-1)%np]; } + + void Delete () { deleted = 1; pnum[0] = pnum[1] = pnum[2] = pnum[3] = PointIndex::BASE-1; } + bool IsDeleted () const { return deleted; } +}; + + +inline ostream & operator<<(ostream & s, const MiniElement2d & el) +{ + s << "np = " << el.GetNP(); + for (int j = 0; j < el.GetNP(); j++) + s << " " << el[j]; + return s; +} + + + + +/// Face in advancing front +class FrontFace +{ +private: + /// + MiniElement2d f; + /// + int qualclass; + /// + char oldfront; + /// + int hashvalue; + /// + int cluster; + +public: + /// + FrontFace (); + /// + FrontFace (const MiniElement2d & af); + /// + const MiniElement2d & Face () const + { return f; } + + /// + int QualClass () const + { return qualclass; } + + /// + void IncrementQualClass () + { qualclass++; } + + /// + void ResetQualClass () + { + if (qualclass > 1) + { + qualclass = 1; + oldfront = 0; + } + } + + /// + bool Valid () const + { return !f.IsDeleted(); } + + /// + void Invalidate (); + + /// + int HashValue() const + { return hashvalue; } + + /// + void SetHashValue(int hv) + { hashvalue = hv; } + + /// + friend class AdFront3; + + int Cluster () const { return cluster; } +}; + + + + +/// Advancing front, 3D. +class AdFront3 +{ + /// + Array points; + /// +Array faces; + /// +Array delpointl; + + /// which points are connected to pi ? +TABLE * connectedpairs; + + /// number of total front faces; +int nff; + /// number of quads in front +int nff4; + + /// +double vol; + + /// +GeomSearch3d hashtable; + + /// +int hashon; + + /// +int hashcreated; + + /// counter for rebuilding internal tables +int rebuildcounter; + /// last base element +int lasti; + /// minimal selection-value of baseelements +int minval; + Array invpindex; + Array pingroup; + + /// +class Box3dTree * facetree; +public: + + /// + AdFront3 (); + /// + ~AdFront3 (); + /// + void GetPoints (Array > & apoints) const; + /// + int GetNP() const + { return points.Size(); } + /// + const Point<3> & GetPoint (PointIndex pi) const + { return points[pi].P(); } + /// + int GetNF() const + { return nff; } + /// + const MiniElement2d & GetFace (int i) const + { return faces.Get(i).Face(); } + /// + void Print () const; + /// + bool Empty () const + { return nff == 0; } + /// + bool Empty (int elnp) const + { + if (elnp == 4) + return (nff4 == 0); + return (nff - nff4 == 0); + } + /// + int SelectBaseElement (); + + /// + void CreateTrees (); + + /// + void GetIntersectingFaces (const Point<3> & pmin, const Point<3> & pmax, + Array & ifaces) const; + + /// + void GetFaceBoundingBox (int i, Box3d & box) const; + + /// + int GetLocals (int baseelement, + Array & locpoints, + Array & locfaces, // local index + Array & pindex, + Array & findex, + INDEX_2_HASHTABLE & connectedpairs, + float xh, + float relh, + INDEX& facesplit); + + /// + void GetGroup (int fi, + Array & grouppoints, + Array & groupelements, + Array & pindex, + Array & findex); + + /// + void DeleteFace (INDEX fi); + /// + PointIndex AddPoint (const Point<3> & p, PointIndex globind); + /// + INDEX AddFace (const MiniElement2d & e); + /// + INDEX AddConnectedPair (const INDEX_2 & pair); + /// + void IncrementClass (INDEX fi) + { faces.Elem(fi).IncrementQualClass(); } + + /// + void ResetClass (INDEX fi) + { faces.Elem(fi).ResetQualClass(); } + + /// + void SetStartFront (int baseelnp = 0); + + /// is Point p inside Surface ? + bool Inside (const Point<3> & p) const; + /// both points on same side ? + int SameSide (const Point<3> & lp1, const Point<3> & lp2, + const Array * testfaces = NULL) const; + + + /// + PointIndex GetGlobalIndex (PointIndex pi) const + { return points[pi].GlobalIndex(); } + /// + double Volume () const + { return vol; } + + +private: + void RebuildInternalTables(); +}; + + + + +#endif diff --git a/libsrc/meshing/basegeom.cpp b/libsrc/meshing/basegeom.cpp new file mode 100644 index 00000000..11075f68 --- /dev/null +++ b/libsrc/meshing/basegeom.cpp @@ -0,0 +1,67 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + + DLL_HEADER GeometryRegisterArray geometryregister; + //DLL_HEADER Array geometryregister; + + GeometryRegister :: ~GeometryRegister() + { ; } + + + + + + int NetgenGeometry :: GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend) + { + if (!mesh) return 1; + + if (perfstepsstart <= MESHCONST_MESHVOLUME) + { + multithread.task = "Volume meshing"; + + MESHING3_RESULT res = + MeshVolume (mparam, *mesh); + + if (res != MESHING3_OK) return 1; + + if (multithread.terminate) return 0; + + RemoveIllegalElements (*mesh); + if (multithread.terminate) return 0; + + MeshQuality3d (*mesh); + } + + + if (multithread.terminate || perfstepsend <= MESHCONST_MESHVOLUME) + return 0; + + + if (perfstepsstart <= MESHCONST_OPTVOLUME) + { + multithread.task = "Volume optimization"; + + OptimizeVolume (mparam, *mesh); + if (multithread.terminate) return 0; + } + + return 0; + } + + + const Refinement & NetgenGeometry :: GetRefinement () const + { + return *new Refinement;; + } + + + void NetgenGeometry :: Save (string filename) const + { + throw NgException("Cannot save geometry - no geometry available"); + } + +} diff --git a/libsrc/meshing/basegeom.hpp b/libsrc/meshing/basegeom.hpp new file mode 100644 index 00000000..eb849657 --- /dev/null +++ b/libsrc/meshing/basegeom.hpp @@ -0,0 +1,61 @@ +#ifndef FILE_BASEGEOM +#define FILE_BASEGEOM + +/**************************************************************************/ +/* File: basegeom.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 23. Aug. 09 */ +/**************************************************************************/ + + +struct Tcl_Interp; + +namespace netgen +{ + + class DLL_HEADER NetgenGeometry + { + public: + virtual ~NetgenGeometry () { ; } + + virtual int GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend); + + virtual const Refinement & GetRefinement () const; + + virtual void Save (string filename) const; + virtual void SaveToMeshFile (ostream & /* ost */) const { ; } + }; + + + + + + class DLL_HEADER GeometryRegister + { + public: + virtual ~GeometryRegister(); + virtual NetgenGeometry * Load (string filename) const = 0; + virtual NetgenGeometry * LoadFromMeshFile (istream & /* ist */) const { return NULL; } + virtual class VisualScene * GetVisualScene (const NetgenGeometry * /* geom */) const + { return NULL; } + virtual void SetParameters (Tcl_Interp * /* interp */) { ; } + }; + + class DLL_HEADER GeometryRegisterArray : public Array + { + public: + virtual ~GeometryRegisterArray() + { + for (int i = 0; i < Size(); i++) + delete (*this)[i]; + } + }; + + // extern DLL_HEADER Array geometryregister; + extern DLL_HEADER GeometryRegisterArray geometryregister; +} + + + +#endif diff --git a/libsrc/meshing/bcfunctions.cpp b/libsrc/meshing/bcfunctions.cpp new file mode 100644 index 00000000..1bab1b75 --- /dev/null +++ b/libsrc/meshing/bcfunctions.cpp @@ -0,0 +1,468 @@ + +#include +#include + + +namespace netgen +{ + // Default colour to be used for boundary condition number "0" + #define DEFAULT_R 0.0 + #define DEFAULT_G 1.0 + #define DEFAULT_B 0.0 + + // Boundary condition number to use if a face does not have a + // colour assigned to it, or if the colour is the above defined + // default colour + #define DEFAULT_BCNUM 1 + + // Default tolerance for colour matching (using Euclidean distance) + #define DEFAULT_EPS 2.5e-05 + + + + + /*! Philippose - 11/07/2009 + Function to check if two RGB colours are equal + + Note#1: Currently uses unweighted Euclidean Distance + for colour matching. + + Note#2: The tolerance used for deciding whether two + colours match is defined as "eps" and is currently + 2.5e-5 (for square of distance) + */ + bool ColourMatch(Vec3d col1, Vec3d col2, double eps = DEFAULT_EPS) + { + if(eps <= 0.0) eps = DEFAULT_EPS; + + bool colmatch = false; + + if(Dist2(col1,col2) < eps) colmatch = true; + + return colmatch; + } + + + + + + /*! Philippose - 11/07/2009 + Function to create a list of all the unique colours + available in a given mesh + */ + void GetFaceColours(Mesh & mesh, Array & face_colours) + { + face_colours.SetSize(1); + face_colours.Elem(1) = mesh.GetFaceDescriptor(1).SurfColour(); + + for(int i = 1; i <= mesh.GetNFD(); i++) + { + Vec3d face_colour = mesh.GetFaceDescriptor(i).SurfColour(); + bool col_found = false; + + for(int j = 1; j <= face_colours.Size(); j++) + { + if(ColourMatch(face_colours.Elem(j),face_colour)) + { + col_found = true; + break; + } + } + + if(!col_found) face_colours.Append(face_colour); + } + + if(printmessage_importance >= 3) + { + cout << endl << "-------- Face Colours --------" << endl; + for( int i = 1; i <= face_colours.Size(); i++) + { + cout << face_colours.Elem(i) << endl; + } + cout << "------------------------------" << endl; + } + } + + + + + + + /*! Philippose - 11/07/2009 + Assign boundary condition numbers based on a user defined + colour profile file. + + The default profile file is "netgen.ocf" + + If the mesh contains colours not defined in the profile, + netgen automatically starts assigning each new colour a + new boundary condition number starting from the highest + boundary condition number specified in the profile file. + */ + void AutoColourAlg_UserProfile(Mesh & mesh, ifstream & ocf) + { + char ocf_inp[100]; + bool header_found = false; + + // Number of colour specifications in the + // user profile file + int numentries = 0; + while((ocf.good()) && (!header_found)) + { + ocf >> ocf_inp; + if(strcmp(ocf_inp,"boundary_colours") == 0) header_found = true; + } + + if(!header_found) + { + ocf.close(); + throw NgException("AutoColourAlg_UserProfile: Invalid or empty Boundary Colour Profile file\n"); + return; + } + + // Read in the number of entries from file + ocf >> numentries; + if(numentries > 0) + { + if(!ocf.good()) + { + ocf.close(); + throw NgException("AutoColourAlg_UserProfile: Invalid or empty Boundary Colour Profile file\n"); + return; + } + + PrintMessage(3, "Number of colour entries: ", numentries); + } + else + { + ocf.close(); + PrintMessage(3, "AutoColourAlg_UserProfile: No Boundary Colour entries found.... no changes made!"); + return; + } + + // Arrays to hold the specified RGB colour triplets as well + // as the associated boundary condition number + Array bc_colours(numentries); + Array bc_num(numentries); + Array bc_used(numentries); + + // Actually read in the data from the file + for(int i = 1; i <= numentries; i++) + { + int bcnum; + // double col_red, col_green, col_blue; + + ocf >> bcnum; + // Boundary condition number DEFAULT_BCNUM is reserved for + // faces which have the default colour Green (0.0,1.0,0.0) + // To prevent confusion, no boundary numbery below this default + // are permitted + if(bcnum < (DEFAULT_BCNUM + 1)) bcnum = DEFAULT_BCNUM+1; + + bc_num.Elem(i) = bcnum; + bc_used.Elem(i) = false; + ocf >> bc_colours.Elem(i).X() + >> bc_colours.Elem(i).Y() + >> bc_colours.Elem(i).Z(); + + if(!ocf.good()) + { + ocf.close(); + throw NgException("Boundary Colour file error: Number of entries do not match specified list size!!\n"); + return; + } + + // Bound checking of the values + // The RGB values should be between 0.0 and 1.0 + if(bc_colours.Elem(bcnum).X() < 0.0) bc_colours.Elem(bcnum).X() = 0.0; + if(bc_colours.Elem(bcnum).X() > 1.0) bc_colours.Elem(bcnum).X() = 1.0; + if(bc_colours.Elem(bcnum).Y() < 0.0) bc_colours.Elem(bcnum).X() = 0.0; + if(bc_colours.Elem(bcnum).Y() > 1.0) bc_colours.Elem(bcnum).X() = 1.0; + if(bc_colours.Elem(bcnum).Z() < 0.0) bc_colours.Elem(bcnum).X() = 0.0; + if(bc_colours.Elem(bcnum).Z() > 1.0) bc_colours.Elem(bcnum).X() = 1.0; + } + + PrintMessage(3, "Successfully loaded Boundary Colour Profile file...."); + ocf.close(); + + // Find the highest boundary condition number in the list + // All colours in the geometry which are not specified in the + // list will be given boundary condition numbers higher than this + // number + int max_bcnum = DEFAULT_BCNUM; + for(int i = 1; i <= bc_num.Size();i++) + { + if(bc_num.Elem(i) > max_bcnum) max_bcnum = bc_num.Elem(i); + } + + PrintMessage(3, "Highest boundary number in list = ",max_bcnum); + + Array all_colours; + + // Extract all the colours to see how many there are + GetFaceColours(mesh,all_colours); + PrintMessage(3,"\nNumber of colours defined in Mesh: ", all_colours.Size()); + + if(all_colours.Size() == 0) + { + PrintMessage(3,"No colour data detected in Mesh... no changes made!"); + return; + } + + int nfd = mesh.GetNFD(); + + for(int face_index = 1; face_index <= nfd; face_index++) + { + // Temporary container for individual face colours + Vec3d face_colour; + + // Get the colour of the face being currently processed + face_colour = mesh.GetFaceDescriptor(face_index).SurfColour(); + if(!ColourMatch(face_colour,Vec3d(DEFAULT_R,DEFAULT_G,DEFAULT_B))) + { + // Boolean variable to check if the boundary condition was applied + // or not... not applied would imply that the colour of the face + // does not exist in the list of colours in the profile file + bool bc_assigned = false; + + for(int col_index = 1; col_index <= bc_colours.Size(); col_index++) + { + if((ColourMatch(face_colour,bc_colours.Elem(col_index))) && (!bc_assigned)) + { + mesh.GetFaceDescriptor(face_index).SetBCProperty(bc_num.Elem(col_index)); + bc_used.Elem(col_index) = true; + bc_assigned = true; + break; + } + } + + // If the colour was not found in the list, add it to the list, and assign + // the next free boundary condition number to it + if(!bc_assigned) + { + max_bcnum++; + bc_num.Append(max_bcnum); + bc_colours.Append(face_colour); + bc_used.Append(true); + + mesh.GetFaceDescriptor(face_index).SetBCProperty(max_bcnum); + } + } + else + { + // Set the boundary condition number to the default one + mesh.GetFaceDescriptor(face_index).SetBCProperty(DEFAULT_BCNUM); + } + } + + // User Information of the results of the operation + Vec3d ref_colour(0.0,1.0,0.0); + PrintMessage(3,"Colour based Boundary Condition Property details:"); + for(int bc_index = 0; bc_index <= bc_num.Size(); bc_index++) + { + if(bc_index > 0) ref_colour = bc_colours.Elem(bc_index); + + if(bc_index == 0) + { + PrintMessage(3, "BC Property: ",DEFAULT_BCNUM); + PrintMessage(3, " RGB Face Colour = ",ref_colour,"","\n"); + } + else if(bc_used.Elem(bc_index)) + { + PrintMessage(3, "BC Property: ",bc_num.Elem(bc_index)); + PrintMessage(3, " RGB Face Colour = ",ref_colour,"","\n"); + } + } + } + + + + + + /*! Philippose - 11/07/2009 + Assign boundary condition numbers based on the colours + assigned to each face in the mesh using an automated + algorithm. + + The particular algorithm used has been briefly explained + in the header file "occauxfunctions.hpp" + */ + void AutoColourAlg_Sorted(Mesh & mesh) + { + Array all_colours; + Array faces_sorted; + Array colours_sorted; + + // Extract all the colours to see how many there are + GetFaceColours(mesh,all_colours); + + // Delete the default colour from the list since it will be accounted + // for automatically + for(int i = 1; i <= all_colours.Size(); i++) + { + if(ColourMatch(all_colours.Elem(i),Vec3d(DEFAULT_R,DEFAULT_G,DEFAULT_B))) + { + all_colours.DeleteElement(i); + break; + } + } + PrintMessage(3,"\nNumber of colours defined in Mesh: ", all_colours.Size()); + + if(all_colours.Size() == 0) + { + PrintMessage(3,"No colour data detected in Mesh... no changes made!"); + return; + } + + // One more slot than the number of colours are required, to + // account for individual faces which have no colour data + // assigned to them in the CAD software + faces_sorted.SetSize(all_colours.Size()+1); + colours_sorted.SetSize(all_colours.Size()+1); + faces_sorted = 0; + + // Slave Array to identify the colours the faces were assigned to, + // after the bubble sort routine to sort the automatic boundary + // identifiers according to the number of surface mesh elements + // of a given colour + for(int i = 0; i <= all_colours.Size(); i++) colours_sorted[i] = i; + + // Used to hold the number of surface elements without any OCC + // colour definition + int no_colour_faces = 0; + + // Index in the faces array assigned to faces without any + // or the default colour definition + int no_colour_index = 0; + + int nfd = mesh.GetNFD(); + + // Extract the number of surface elements having a given colour + // And save this number into an array for later sorting + for(int face_index = 1; face_index <= nfd; face_index++) + { + Array se_face; + + mesh.GetSurfaceElementsOfFace(face_index, se_face); + + Vec3d face_colour; + + face_colour = mesh.GetFaceDescriptor(face_index).SurfColour(); + if(!ColourMatch(face_colour,Vec3d(DEFAULT_R,DEFAULT_G,DEFAULT_B))) + { + for(int i = 1; i <= all_colours.Size(); i++) + { + if(ColourMatch(face_colour, all_colours.Elem(i))) + { + faces_sorted[i] = faces_sorted[i] + se_face.Size(); + } + } + } + else + { + // Add the number of surface elements without any colour + // definition separately + no_colour_faces = no_colour_faces + se_face.Size(); + } + } + + // Sort the face colour indices according to the number of surface + // mesh elements which have a specific colour + BubbleSort(faces_sorted,colours_sorted); + + // Now update the array position assigned for surface elements + // without any colour definition with the number of elements + faces_sorted[no_colour_index] = no_colour_faces; + + // Now actually assign the BC Property to the respective faces + for(int face_index = 1; face_index <= nfd; face_index++) + { + Vec3d face_colour; + + face_colour = mesh.GetFaceDescriptor(face_index).SurfColour(); + if(!ColourMatch(face_colour,Vec3d(DEFAULT_R,DEFAULT_G,DEFAULT_B))) + { + for(int i = 0; i < colours_sorted.Size(); i++) + { + Vec3d ref_colour; + if(i != no_colour_index) ref_colour = all_colours.Elem(colours_sorted[i]); + + if(ColourMatch(face_colour, ref_colour)) + { + mesh.GetFaceDescriptor(face_index).SetBCProperty(i + DEFAULT_BCNUM); + } + } + } + else + { + mesh.GetFaceDescriptor(face_index).SetBCProperty(DEFAULT_BCNUM); + } + + PrintMessage(4,"Face number: ",face_index," ; BC Property = ",mesh.GetFaceDescriptor(face_index).BCProperty()); + } + + // User Information of the results of the operation + Vec3d ref_colour(0.0,1.0,0.0); + PrintMessage(3,"Colour based Boundary Condition Property details:"); + for(int i = 0; i < faces_sorted.Size(); i++) + { + if(colours_sorted[i] > 0) ref_colour = all_colours.Elem(colours_sorted[i]); + + PrintMessage(3, "BC Property: ",i + DEFAULT_BCNUM); + PrintMessage(3, " Nr. of Surface Elements = ", faces_sorted[i]); + PrintMessage(3, " Colour Index = ", colours_sorted[i]); + PrintMessage(3, " RGB Face Colour = ",ref_colour,"","\n"); + } + } + + + + + + /*! Philippose - 13/07/2009 + Main function implementing automated assignment of + Boundary Condition numbers based on face colours + + This functionality is currently implemtented at the mesh + level, and hence allows colour based assignment of boundary + conditions for any geometry type within netgen which + supports face colours + */ + void AutoColourBcProps(Mesh & mesh, const char * bccolourfile) + { + // Go directly to the alternate algorithm if no colour profile file was specified + if(!bccolourfile) + { + PrintMessage(1,"AutoColourBcProps: Using Automatic Colour based boundary property assignment algorithm"); + AutoColourAlg_Sorted(mesh); + } + else + { + ifstream ocf(bccolourfile); + + // If there was an error opening the Colour profile file, jump to the alternate + // algorithm after printing a message + if(!ocf) + { + PrintMessage(1,"AutoColourBcProps: Error loading Boundary Colour Profile file ", + bccolourfile, " ....","Switching to Automatic Assignment algorithm!"); + + AutoColourAlg_Sorted(mesh); + } + // If the file opens successfully, call the function which assigns boundary conditions + // based on the colour profile file + else + { + PrintMessage(1, "AutoColourBcProps: Using Boundary Colour Profile file: "); + PrintMessage(1, " ", bccolourfile); + AutoColourAlg_UserProfile(mesh, ocf); + + // Make sure the file is closed before exiting the function + if(ocf.is_open()) + { + ocf.close(); + } + } + } + } +} diff --git a/libsrc/meshing/bcfunctions.hpp b/libsrc/meshing/bcfunctions.hpp new file mode 100644 index 00000000..593838af --- /dev/null +++ b/libsrc/meshing/bcfunctions.hpp @@ -0,0 +1,53 @@ +#ifndef FILE_BCFUNCTIONS +#define FILE_BCFUNCTIONS + +// Philippose - 14/03/2009 +// Auxiliary functions for OCC Geometry +// Use this file and the corresponding ".cpp" +// file to add miscellaneous functionality +// to the OpenCascade Geometry support in Netgen +namespace netgen +{ + /*! \brief Automatically assign boundary conditions for meshes + + This function allows the boundary condition numbers of a + mesh created in Netgen to be automatically assigned based on + the colours of each face. + + Currently, two algorithms are utilised to assign the BC Properties: + 1. Automatic assignment using a user defined colour profile file + which defines which RGB colours are to be assigned to which + BC Property number + - A default profile file exists in the Netgen folder called + "netgen.ocf" + + 2. The second algorithm uses the following automated algorithm: + - Extract all the colours present in the mesh + - Use colour index 0 (zero) for all faces with no colour defined + - Calculate the number of faces of the surface mesh for each colour + - Sort the number of surface elements in ascending order, with the + colour indices as a slave + - Use the indices of the sorted array as the BC property number + + Example: If there are 3 colours, present in the mesh and the number + of surface elements for each colour are: + - Colour 0: 8500 + - Colour 1: 120 + - Colour 2: 2200 + - Colour 3: 575 + + The above is sorted in ascending order and assigned as BC Properties: + - BC Prop 0: 120 : Colour 1 + - BC Prop 1: 575 : Colour 3 + - BC Prop 2: 2200 : Colour 2 + - BC Prop 3: 8500 : Colour 0 (no colour defined) + */ + //extern void OCCAutoColourBcProps(Mesh & mesh, OCCGeometry & occgeometry, const char *occcolourfile); + extern void AutoColourBcProps(Mesh & mesh, const char *bccolourfile); + + extern void GetFaceColours(Mesh & mesh, Array & face_colours); + + extern bool ColourMatch(Vec3d col1, Vec3d col2, double eps = 2.5e-05); +} +#endif + diff --git a/libsrc/meshing/bisect.cpp b/libsrc/meshing/bisect.cpp new file mode 100644 index 00000000..3da30ba6 --- /dev/null +++ b/libsrc/meshing/bisect.cpp @@ -0,0 +1,4046 @@ +#include +#include "meshing.hpp" + +#define noDEBUG + + +namespace netgen +{ + class MarkedTet; + class MarkedPrism; + class MarkedIdentification; + class MarkedTri; + class MarkedQuad; + + typedef Array T_MTETS; + typedef Array T_MPRISMS; + typedef Array T_MIDS; + typedef Array T_MTRIS; + typedef Array T_MQUADS; + + + + class MarkedTet + { + public: + /// pnums of tet + PointIndex pnums[4]; + /// material number + int matindex; + /// element marked for refinement + /// marked = 1: marked by element marker, marked = 2 due to closure + unsigned int marked:2; + /// flag of Arnold-Mukherjee algorithm + unsigned int flagged:1; + /// tetedge (local coordinates 0..3) + unsigned int tetedge1:3; + unsigned int tetedge2:3; + // marked edge of faces + // face_j : face without node j, + // mark_k : edge without node k + + char faceedges[4]; + // unsigned char faceedges[4]; + bool incorder; + unsigned int order:6; + + MarkedTet() + { + for (int i = 0; i < 4; i++) { faceedges[i] = 255; } + } + }; + + ostream & operator<< (ostream & ost, const MarkedTet & mt) + { + for(int i=0; i<4; i++) + ost << mt.pnums[i] << " "; + + ost << mt.matindex << " " << int(mt.marked) << " " << int(mt.flagged) << " " << int(mt.tetedge1) << " " << int(mt.tetedge2) << " "; + + ost << "faceedges = "; + for(int i=0; i<4; i++) + ost << int(mt.faceedges[i]) << " "; + + ost << " order = "; + ost << mt.incorder << " " << int(mt.order) << "\n"; + return ost; + } + istream & operator>> (istream & ost, MarkedTet & mt) + { + for(int i=0; i<4; i++) + ost >> mt.pnums[i]; + + ost >> mt.matindex; + + int auxint; + ost >> auxint; + mt.marked = auxint; + ost >> auxint; + mt.flagged = auxint; + ost >> auxint; + mt.tetedge1 = auxint; + ost >> auxint; + mt.tetedge2 = auxint; + + char auxchar; + + for(int i=0; i<4; i++) + { + ost >> auxchar; + mt.faceedges[i] = auxchar; + } + + ost >> mt.incorder; + ost >> auxint; + mt.order = auxint; + return ost; + } + + class MarkedPrism + { + public: + /// 6 point numbers + PointIndex pnums[6]; + /// material number + int matindex; + /// marked for refinement + int marked; + /// edge without node k (0,1,2) + int markededge; + + bool incorder; + unsigned int order:6; + }; + + + ostream & operator<< (ostream & ost, const MarkedPrism & mp) + { + for(int i=0; i<6; i++) + ost << mp.pnums[i] << " "; + + ost << mp.matindex << " " << mp.marked << " " << mp.markededge << " " << mp.incorder << " " << int(mp.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedPrism & mp) + { + for(int i=0; i<6; i++) + ist >> mp.pnums[i]; + + ist >> mp.matindex >> mp.marked >> mp.markededge >> mp.incorder; + int auxint; + ist >> auxint; + mp.order = auxint; + return ist; + } + + + class MarkedIdentification + { + public: + // number of points of one face (3 or 4) + int np; + /// 6 or 8 point numbers + PointIndex pnums[8]; + /// marked for refinement + int marked; + /// edge starting with node k (0,1,2, or 3) + int markededge; + + bool incorder; + unsigned int order:6; + }; + + + ostream & operator<< (ostream & ost, const MarkedIdentification & mi) + { + ost << mi.np << " "; + for(int i=0; i<2*mi.np; i++) + ost << mi.pnums[i] << " "; + ost << mi.marked << " " << mi.markededge << " " << mi.incorder << " " << int(mi.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedIdentification & mi) + { + ist >> mi.np; + for(int i=0; i<2*mi.np; i++) + ist >> mi.pnums[i]; + ist >> mi.marked >> mi.markededge >> mi.incorder; + int auxint; + ist >> auxint; + mi.order = auxint; + return ist; + } + + + + + + class MarkedTri + { + public: + /// three point numbers + PointIndex pnums[3]; + /// three geominfos + PointGeomInfo pgeominfo[3]; + /// marked for refinement + int marked; + /// edge without node k + int markededge; + /// surface id + int surfid; + + bool incorder; + unsigned int order:6; + }; + + ostream & operator<< (ostream & ost, const MarkedTri & mt) + { + for(int i=0; i<3; i++) + ost << mt.pnums[i] << " "; + for(int i=0; i<3; i++) + ost << mt.pgeominfo[i] << " "; + ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedTri & mt) + { + for(int i=0; i<3; i++) + ist >> mt.pnums[i]; + for(int i=0; i<3; i++) + ist >> mt.pgeominfo[i]; + ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder; + int auxint; + ist >> auxint; + mt.order = auxint; + return ist; + } + + + + class MarkedQuad + { + public: + /// point numbers + PointIndex pnums[4]; + /// + PointGeomInfo pgeominfo[4]; + /// marked for refinement + int marked; + /// marked edge: 0/2 = vertical, 1/3 = horizontal + int markededge; + /// surface id + int surfid; + + bool incorder; + unsigned int order:6; + }; + + ostream & operator<< (ostream & ost, const MarkedQuad & mt) + { + for(int i=0; i<4; i++) + ost << mt.pnums[i] << " "; + for(int i=0; i<4; i++) + ost << mt.pgeominfo[i] << " "; + ost << mt.marked << " " << mt.markededge << " " << mt.surfid << " " << mt.incorder << " " << int(mt.order) << "\n"; + return ost; + } + istream & operator>> (istream & ist, MarkedQuad & mt) + { + for(int i=0; i<4; i++) + ist >> mt.pnums[i]; + for(int i=0; i<4; i++) + ist >> mt.pgeominfo[i]; + ist >> mt.marked >> mt.markededge >> mt.surfid >> mt.incorder; + int auxint; + ist >> auxint; + mt.order = auxint; + return ist; + } + + + + + void PrettyPrint(ostream & ost, const MarkedTet & mt) + { + int te1 = mt.tetedge1; + int te2 = mt.tetedge2; + int order = mt.order; + + ost << "MT: " << mt.pnums[0] << " - " << mt.pnums[1] << " - " + << mt.pnums[2] << " - " << mt.pnums[3] << endl + << "marked edge: " << te1 << " - " << te2 + << ", order = " << order << endl; + //for (int k = 0; k < 4; k++) + // ost << int(mt.faceedges[k]) << " "; + for (int k = 0; k < 4; k++) + { + ost << "face"; + for (int j=0; j<4; j++) + if(j != k) + ost << " " << mt.pnums[j]; + for(int i=0; i<3; i++) + for(int j=i+1; j<4; j++) + if(i != k && j != k && int(mt.faceedges[k]) == 6-k-i-j) + ost << " marked edge " << mt.pnums[i] << " " << mt.pnums[j] << endl; + } + ost << endl; + } + + + + + int BTSortEdges (const Mesh & mesh, + const Array< Array* > & idmaps, + INDEX_2_CLOSED_HASHTABLE & edgenumber) + { + PrintMessage(4,"sorting ... "); + + // if (mesh.PureTetMesh()) + if (1) + { + // new, fast version + + Array edges; + Array eclasses; + + int i, j, k; + int cntedges = 0; + int go_on; + int ned(0); + + // enumerate edges: + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement (i); + static int tetedges[6][2] = + { { 1, 2 }, + { 1, 3 }, + { 1, 4 }, + { 2, 3 }, + { 2, 4 }, + { 3, 4 } } ; + static int prismedges[9][2] = + { { 1, 2 }, + { 1, 3 }, + { 2, 3 }, + { 4, 5 }, + { 4, 6 }, + { 5, 6 }, + { 1, 4 }, + { 2, 5 }, + { 3, 6 } }; + int pyramidedges[6][2] = + { { 1, 2 }, + { 3, 4 }, + { 1, 5 }, + { 2, 5 }, + { 3, 5 }, + { 4, 5 } }; + + int (*tip)[2] = NULL; + + switch (el.GetType()) + { + case TET: + case TET10: + { + tip = tetedges; + ned = 6; + break; + } + case PRISM: + case PRISM12: + { + tip = prismedges; + ned = 6; + break; + } + case PYRAMID: + { + tip = pyramidedges; + ned = 6; + break; + } + default: + throw NgException("Bisect, element type not handled in switch"); + } + + for (j = 0; j < ned; j++) + { + INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1])); + i2.Sort(); + //(*testout) << "edge " << i2 << endl; + if (!edgenumber.Used(i2)) + { + cntedges++; + edges.Append (i2); + edgenumber.Set(i2, cntedges); + } + } + } + + // additional surface edges: + for (i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & el = mesh.SurfaceElement (i); + static int trigedges[3][2] = + { { 1, 2 }, + { 2, 3 }, + { 3, 1 } }; + + static int quadedges[4][2] = + { { 1, 2 }, + { 2, 3 }, + { 3, 4 }, + { 4, 1 } }; + + + int (*tip)[2] = NULL; + + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + tip = trigedges; + ned = 3; + break; + } + case QUAD: + case QUAD6: + { + tip = quadedges; + ned = 4; + break; + } + default: + { + cerr << "Error: Sort for Bisect, SE has " << el.GetNP() << " points" << endl; + ned = 0; + } + } + + for (j = 0; j < ned; j++) + { + INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1])); + i2.Sort(); + if (!edgenumber.Used(i2)) + { + cntedges++; + edges.Append (i2); + edgenumber.Set(i2, cntedges); + } + } + } + + + + + + eclasses.SetSize (cntedges); + for (i = 1; i <= cntedges; i++) + eclasses.Elem(i) = i; + + // identify edges in element stack + do + { + go_on = 0; + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement (i); + + if (el.GetType() != PRISM && + el.GetType() != PRISM12 && + el.GetType() != PYRAMID) + continue; + + int prismpairs[3][4] = + { { 1, 2, 4, 5 }, + { 2, 3, 5, 6 }, + { 1, 3, 4, 6 } }; + + int pyramidpairs[3][4] = + { { 1, 2, 4, 3 }, + { 1, 5, 4, 5 }, + { 2, 5, 3, 5 } }; + + int (*pairs)[4] = NULL; + switch (el.GetType()) + { + case PRISM: + case PRISM12: + { + pairs = prismpairs; + break; + } + case PYRAMID: + { + pairs = pyramidpairs; + break; + } + default: + throw NgException("Bisect, element type not handled in switch, 2"); + } + + for (j = 0; j < 3; j++) + { + INDEX_2 e1 (el.PNum(pairs[j][0]), + el.PNum(pairs[j][1])); + INDEX_2 e2 (el.PNum(pairs[j][2]), + el.PNum(pairs[j][3])); + e1.Sort(); + e2.Sort(); + + int eclass1 = edgenumber.Get (e1); + int eclass2 = edgenumber.Get (e2); + + // (*testout) << "identify edges " << eclass1 << "-" << eclass2 << endl; + + if (eclasses.Get(eclass1) > + eclasses.Get(eclass2)) + { + eclasses.Elem(eclass1) = + eclasses.Get(eclass2); + go_on = 1; + } + else if (eclasses.Get(eclass2) > + eclasses.Get(eclass1)) + { + eclasses.Elem(eclass2) = + eclasses.Get(eclass1); + go_on = 1; + } + } + } + + for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el2d = mesh[sei]; + + for(i = 0; i < el2d.GetNP(); i++) + { + INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]); + e1.Sort(); + INDEX_2 e2; + + for(k = 0; k < idmaps.Size(); k++) + { + e2.I1() = (*idmaps[k])[e1.I1()]; + e2.I2() = (*idmaps[k])[e1.I2()]; + + if(e2.I1() == 0 || e2.I2() == 0 || + e1.I1() == e2.I1() || e1.I2() == e2.I2()) + continue; + + e2.Sort(); + if(!edgenumber.Used(e2)) + continue; + + + int eclass1 = edgenumber.Get (e1); + int eclass2 = edgenumber.Get (e2); + + if (eclasses.Get(eclass1) > + eclasses.Get(eclass2)) + { + eclasses.Elem(eclass1) = + eclasses.Get(eclass2); + + + go_on = 1; + } + else if (eclasses.Get(eclass2) > + eclasses.Get(eclass1)) + { + eclasses.Elem(eclass2) = + eclasses.Get(eclass1); + go_on = 1; + } + } + } + + } + + } + while (go_on); + +// for (i = 1; i <= cntedges; i++) +// { +// (*testout) << "edge " << i << ": " +// << edges.Get(i).I1() << "-" << edges.Get(i).I2() +// << ", class = " << eclasses.Get(i) << endl; +// } + + // compute classlength: + Array edgelength(cntedges); + + /* + for (i = 1; i <= cntedges; i++) + edgelength.Elem(i) = 1e20; + */ + + for (i = 1; i <= cntedges; i++) + { + INDEX_2 edge = edges.Get(i); + double elen = Dist (mesh.Point(edge.I1()), + mesh.Point(edge.I2())); + edgelength.Elem (i) = elen; + } + + /* + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement (i); + + if (el.GetType() == TET) + { + for (j = 1; j <= 3; j++) + for (k = j+1; k <= 4; k++) + { + INDEX_2 i2(el.PNum(j), el.PNum(k)); + i2.Sort(); + + int enr = edgenumber.Get(i2); + double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); + if (elen < edgelength.Get(enr)) + edgelength.Set (enr, elen); + } + } + else if (el.GetType() == PRISM) + { + for (j = 1; j <= 3; j++) + { + k = (j % 3) + 1; + + INDEX_2 i2(el.PNum(j), el.PNum(k)); + i2.Sort(); + + int enr = edgenumber.Get(i2); + double elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); + if (elen < edgelength.Get(enr)) + edgelength.Set (enr, elen); + + i2 = INDEX_2(el.PNum(j+3), el.PNum(k+3)); + i2.Sort(); + + enr = edgenumber.Get(i2); + elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); + if (elen < edgelength.Get(enr)) + edgelength.Set (enr, elen); + + if (!edgenumber.Used(i2)) + { + cntedges++; + edgenumber.Set(i2, cntedges); + } + i2 = INDEX_2(el.PNum(j), el.PNum(j+3)); + i2.Sort(); + + enr = edgenumber.Get(i2); + elen = Dist (mesh.Point (i2.I1()), mesh.Point (i2.I2())); + if (elen < edgelength.Get(enr)) + edgelength.Set (enr, elen); + } + } + } + */ + + + for (i = 1; i <= cntedges; i++) + { + if (eclasses.Get(i) != i) + { + if (edgelength.Get(i) < edgelength.Get(eclasses.Get(i))) + edgelength.Elem(eclasses.Get(i)) = edgelength.Get(i); + edgelength.Elem(i) = 1e20; + } + } + + + TABLE eclasstab(cntedges); + for (i = 1; i <= cntedges; i++) + eclasstab.Add1 (eclasses.Get(i), i); + + + // sort edges: + Array sorted(cntedges); + + QuickSort (edgelength, sorted); + + int cnt = 0; + for (i = 1; i <= cntedges; i++) + { + int ii = sorted.Get(i); + for (j = 1; j <= eclasstab.EntrySize(ii); j++) + { + cnt++; + edgenumber.Set (edges.Get(eclasstab.Get(ii, j)), cnt); + } + } + return cnt; + } + + else + + { + // old version + + int i, j; + int cnt = 0; + int found; + double len2, maxlen2; + INDEX_2 ep; + + // sort edges by length, parallel edges (on prisms) + // are added in blocks + + do + { + found = 0; + maxlen2 = 1e30; + + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement (i); + int ned; + int tetedges[6][2] = + { { 1, 2 }, + { 1, 3 }, + { 1, 4 }, + { 2, 3 }, + { 2, 4 }, + { 3, 4 } }; + int prismedges[6][2] = + { { 1, 2 }, + { 1, 3 }, + { 2, 4 }, + { 4, 5 }, + { 4, 6 }, + { 5, 6 } }; + int pyramidedges[6][2] = + { { 1, 2 }, + { 3, 4 }, + { 1, 5 }, + { 2, 5 }, + { 3, 5 }, + { 4, 5 } }; + + int (*tip)[2]; + + switch (el.GetType()) + { + case TET: + { + tip = tetedges; + ned = 6; + break; + } + case PRISM: + { + tip = prismedges; + ned = 6; + break; + } + case PYRAMID: + { + tip = pyramidedges; + ned = 6; + break; + } + default: + throw NgException("Bisect, element type not handled in switch, 3"); + } + + for (j = 0; j < ned; j++) + { + INDEX_2 i2(el.PNum(tip[j][0]), el.PNum(tip[j][1])); + i2.Sort(); + if (!edgenumber.Used(i2)) + { + len2 = Dist (mesh.Point (i2.I1()), + mesh.Point (i2.I2())); + if (len2 < maxlen2) + { + maxlen2 = len2; + ep = i2; + found = 1; + } + } + } + } + if (found) + { + cnt++; + edgenumber.Set (ep, cnt); + + + // find connected edges: + int go_on = 0; + do + { + go_on = 0; + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement (i); + if (el.GetNP() != 6) continue; + + int prismpairs[3][4] = + { { 1, 2, 4, 5 }, + { 2, 3, 5, 6 }, + { 1, 3, 4, 6 } }; + + int pyramidpairs[3][4] = + { { 1, 2, 4, 3 }, + { 1, 5, 4, 5 }, + { 2, 5, 3, 5 } }; + + int (*pairs)[4]; + switch (el.GetType()) + { + case PRISM: + { + pairs = prismpairs; + break; + } + case PYRAMID: + { + pairs = pyramidpairs; + break; + } + default: + throw NgException("Bisect, element type not handled in switch, 3a"); + } + + for (j = 0; j < 3; j++) + { + INDEX_2 e1 (el.PNum(pairs[j][0]), + el.PNum(pairs[j][1])); + INDEX_2 e2 (el.PNum(pairs[j][2]), + el.PNum(pairs[j][3])); + e1.Sort(); + e2.Sort(); + + int used1 = edgenumber.Used (e1); + int used2 = edgenumber.Used (e2); + + if (used1 && !used2) + { + cnt++; + edgenumber.Set (e2, cnt); + go_on = 1; + } + if (used2 && !used1) + { + cnt++; + edgenumber.Set (e1, cnt); + go_on = 1; + } + } + } + } + while (go_on); + } + } + while (found); + + return cnt; + } + } + + + + + void BTDefineMarkedTet (const Element & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + MarkedTet & mt) + { + for (int i = 0; i < 4; i++) + mt.pnums[i] = el[i]; + + mt.marked = 0; + mt.flagged = 0; + + mt.incorder = 0; + mt.order = 1; + + int val = 0; + // find marked edge of tet: + for (int i = 0; i < 3; i++) + for (int j = i+1; j < 4; j++) + { + INDEX_2 i2(mt.pnums[i], mt.pnums[j]); + i2.Sort(); + int hval = edgenumber.Get(i2); + if (hval > val) + { + val = hval; + mt.tetedge1 = i; + mt.tetedge2 = j; + } + } + + + // find marked edges of faces: + for (int k = 0; k < 4; k++) + { + val = 0; + for (int i = 0; i < 3; i++) + for (int j = i+1; j < 4; j++) + if (i != k && j != k) + { + INDEX_2 i2(mt.pnums[i], mt.pnums[j]); + i2.Sort(); + int hval = edgenumber.Get(i2); + if (hval > val) + { + val = hval; + int hi = 6 - k - i - j; + mt.faceedges[k] = char(hi); + } + } + } + } + + + + + void BTDefineMarkedPrism (const Element & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + MarkedPrism & mp) + { + if (el.GetType() == PRISM || + el.GetType() == PRISM12) + { + for (int i = 0; i < 6; i++) + mp.pnums[i] = el[i]; + } + else if (el.GetType() == PYRAMID) + { + static int map[6] = + { 1, 2, 5, 4, 3, 5 }; + for (int i = 0; i < 6; i++) + mp.pnums[i] = el.PNum(map[i]); + } + else if (el.GetType() == TET || + el.GetType() == TET10) + { + static int map[6] = + { 1, 4, 3, 2, 4, 3 }; + for (int i = 0; i < 6; i++) + mp.pnums[i] = el.PNum(map[i]); + + } + else + { + PrintSysError ("Define marked prism called for non-prism and non-pyramid"); + } + + + + mp.marked = 0; + + mp.incorder = 0; + mp.order = 1; + + int val = 0; + for (int i = 0; i < 2; i++) + for (int j = i+1; j < 3; j++) + { + INDEX_2 i2(mp.pnums[i], mp.pnums[j]); + i2.Sort(); + int hval = edgenumber.Get(i2); + if (hval > val) + { + val = hval; + mp.markededge = 3 - i - j; + } + } + } + + + + bool BTDefineMarkedId(const Element2d & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + const Array & idmap, + MarkedIdentification & mi) + { + + bool identified = true; + mi.np = el.GetNP(); + int min1(0),min2(0); + for(int j = 0; identified && j < mi.np; j++) + { + mi.pnums[j] = el[j]; + mi.pnums[j+mi.np] = idmap[el[j]]; + + if(j == 0 || el[j] < min1) + min1 = el[j]; + if(j == 0 || mi.pnums[j+mi.np] < min2) + min2 = mi.pnums[j+mi.np]; + + identified = (mi.pnums[j+mi.np] != 0 && mi.pnums[j+mi.np] != mi.pnums[j]); + } + + identified = identified && (min1 < min2); + + if(identified) + { + mi.marked = 0; + + mi.incorder = 0; + mi.order = 1; + + int val = 0; + for (int i = 0; i < mi.np; i++) + { + INDEX_2 i2(mi.pnums[i], mi.pnums[(i+1)%mi.np]); + i2.Sort(); + int hval = edgenumber.Get(i2); + if (hval > val) + { + val = hval; + mi.markededge = i; + } + } + } + + return identified; + } + + + void BTDefineMarkedTri (const Element2d & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + MarkedTri & mt) + { + for (int i = 0; i < 3; i++) + { + mt.pnums[i] = el[i]; + mt.pgeominfo[i] = el.GeomInfoPi (i+1); + } + + mt.marked = 0; + mt.surfid = el.GetIndex(); + + mt.incorder = 0; + mt.order = 1; + + int val = 0; + for (int i = 0; i < 2; i++) + for (int j = i+1; j < 3; j++) + { + INDEX_2 i2(mt.pnums[i], mt.pnums[j]); + i2.Sort(); + int hval = edgenumber.Get(i2); + if (hval > val) + { + val = hval; + mt.markededge = 3 - i - j; + } + } + } + + + + void PrettyPrint(ostream & ost, const MarkedTri & mt) + { + ost << "MarkedTrig: " << endl; + ost << " pnums = "; for (int i=0; i<3; i++) ost << mt.pnums[i] << " "; ost << endl; + ost << " marked = " << mt.marked << ", markededge=" << mt.markededge << endl; + for(int i=0; i<2; i++) + for(int j=i+1; j<3; j++) + if(mt.markededge == 3-i-j) + ost << " marked edge pnums = " << mt.pnums[i] << " " << mt.pnums[j] << endl; + } + + + void PrettyPrint(ostream & ost, const MarkedQuad & mq) + { + ost << "MarkedQuad: " << endl; + ost << " pnums = "; for (int i=0; i<4; i++) ost << mq.pnums[i] << " "; ost << endl; + ost << " marked = " << mq.marked << ", markededge=" << mq.markededge << endl; + } + + + + + + void BTDefineMarkedQuad (const Element2d & el, + INDEX_2_CLOSED_HASHTABLE & edgenumber, + MarkedQuad & mq) + { + for (int i = 0; i < 4; i++) + mq.pnums[i] = el[i]; + Swap (mq.pnums[2], mq.pnums[3]); + + mq.marked = 0; + mq.markededge = 0; + mq.surfid = el.GetIndex(); + } + + + + + // mark elements due to local h + int BTMarkTets (T_MTETS & mtets, + T_MPRISMS & mprisms, + const Mesh & mesh) + { + int marked = 0; + + int np = mesh.GetNP(); + Vector hv(np); + for (int i = 0; i < np; i++) + hv(i) = mesh.GetH (mesh.Point(i+1)); + + double hfac = 1; + + for (int step = 1; step <= 2; step++) + { + for (int i = 1; i <= mtets.Size(); i++) + { + double h = 0; + + for (int j = 0; j < 3; j++) + for (int k = j+1; k < 4; k++) + { + const Point<3> & p1 = mesh.Point (mtets.Get(i).pnums[j]); + const Point<3> & p2 = mesh.Point (mtets.Get(i).pnums[k]); + double hh = Dist2 (p1, p2); + if (hh > h) h = hh; + } + h = sqrt (h); + + double hshould = 1e10; + for (int j = 0; j < 4; j++) + { + double hi = hv (mtets.Get(i).pnums[j]-1); + if (hi < hshould) + hshould = hi; + } + + + if (step == 1) + { + if (h / hshould > hfac) + hfac = h / hshould; + } + else + { + if (h > hshould * hfac) + { + mtets.Elem(i).marked = 1; + marked = 1; + } + else + mtets.Elem(i).marked = 0; + } + + } + for (int i = 1; i <= mprisms.Size(); i++) + { + double h = 0; + + for (int j = 0; j < 2; j++) + for (int k = j+1; k < 3; k++) + { + const Point<3> & p1 = mesh.Point (mprisms.Get(i).pnums[j]); + const Point<3> & p2 = mesh.Point (mprisms.Get(i).pnums[k]); + double hh = Dist2 (p1, p2); + if (hh > h) h = hh; + } + h = sqrt (h); + + double hshould = 1e10; + for (int j = 0; j < 6; j++) + { + double hi = hv (mprisms.Get(i).pnums[j]-1); + if (hi < hshould) + hshould = hi; + } + + + if (step == 1) + { + if (h / hshould > hfac) + hfac = h / hshould; + } + else + { + if (h > hshould * hfac) + { + mprisms.Elem(i).marked = 1; + marked = 1; + } + else + mprisms.Elem(i).marked = 0; + } + + } + + + + if (step == 1) + { + if (hfac > 2) + hfac /= 2; + else + hfac = 1; + } + + } + return marked; + } + + + + + + + + + + + + + + + void BTBisectTet (const MarkedTet & oldtet, int newp, + MarkedTet & newtet1, MarkedTet & newtet2) + { +#ifdef DEBUG + *testout << "bisect tet " << oldtet << endl; +#endif + + + // points vis a vis from tet-edge + int vis1, vis2; + vis1 = 0; + while (vis1 == oldtet.tetedge1 || vis1 == oldtet.tetedge2) + vis1++; + vis2 = 6 - vis1 - oldtet.tetedge1 - oldtet.tetedge2; + + + + + + // is tet of type P ? + int istypep = 0; + for (int i = 0; i < 4; i++) + { + int cnt = 0; + for (int j = 0; j < 4; j++) + if (oldtet.faceedges[j] == i) + cnt++; + if (cnt == 3) + istypep = 1; + } + + + + for (int i = 0; i < 4; i++) + { + newtet1.pnums[i] = oldtet.pnums[i]; + newtet2.pnums[i] = oldtet.pnums[i]; + } + newtet1.flagged = istypep && !oldtet.flagged; + newtet2.flagged = istypep && !oldtet.flagged; + + int nm = oldtet.marked - 1; + if (nm < 0) nm = 0; + newtet1.marked = nm; + newtet2.marked = nm; + +#ifdef DEBUG + *testout << "newtet1,before = " << newtet1 << endl; + *testout << "newtet2,before = " << newtet2 << endl; +#endif + + for (int i = 0; i < 4; i++) + { + if (i == oldtet.tetedge1) + { + newtet2.pnums[i] = newp; + newtet2.faceedges[i] = oldtet.faceedges[i]; // inherited face + newtet2.faceedges[vis1] = i; // cut faces + newtet2.faceedges[vis2] = i; + + int j = 0; + while (j == i || j == oldtet.faceedges[i]) + j++; + int k = 6 - i - oldtet.faceedges[i] - j; + newtet2.tetedge1 = j; // tet-edge + newtet2.tetedge2 = k; + + // new face: + if (istypep && oldtet.flagged) + { + int hi = 6 - oldtet.tetedge1 - j - k; + newtet2.faceedges[oldtet.tetedge2] = char(hi); + } + else + newtet2.faceedges[oldtet.tetedge2] = oldtet.tetedge1; + +#ifdef DEBUG + *testout << "i = " << i << ", j = " << j << " k = " << k + << " oldtet.tetedge1 = " << oldtet.tetedge1 + << " oldtet.tetedge2 = " << oldtet.tetedge2 + << " 6-oldtet.tetedge1-j-k = " << 6 - oldtet.tetedge1 - j - k + << " 6-oldtet.tetedge1-j-k = " << short(6 - oldtet.tetedge1 - j - k) + << endl; + *testout << "vis1 = " << vis1 << ", vis2 = " << vis2 << endl; + for (int j = 0; j < 4; j++) + if (newtet2.faceedges[j] > 3) + { + *testout << "ERROR1" << endl; + } +#endif + } + + if (i == oldtet.tetedge2) + { + newtet1.pnums[i] = newp; + newtet1.faceedges[i] = oldtet.faceedges[i]; // inherited face + newtet1.faceedges[vis1] = i; + newtet1.faceedges[vis2] = i; + int j = 0; + while (j == i || j == oldtet.faceedges[i]) + j++; + int k = 6 - i - oldtet.faceedges[i] - j; + newtet1.tetedge1 = j; + newtet1.tetedge2 = k; + + // new face: + if (istypep && oldtet.flagged) + { + int hi = 6 - oldtet.tetedge2 - j - k; + newtet1.faceedges[oldtet.tetedge1] = char(hi); + } + else + newtet1.faceedges[oldtet.tetedge1] = oldtet.tetedge2; + +#ifdef DEBUG + for (int j = 0; j < 4; j++) + if (newtet2.faceedges[j] > 3) + { + *testout << "ERROR2" << endl; + } +#endif + } + } + + newtet1.matindex = oldtet.matindex; + newtet2.matindex = oldtet.matindex; + newtet1.incorder = 0; + newtet1.order = oldtet.order; + newtet2.incorder = 0; + newtet2.order = oldtet.order; + + *testout << "newtet1 = " << newtet1 << endl; + *testout << "newtet2 = " << newtet2 << endl; + } + + + + + void BTBisectPrism (const MarkedPrism & oldprism, int newp1, int newp2, + MarkedPrism & newprism1, MarkedPrism & newprism2) + { + for (int i = 0; i < 6; i++) + { + newprism1.pnums[i] = oldprism.pnums[i]; + newprism2.pnums[i] = oldprism.pnums[i]; + } + + int pe1 = 0; + if (pe1 == oldprism.markededge) + pe1++; + int pe2 = 3 - oldprism.markededge - pe1; + + newprism1.pnums[pe2] = newp1; + newprism1.pnums[pe2+3] = newp2; + newprism1.markededge = pe2; + newprism2.pnums[pe1] = newp1; + newprism2.pnums[pe1+3] = newp2; + newprism2.markededge = pe1; + + newprism1.matindex = oldprism.matindex; + newprism2.matindex = oldprism.matindex; + + int nm = oldprism.marked - 1; + if (nm < 0) nm = 0; + newprism1.marked = nm; + newprism2.marked = nm; + + newprism1.incorder = 0; + newprism1.order = oldprism.order; + newprism2.incorder = 0; + newprism2.order = oldprism.order; + } + + + void BTBisectIdentification (const MarkedIdentification & oldid, + Array & newp, + MarkedIdentification & newid1, + MarkedIdentification & newid2) + { + for(int i=0; i<2*oldid.np; i++) + { + newid1.pnums[i] = oldid.pnums[i]; + newid2.pnums[i] = oldid.pnums[i]; + } + newid1.np = newid2.np = oldid.np; + + if(oldid.np == 3) + { + newid1.pnums[(oldid.markededge+1)%3] = newp[0]; + newid1.pnums[(oldid.markededge+1)%3+3] = newp[1]; + newid1.markededge = (oldid.markededge+2)%3; + + newid2.pnums[oldid.markededge] = newp[0]; + newid2.pnums[oldid.markededge+3] = newp[1]; + newid2.markededge = (oldid.markededge+1)%3; + } + else if(oldid.np == 4) + { + newid1.pnums[(oldid.markededge+1)%4] = newp[0]; + newid1.pnums[(oldid.markededge+2)%4] = newp[2]; + newid1.pnums[(oldid.markededge+1)%4+4] = newp[1]; + newid1.pnums[(oldid.markededge+2)%4+4] = newp[3]; + newid1.markededge = (oldid.markededge+3)%4; + + newid2.pnums[oldid.markededge] = newp[0]; + newid2.pnums[(oldid.markededge+3)%4] = newp[2]; + newid2.pnums[oldid.markededge+4] = newp[1]; + newid2.pnums[(oldid.markededge+3)%4+4] = newp[3]; + newid2.markededge = (oldid.markededge+1)%4; + } + + + int nm = oldid.marked - 1; + if (nm < 0) nm = 0; + newid1.marked = newid2.marked = nm; + + newid1.incorder = newid2.incorder = 0; + newid1.order = newid2.order = oldid.order; + } + + + + void BTBisectTri (const MarkedTri & oldtri, int newp, const PointGeomInfo & newpgi, + MarkedTri & newtri1, MarkedTri & newtri2) + { + for (int i = 0; i < 3; i++) + { + newtri1.pnums[i] = oldtri.pnums[i]; + newtri1.pgeominfo[i] = oldtri.pgeominfo[i]; + newtri2.pnums[i] = oldtri.pnums[i]; + newtri2.pgeominfo[i] = oldtri.pgeominfo[i]; + } + + int pe1 = 0; + if (pe1 == oldtri.markededge) + pe1++; + int pe2 = 3 - oldtri.markededge - pe1; + + newtri1.pnums[pe2] = newp; + newtri1.pgeominfo[pe2] = newpgi; + newtri1.markededge = pe2; + + newtri2.pnums[pe1] = newp; + newtri2.pgeominfo[pe1] = newpgi; + newtri2.markededge = pe1; + + + newtri1.surfid = oldtri.surfid; + newtri2.surfid = oldtri.surfid; + + int nm = oldtri.marked - 1; + if (nm < 0) nm = 0; + newtri1.marked = nm; + newtri2.marked = nm; + + newtri1.incorder = 0; + newtri1.order = oldtri.order; + newtri2.incorder = 0; + newtri2.order = oldtri.order; + } + + + void BTBisectQuad (const MarkedQuad & oldquad, + int newp1, const PointGeomInfo & npgi1, + int newp2, const PointGeomInfo & npgi2, + MarkedQuad & newquad1, MarkedQuad & newquad2) + { + for (int i = 0; i < 4; i++) + { + newquad1.pnums[i] = oldquad.pnums[i]; + newquad1.pgeominfo[i] = oldquad.pgeominfo[i]; + newquad2.pnums[i] = oldquad.pnums[i]; + newquad2.pgeominfo[i] = oldquad.pgeominfo[i]; + } + +/* if (oldquad.marked==1) // he/sz: 2d quads or 3d prism + { + newquad1.pnums[1] = newp1; + newquad1.pgeominfo[1] = npgi1; + newquad1.pnums[3] = newp2; + newquad1.pgeominfo[3] = npgi2; + + newquad2.pnums[0] = newp1; + newquad2.pgeominfo[0] = npgi1; + newquad2.pnums[2] = newp2; + newquad2.pgeominfo[2] = npgi2; + } + + else if (oldquad.marked==2) // he/sz: 2d quads only + { + newquad1.pnums[0] = newp1; + newquad1.pnums[1] = newp2; + newquad1.pnums[3] = oldquad.pnums[2]; + newquad1.pnums[2] = oldquad.pnums[0]; + newquad1.pgeominfo[0] = npgi1; + newquad1.pgeominfo[1] = npgi2; + newquad1.pgeominfo[3] = oldquad.pgeominfo[2]; + newquad1.pgeominfo[2] = oldquad.pgeominfo[0]; + + newquad2.pnums[0] = newp2; + newquad2.pnums[1] = newp1; + newquad2.pnums[3] = oldquad.pnums[1]; + newquad2.pnums[2] = oldquad.pnums[3]; + newquad2.pgeominfo[0] = npgi2; + newquad2.pgeominfo[1] = npgi1; + newquad2.pgeominfo[3] = oldquad.pgeominfo[1]; + newquad2.pgeominfo[2] = oldquad.pgeominfo[3]; + } + + */ + + if (oldquad.markededge==0 || oldquad.markededge==2) + { + newquad1.pnums[1] = newp1; + newquad1.pgeominfo[1] = npgi1; + newquad1.pnums[3] = newp2; + newquad1.pgeominfo[3] = npgi2; + + newquad2.pnums[0] = newp1; + newquad2.pgeominfo[0] = npgi1; + newquad2.pnums[2] = newp2; + newquad2.pgeominfo[2] = npgi2; + } + else // 1 || 3 + { + newquad1.pnums[2] = newp1; + newquad1.pgeominfo[2] = npgi1; + newquad1.pnums[3] = newp2; + newquad1.pgeominfo[3] = npgi2; + + newquad2.pnums[0] = newp1; + newquad2.pgeominfo[0] = npgi1; + newquad2.pnums[1] = newp2; + newquad2.pgeominfo[1] = npgi2; + } + newquad1.surfid = oldquad.surfid; + newquad2.surfid = oldquad.surfid; + + int nm = oldquad.marked - 1; + if (nm < 0) nm = 0; + + newquad1.marked = nm; + newquad2.marked = nm; + + if (nm==1) + { + newquad1.markededge=1; + newquad2.markededge=1; + } + else + { + newquad1.markededge=0; + newquad2.markededge=0; + } + + } + + + int MarkHangingIdentifications(T_MIDS & mids, + const INDEX_2_CLOSED_HASHTABLE & cutedges) + { + int hanging = 0; + for (int i = 1; i <= mids.Size(); i++) + { + if (mids.Elem(i).marked) + { + hanging = 1; + continue; + } + + const int np = mids.Get(i).np; + for(int j = 0; j < np; j++) + { + INDEX_2 edge1(mids.Get(i).pnums[j], + mids.Get(i).pnums[(j+1) % np]); + INDEX_2 edge2(mids.Get(i).pnums[j+np], + mids.Get(i).pnums[((j+1) % np) + np]); + + edge1.Sort(); + edge2.Sort(); + if (cutedges.Used (edge1) || + cutedges.Used (edge2)) + { + mids.Elem(i).marked = 1; + hanging = 1; + } + } + } + + return hanging; + } + + + /* + void IdentifyCutEdges(Mesh & mesh, + INDEX_2_CLOSED_HASHTABLE & cutedges) + { + int i,j,k; + + Array< Array* > idmaps; + for(i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + idmaps.Append(new Array); + mesh.GetIdentifications().GetMap(i,*idmaps.Last()); + } + + + + for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el2d = mesh[sei]; + + for(i = 0; i < el2d.GetNP(); i++) + { + INDEX_2 e1(el2d[i], el2d[(i+1) % el2d.GetNP()]); + e1.Sort(); + + if(!cutedges.Used(e1)) + continue; + + + for(k = 0; k < idmaps.Size(); k++) + { + INDEX_2 e2((*idmaps[k])[e1.I1()], + (*idmaps[k])[e1.I2()]); + + if(e2.I1() == 0 || e2.I2() == 0 || + e1.I1() == e2.I1() || e1.I2() == e2.I2()) + continue; + + e2.Sort(); + + if(cutedges.Used(e2)) + continue; + + Point3d np = Center(mesh.Point(e2.I1()), + mesh.Point(e2.I2())); + int newp = mesh.AddPoint(np); + cutedges.Set(e2,newp); + (*testout) << "DAAA" << endl; + } + } + } + + + for(i=0; i & cutedges) + { + int hanging = 0; + for (int i = 1; i <= mtets.Size(); i++) + { + MarkedTet & teti = mtets.Elem(i); + + if (teti.marked) + { + hanging = 1; + continue; + } + + for (int j = 0; j < 3; j++) + for (int k = j+1; k < 4; k++) + { + INDEX_2 edge(teti.pnums[j], + teti.pnums[k]); + edge.Sort(); + if (cutedges.Used (edge)) + { + teti.marked = 1; + hanging = 1; + } + } + } + + return hanging; + } + + + + int MarkHangingPrisms (T_MPRISMS & mprisms, + const INDEX_2_CLOSED_HASHTABLE & cutedges) + { + int hanging = 0; + for (int i = 1; i <= mprisms.Size(); i++) + { + if (mprisms.Elem(i).marked) + { + hanging = 1; + continue; + } + + for (int j = 0; j < 2; j++) + for (int k = j+1; k < 3; k++) + { + INDEX_2 edge1(mprisms.Get(i).pnums[j], + mprisms.Get(i).pnums[k]); + INDEX_2 edge2(mprisms.Get(i).pnums[j+3], + mprisms.Get(i).pnums[k+3]); + edge1.Sort(); + edge2.Sort(); + if (cutedges.Used (edge1) || + cutedges.Used (edge2)) + { + mprisms.Elem(i).marked = 1; + hanging = 1; + } + } + } + return hanging; + } + + + + int MarkHangingTris (T_MTRIS & mtris, + const INDEX_2_CLOSED_HASHTABLE & cutedges) + { + int hanging = 0; + for (int i = 1; i <= mtris.Size(); i++) + { + if (mtris.Get(i).marked) + { + hanging = 1; + continue; + } + for (int j = 0; j < 2; j++) + for (int k = j+1; k < 3; k++) + { + INDEX_2 edge(mtris.Get(i).pnums[j], + mtris.Get(i).pnums[k]); + edge.Sort(); + if (cutedges.Used (edge)) + { + mtris.Elem(i).marked = 1; + hanging = 1; + } + } + } + return hanging; + } + + + + int MarkHangingQuads (T_MQUADS & mquads, + const INDEX_2_CLOSED_HASHTABLE & cutedges) + { + int hanging = 0; + for (int i = 1; i <= mquads.Size(); i++) + { + if (mquads.Elem(i).marked) + { + hanging = 1; + continue; + } + + INDEX_2 edge1(mquads.Get(i).pnums[0], + mquads.Get(i).pnums[1]); + INDEX_2 edge2(mquads.Get(i).pnums[2], + mquads.Get(i).pnums[3]); + edge1.Sort(); + edge2.Sort(); + if (cutedges.Used (edge1) || + cutedges.Used (edge2)) + { + mquads.Elem(i).marked = 1; + mquads.Elem(i).markededge = 0; + hanging = 1; + continue; + } + + // he/sz: second case: split horizontally + INDEX_2 edge3(mquads.Get(i).pnums[1], + mquads.Get(i).pnums[3]); + INDEX_2 edge4(mquads.Get(i).pnums[2], + mquads.Get(i).pnums[0]); + + edge3.Sort(); + edge4.Sort(); + if (cutedges.Used (edge3) || + cutedges.Used (edge4)) + { + mquads.Elem(i).marked = 1; + mquads.Elem(i).markededge = 1; + hanging = 1; + continue; + } + + } + return hanging; + } + + + + void ConnectToNodeRec (int node, int tonode, + const TABLE & conto, Array & connecttonode) + { + // (*testout) << "connect " << node << " to " << tonode << endl; + for (int i = 1; i <= conto.EntrySize(node); i++) + { + int n2 = conto.Get(node, i); + if (!connecttonode.Get(n2)) + { + connecttonode.Elem(n2) = tonode; + ConnectToNodeRec (n2, tonode, conto, connecttonode); + } + } + } + + + + + T_MTETS mtets; + T_MPRISMS mprisms; + T_MIDS mids; + T_MTRIS mtris; + T_MQUADS mquads; + + + void WriteMarkedElements(ostream & ost) + { + ost << "Marked Elements\n"; + + ost << mtets.Size() << "\n"; + for(int i=0; i> auxstring; + + if(auxstring != "Marked") + return false; + + if(ist) + ist >> auxstring; + + if(auxstring != "Elements") + return false; + + int size; + + ist >> size; + mtets.SetSize(size); + for(int i=0; i> mtets[i]; + if(mtets[i].pnums[0] > mesh.GetNV() || + mtets[i].pnums[1] > mesh.GetNV() || + mtets[i].pnums[2] > mesh.GetNV() || + mtets[i].pnums[3] > mesh.GetNV()) + return false; + } + + ist >> size; + mprisms.SetSize(size); + for(int i=0; i> mprisms[i]; + + ist >> size; + mids.SetSize(size); + for(int i=0; i> mids[i]; + + ist >> size; + mtris.SetSize(size); + for(int i=0; i> mtris[i]; + + ist >> size; + mquads.SetSize(size); + for(int i=0; i> mquads[i]; + + return true; + } + + + + + + void BisectTetsCopyMesh (Mesh & mesh, const class CSGeometry *, + BisectionOptions & opt, + const Array< Array* > & idmaps, + const string & refinfofile) + { + // mtets.SetName ("bisection, tets"); + // mprisms.SetName ("bisection, prisms"); + // mtris.SetName ("bisection, trigs"); + // nmquads.SetName ("bisection, quads"); + // mids.SetName ("bisection, identifications"); + + //int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + + /* + if (mtets.Size() + mprisms.Size() == mesh.GetNE()) + return; + */ + + bool readok = false; + + if(refinfofile != "") + { + PrintMessage(3,"Reading marked-element information from \"",refinfofile,"\""); + ifstream ist(refinfofile.c_str()); + + readok = ReadMarkedElements(ist,mesh); + + ist.close(); + } + + if(!readok) + { + PrintMessage(3,"resetting marked-element information"); + mtets.SetSize(0); + mprisms.SetSize(0); + mids.SetSize(0); + mtris.SetSize(0); + mquads.SetSize(0); + + + INDEX_2_HASHTABLE shortedges(100); + for (int i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + if (el.GetType() == PRISM || + el.GetType() == PRISM12) + { + for (int j = 1; j <= 3; j++) + { + INDEX_2 se(el.PNum(j), el.PNum(j+3)); + se.Sort(); + shortedges.Set (se, 1); + } + } + } + + + + // INDEX_2_HASHTABLE edgenumber(np); + INDEX_2_CLOSED_HASHTABLE edgenumber(9*ne+4*nse); + + BTSortEdges (mesh, idmaps, edgenumber); + + + for (int i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + + switch (el.GetType()) + { + case TET: + case TET10: + { + // if tet has short edge, it is handled as degenerated prism + + int foundse = 0; + for (int j = 1; j <= 3; j++) + for (int k = j+1; k <= 4; k++) + { + INDEX_2 se(el.PNum(j), el.PNum(k)); + se.Sort(); + if (shortedges.Used (se)) + { + // cout << "tet converted to prism" << endl; + + foundse = 1; + int p3 = 1; + while (p3 == j || p3 == k) + p3++; + int p4 = 10 - j - k - p3; + + // even permutation ? + int pi[4]; + pi[0] = j; + pi[1] = k; + pi[2] = p3; + pi[3] = p4; + int cnt = 0; + for (int l = 1; l <= 4; l++) + for (int m = 0; m < 3; m++) + if (pi[m] > pi[m+1]) + { + Swap (pi[m], pi[m+1]); + cnt++; + } + if (cnt % 2) + Swap (p3, p4); + + Element hel = el; + hel.PNum(1) = el.PNum(j); + hel.PNum(2) = el.PNum(k); + hel.PNum(3) = el.PNum(p3); + hel.PNum(4) = el.PNum(p4); + + MarkedPrism mp; + BTDefineMarkedPrism (hel, edgenumber, mp); + mp.matindex = el.GetIndex(); + mprisms.Append (mp); + } + } + if (!foundse) + { + MarkedTet mt; + BTDefineMarkedTet (el, edgenumber, mt); + mt.matindex = el.GetIndex(); + mtets.Append (mt); + } + break; + } + case PYRAMID: + { + // eventually rotate + MarkedPrism mp; + + INDEX_2 se(el.PNum(1), el.PNum(2)); + se.Sort(); + if (shortedges.Used (se)) + { + Element hel = el; + hel.PNum(1) = el.PNum(2); + hel.PNum(2) = el.PNum(3); + hel.PNum(3) = el.PNum(4); + hel.PNum(4) = el.PNum(1); + BTDefineMarkedPrism (hel, edgenumber, mp); + } + else + { + BTDefineMarkedPrism (el, edgenumber, mp); + } + + mp.matindex = el.GetIndex(); + mprisms.Append (mp); + break; + } + case PRISM: + case PRISM12: + { + MarkedPrism mp; + BTDefineMarkedPrism (el, edgenumber, mp); + mp.matindex = el.GetIndex(); + mprisms.Append (mp); + break; + } + default: + throw NgException("Bisect, element type not handled in switch, 4"); + } + } + + for (int i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (el.GetType() == TRIG || + el.GetType() == TRIG6) + { + MarkedTri mt; + BTDefineMarkedTri (el, edgenumber, mt); + mtris.Append (mt); + } + else + { + MarkedQuad mq; + BTDefineMarkedQuad (el, edgenumber, mq); + mquads.Append (mq); + } + + MarkedIdentification mi; + for(int j=0; j0) + { + ostringstream str1,str2; + str1 << "copied " << mtets.Size() << " tets, " << mprisms.Size() << " prisms"; + str2 << " " << mtris.Size() << " trigs, " << mquads.Size() << " quads"; + + PrintMessage(4,str1.str()); + PrintMessage(4,str2.str()); + } + } + + + /* + void UpdateEdgeMarks2(Mesh & mesh, + const Array< Array* > & idmaps) + { + Array< Array*,PointIndex::BASE > mtets_old(mesh.GetNP()); + Array< Array*,PointIndex::BASE > mprisms_old(mesh.GetNP()); + Array< Array*,PointIndex::BASE > mids_old(mesh.GetNP()); + Array< Array*,PointIndex::BASE > mtris_old(mesh.GetNP()); + Array< Array*,PointIndex::BASE > mquads_old(mesh.GetNP()); + + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + for(int i=PointIndex::BASE; i; + + for(int i=0; iAppend(mtets[i]); + for(int i=0; iAppend(mprisms[i]); + for(int i=0; iAppend(mids[i]); + for(int i=0; iAppend(mtris[i]); + } + for(int i=0; iAppend(mquads[i]); + + + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int i, j, k, l, m; + + +// if (mtets.Size() + mprisms.Size() == mesh.GetNE()) +// return; + + + + mtets.SetSize(0); + mprisms.SetSize(0); + mids.SetSize(0); + mtris.SetSize(0); + mquads.SetSize(0); + + + INDEX_2_HASHTABLE shortedges(100); + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + if (el.GetType() == PRISM || + el.GetType() == PRISM12) + { + for (j = 1; j <= 3; j++) + { + INDEX_2 se(el.PNum(j), el.PNum(j+3)); + se.Sort(); + shortedges.Set (se, 1); + } + } + } + + + + // INDEX_2_HASHTABLE edgenumber(np); + INDEX_2_CLOSED_HASHTABLE edgenumber(9*ne+4*nse); + + BTSortEdges (mesh, idmaps, edgenumber); + + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + + switch (el.GetType()) + { + case TET: + case TET10: + { + // if tet has short edge, it is handled as degenerated prism + + int foundse = 0; + for (j = 1; j <= 3; j++) + for (k = j+1; k <= 4; k++) + { + INDEX_2 se(el.PNum(j), el.PNum(k)); + se.Sort(); + if (shortedges.Used (se)) + { +// cout << "tet converted to prism" << endl; + + foundse = 1; + int p3 = 1; + while (p3 == j || p3 == k) + p3++; + int p4 = 10 - j - k - p3; + + // even permutation ? + int pi[4]; + pi[0] = j; + pi[1] = k; + pi[2] = p3; + pi[3] = p4; + int cnt = 0; + for (l = 1; l <= 4; l++) + for (m = 0; m < 3; m++) + if (pi[m] > pi[m+1]) + { + Swap (pi[m], pi[m+1]); + cnt++; + } + if (cnt % 2) + Swap (p3, p4); + + Element hel = el; + hel.PNum(1) = el.PNum(j); + hel.PNum(2) = el.PNum(k); + hel.PNum(3) = el.PNum(p3); + hel.PNum(4) = el.PNum(p4); + + MarkedPrism mp; + + BTDefineMarkedPrism (hel, edgenumber, mp); + mp.matindex = el.GetIndex(); + mprisms.Append (mp); + } + } + if (!foundse) + { + MarkedTet mt; + + int oldind = -1; + for(l = 0; oldind < 0 && lSize(); l++) + if(el[1] == (*mtets_old[el[0]])[l].pnums[1] && + el[2] == (*mtets_old[el[0]])[l].pnums[2] && + el[3] == (*mtets_old[el[0]])[l].pnums[3]) + oldind = l; + + if(oldind >= 0) + mtets.Append((*mtets_old[el[0]])[oldind]); + else + { + BTDefineMarkedTet (el, edgenumber, mt); + mt.matindex = el.GetIndex(); + mtets.Append (mt); + } + } + break; + } + case PYRAMID: + { + // eventually rotate + MarkedPrism mp; + + INDEX_2 se(el.PNum(1), el.PNum(2)); + se.Sort(); + if (shortedges.Used (se)) + { + Element hel = el; + hel.PNum(1) = el.PNum(2); + hel.PNum(2) = el.PNum(3); + hel.PNum(3) = el.PNum(4); + hel.PNum(4) = el.PNum(1); + BTDefineMarkedPrism (hel, edgenumber, mp); + } + else + { + BTDefineMarkedPrism (el, edgenumber, mp); + } + + mp.matindex = el.GetIndex(); + mprisms.Append (mp); + break; + } + case PRISM: + case PRISM12: + { + MarkedPrism mp; + BTDefineMarkedPrism (el, edgenumber, mp); + mp.matindex = el.GetIndex(); + mprisms.Append (mp); + break; + } + } + } + + for (i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (el.GetType() == TRIG || + el.GetType() == TRIG6) + { + MarkedTri mt; + BTDefineMarkedTri (el, edgenumber, mt); + mtris.Append (mt); + } + else + { + MarkedQuad mq; + BTDefineMarkedQuad (el, edgenumber, mq); + mquads.Append (mq); + } + + MarkedIdentification mi; + + + + for(j=0; jSize(); l++) + { + bool equal = true; + for(int m = 1; equal && m < mi.np; m++) + equal = (mi.pnums[m] == (*mids_old[el[0]])[l].pnums[m]); + if(equal) + oldind = l; + } + + if(oldind >= 0) + mids.Last() = (*mids_old[mi.pnums[0]])[oldind]; + } + + } + + + + for(int i=PointIndex::BASE; i* > & idmaps) + //const Array < Array* > & elements_before, + //const Array < Array* > & markedelts_num, + // const Array < Array* > & surfelements_before, + // const Array < Array* > & markedsurfelts_num) + { + /* + T_MTETS mtets_old; mtets_old.Copy(mtets); + T_MPRISMS mprisms_old; mprisms_old.Copy(mprisms); + T_MIDS mids_old; mids_old.Copy(mids); + T_MTRIS mtris_old; mtris_old.Copy(mtris); + T_MQUADS mquads_old; mquads_old.Copy(mquads); + */ + T_MTETS mtets_old (mtets); + T_MPRISMS mprisms_old (mprisms); + T_MIDS mids_old (mids); + T_MTRIS mtris_old (mtris); + T_MQUADS mquads_old (mquads); + + + + mtets.SetSize(0); + mprisms.SetSize(0); + mids.SetSize(0); + mtris.SetSize(0); + mquads.SetSize(0); + + //int nv = mesh.GetNV(); + + + INDEX_2_CLOSED_HASHTABLE edgenumber(9*mesh.GetNE()+4*mesh.GetNSE()); + + int maxnum = BTSortEdges (mesh, idmaps, edgenumber); + + for(int m = 0; m < mtets_old.Size(); m++) + { + MarkedTet & mt = mtets_old[m]; + + //(*testout) << "old mt " << mt; + + INDEX_2 edge (mt.pnums[mt.tetedge1],mt.pnums[mt.tetedge2]); + edge.Sort(); + if(edgenumber.Used(edge)) + { + int val = edgenumber.Get(edge); + //(*testout) << "set voledge " << edge << " from " << val; + if(val <= maxnum) + { + val += 2*maxnum; + edgenumber.Set(edge,val); + } + else if(val <= 2*maxnum) + { + val += maxnum; + edgenumber.Set(edge,val); + } + //(*testout) << " to " << val << endl; + } + + for(int k=0; k<4; k++) + for(int i=0; i<3; i++) + for(int j=i+1; i != k && j<4; j++) + if(j != k && int(mt.faceedges[k]) == 6-k-i-j) + { + edge[0] = mt.pnums[i]; + edge[1] = mt.pnums[j]; + edge.Sort(); + if(edgenumber.Used(edge)) + { + int val = edgenumber.Get(edge); + //(*testout) << "set faceedge " << edge << " from " << val; + if(val <= maxnum) + { + val += maxnum; + edgenumber.Set(edge,val); + } + //(*testout) << " to " << val << endl; + } + } + } + + + + + for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + //int pos = elements_before[el[0]]->Pos(el); + //int elnum = (pos >= 0) ? (*markedelts_num[el[0]])[pos] : -1; + + switch (el.GetType()) + { + case TET: + case TET10: + { + //if(elnum >= 0) + // { + // mtets.Append(mtets_old[elnum]); + // } + //else + // { + MarkedTet mt; + BTDefineMarkedTet (el, edgenumber, mt); + mt.matindex = el.GetIndex(); + + mtets.Append (mt); + + //(*testout) << "mtet " << mtets.Last() << endl; + break; + } + case PYRAMID: + { + cerr << "Refinement :: UpdateEdgeMarks not yet implemented for pyramids" + << endl; + break; + } + + case PRISM: + case PRISM12: + { + cerr << "Refinement :: UpdateEdgeMarks not yet implemented for prisms" + << endl; + break; + } + default: + throw NgException("Bisect, element type not handled in switch, 6"); + } + + } + + + + for(SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el = mesh[sei]; + + /* + for(int k=0; k<3; k++) + auxind3[k] = el[k]; + + auxind3.Sort(); + + int pos = oldfaces[auxind3[0]]->Pos(auxind3); + if(pos < 0) + cout << "UIUIUI" << endl; + */ + + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + MarkedTri mt; + BTDefineMarkedTri (el, edgenumber, mt); + mtris.Append (mt); + break; + } + + case QUAD: + case QUAD6: + { + MarkedQuad mt; + BTDefineMarkedQuad (el, edgenumber, mt); + mquads.Append (mt); + break; + } + default: + throw NgException("Bisect, element type not handled in switch, 5"); + } + + + MarkedIdentification mi; + for(int j=0; jPos(el); + int elnum = (pos >= 0) ? (*markedsurfelts_num[el[0]])[pos] : -1; + + + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + if(elnum >= 0) + mtris.Append(mtris_old[elnum]); + else + { + MarkedTri mt; + BTDefineMarkedTri (el, edgenumber, mt); + mtris.Append (mt); + (*testout) << "(new) "; + } + (*testout) << "mtri " << mtris.Last(); + break; + } + + case QUAD: + case QUAD6: + { + if(elnum >= 0) + mquads.Append(mquads_old[elnum]); + else + { + MarkedQuad mt; + BTDefineMarkedQuad (el, edgenumber, mt); + mquads.Append (mt); + } + break; + } + } + */ + } + + /* + for(int i=0; i * quality_loss) const + { + PrintMessage(1,"Mesh bisection"); + PushStatus("Mesh bisection"); + + static int timer = NgProfiler::CreateTimer ("Bisect"); + NgProfiler::RegionTimer reg1 (timer); + + + + static int localizetimer = NgProfiler::CreateTimer("localize edgepoints"); + NgProfiler::RegionTimer * loct = new NgProfiler::RegionTimer(localizetimer); + LocalizeEdgePoints(mesh); + delete loct; + + Array< Array* > idmaps; + for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + idmaps.Append(new Array); + mesh.GetIdentifications().GetMap(i,*idmaps.Last(),true); + } + } + + + string refelementinfofileread = ""; + string refelementinfofilewrite = ""; + + if(opt.refinementfilename) + { + ifstream inf(opt.refinementfilename); + string st; + inf >> st; + if(st == "refinementinfo") + { + while(inf) + { + while(inf && st != "markedelementsfile") + inf >> st; + + if(inf) + inf >> st; + + if(st == "read" && inf) + ReadEnclString(inf,refelementinfofileread,'\"'); + else if(st == "write" && inf) + ReadEnclString(inf,refelementinfofilewrite,'\"'); + } + } + inf.close(); + } + + + + if (mesh.mglevels == 1 || idmaps.Size() > 0) + BisectTetsCopyMesh(mesh, NULL, opt, idmaps, refelementinfofileread); + + + mesh.ComputeNVertices(); + + int np = mesh.GetNV(); + mesh.SetNP(np); + + // int ne = mesh.GetNE(); + // int nse = mesh.GetNSE(); + // int i, j, l; + + // int initnp = np; + // int maxsteps = 3; + + mesh.mglevels++; + + /* + if (opt.refinementfilename || opt.usemarkedelements) + maxsteps = 3; + */ + + + if (opt.refine_p) + { + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int ox,oy,oz; + for (ElementIndex ei = 0; ei < ne; ei++) + if (mesh[ei].TestRefinementFlag()) + { + mesh[ei].GetOrder(ox,oy,oz); + mesh[ei].SetOrder (ox+1,oy+1,oz+1); + if (mesh[ei].TestStrongRefinementFlag()) + mesh[ei].SetOrder (ox+2,oy+2,oz+2); + } + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + if (mesh[sei].TestRefinementFlag()) + { + mesh[sei].GetOrder(ox,oy); + mesh[sei].SetOrder(ox+1,oy+1); + if (mesh[sei].TestStrongRefinementFlag()) + mesh[sei].SetOrder(ox+2,oy+2); + } + +#ifndef SABINE //Nachbarelemente mit ordx,ordy,ordz + + Array v_order (mesh.GetNP()); + v_order = 0; + + for (ElementIndex ei = 0; ei < ne; ei++) + for (int j = 0; j < mesh[ei].GetNP(); j++) + if (mesh[ei].GetOrder() > v_order[mesh[ei][j]]) + v_order[mesh[ei][j]] = mesh[ei].GetOrder(); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + for (int j = 0; j < mesh[sei].GetNP(); j++) + if (mesh[sei].GetOrder() > v_order[mesh[sei][j]]) + v_order[mesh[sei][j]] = mesh[sei].GetOrder(); + + for (ElementIndex ei = 0; ei < ne; ei++) + for (int j = 0; j < mesh[ei].GetNP(); j++) + if (mesh[ei].GetOrder() < v_order[mesh[ei][j]]-1) + mesh[ei].SetOrder(v_order[mesh[ei][j]]-1); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + for (int j = 0; j < mesh[sei].GetNP(); j++) + if (mesh[sei].GetOrder() < v_order[mesh[sei][j]]-1) + mesh[sei].SetOrder(v_order[mesh[sei][j]]-1); + +#endif + + PopStatus(); + return; + } + + + + // INDEX_2_HASHTABLE cutedges(10 + 5 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size())); + INDEX_2_CLOSED_HASHTABLE cutedges(10 + 9 * (mtets.Size()+mprisms.Size()+mtris.Size()+mquads.Size())); + + bool noprojection = false; + + for (int l = 1; l <= 1; l++) + { + int marked = 0; + if (opt.refinementfilename) + { + ifstream inf(opt.refinementfilename); + PrintMessage(3,"load refinementinfo from file ",opt.refinementfilename); + + string st; + inf >> st; + if(st == "refinementinfo") + // new version + { + for(int i=1; i<=mtets.Size(); i++) + mtets.Elem(i).marked = 0; + for(int i=1; i<=mprisms.Size(); i++) + mprisms.Elem(i).marked = 0; + for(int i=1; i<=mtris.Size(); i++) + mtris.Elem(i).marked = 0; + for(int i=1; i<=mquads.Size(); i++) + mquads.Elem(i).marked = 0; + for(int i=1; i<=mprisms.Size(); i++) + mids.Elem(i).marked = 0; + + inf >> st; + while(inf) + { + if(st[0] == '#') + { + inf.ignore(10000,'\n'); + inf >> st; + } + else if(st == "markedelementsfile") + { + inf >> st; + ReadEnclString(inf,st,'\"'); + inf >> st; + } + else if(st == "noprojection") + { + noprojection = true; + inf >> st; + } + else if(st == "refine") + { + inf >> st; + if(st == "elements") + { + inf >> st; + bool isint = true; + for(string::size_type ii=0; isint && ii> st; + isint = true; + for(string::size_type ii=0; isint && ii> bounds[i]; + + int cnt = 0; + + for(ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + // + Point<3> center(0,0,0); + for(int i=0; i 0) + marked = 1; + + + inf >> st; + } + else + { + throw NgException("something wrong with refinementinfo file"); + } + } + } + } + else + { + inf.close(); + inf.open(opt.refinementfilename); + + char ch; + for (int i = 1; i <= mtets.Size(); i++) + { + inf >> ch; + if(!inf) + throw NgException("something wrong with refinementinfo file (old format)"); + mtets.Elem(i).marked = (ch == '1'); + } + marked = 1; + } + inf.close(); + } + + else if (opt.usemarkedelements) + { + int cntm = 0; + + // all in one ! + if (mprisms.Size()) + { + int cnttet = 0; + int cntprism = 0; + for (int i = 1; i <= mesh.GetNE(); i++) + { + if (mesh.VolumeElement(i).GetType() == TET || + mesh.VolumeElement(i).GetType() == TET10) + { + cnttet++; + mtets.Elem(cnttet).marked = + 3 * mesh.VolumeElement(i).TestRefinementFlag(); + if (mtets.Elem(cnttet).marked) + cntm++; + } + else + { + cntprism++; + mprisms.Elem(cntprism).marked = + 2 * mesh.VolumeElement(i).TestRefinementFlag(); + if (mprisms.Elem(cntprism).marked) + cntm++; + } + + } + } + else + for (int i = 1; i <= mtets.Size(); i++) + { + mtets.Elem(i).marked = + 3 * mesh.VolumeElement(i).TestRefinementFlag(); + if (mtets.Elem(i).marked) + cntm++; + } + + // (*testout) << "mtets = " << mtets << endl; + + /* + for (i = 1; i <= mtris.Size(); i++) + mtris.Elem(i).marked = 0; + for (i = 1; i <= mquads.Size(); i++) + mquads.Elem(i).marked = 0; + */ + + if (printmessage_importance>0) + { + ostringstream str; + str << "marked elements: " << cntm; + PrintMessage(4,str.str()); + } + + int cnttrig = 0; + int cntquad = 0; + for (int i = 1; i <= mesh.GetNSE(); i++) + { + if (mesh.SurfaceElement(i).GetType() == TRIG || + mesh.SurfaceElement(i).GetType() == TRIG6) + { + cnttrig++; + mtris.Elem(cnttrig).marked = + mesh.SurfaceElement(i).TestRefinementFlag() ? 2 : 0; + // mtris.Elem(cnttrig).marked = 0; + if (mtris.Elem(cnttrig).marked) + cntm++; + } + else + { + cntquad++; + // 2d: marked=2, 3d prisms: marked=1 + mquads.Elem(cntquad).marked = + mesh.SurfaceElement(i).TestRefinementFlag() ? 4-mesh.GetDimension() : 0 ; + // mquads.Elem(cntquad).marked = 0; + if (mquads.Elem(cntquad).marked) + cntm++; + } + } + + if (printmessage_importance>0) + { + ostringstream str; + str << "with surface-elements: " << cntm; + PrintMessage(4,str.str()); + } + + // he/sz: das wird oben schon richtig gemacht. + // hier sind die quads vergessen! + /* + if (mesh.GetDimension() == 2) + { + cntm = 0; + for (i = 1; i <= mtris.Size(); i++) + { + mtris.Elem(i).marked = + 2 * mesh.SurfaceElement(i).TestRefinementFlag(); + // mtris.Elem(i).marked = 2; + if (mtris.Elem(i).marked) + cntm++; + } + + if (!cntm) + { + for (i = 1; i <= mtris.Size(); i++) + { + mtris.Elem(i).marked = 2; + cntm++; + } + } + cout << "trigs: " << mtris.Size() << " "; + cout << "marked: " << cntm << endl; + } + */ + + marked = (cntm > 0); + } + else + { + marked = BTMarkTets (mtets, mprisms, mesh); + } + + if (!marked) break; + + + //(*testout) << "mtets " << mtets << endl; + + if (opt.refine_p) + { + PrintMessage(3,"refine p"); + + for (int i = 1; i <= mtets.Size(); i++) + mtets.Elem(i).incorder = mtets.Elem(i).marked ? 1 : 0; + + for (int i = 1; i <= mtets.Size(); i++) + if (mtets.Elem(i).incorder) + mtets.Elem(i).marked = 0; + + + for (int i = 1; i <= mprisms.Size(); i++) + mprisms.Elem(i).incorder = mprisms.Elem(i).marked ? 1 : 0; + + for (int i = 1; i <= mprisms.Size(); i++) + if (mprisms.Elem(i).incorder) + mprisms.Elem(i).marked = 0; + + + for (int i = 1; i <= mtris.Size(); i++) + mtris.Elem(i).incorder = mtris.Elem(i).marked ? 1 : 0; + + for (int i = 1; i <= mtris.Size(); i++) + { + if (mtris.Elem(i).incorder) + mtris.Elem(i).marked = 0; + } + } + + if (opt.refine_hp) + { + PrintMessage(3,"refine hp"); + BitArray singv(np); + singv.Clear(); + + if (mesh.GetDimension() == 3) + { + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + singv.Set (seg[0]); + singv.Set (seg[1]); + } + /* + for ( i=1; i<= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + for(int j=1; j<=sel.GetNP(); j++) + singv.Set(sel.PNum(j)); + } + */ + } + else + { + // vertices with 2 different bnds + Array bndind(np); + bndind = 0; + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + for (int j = 0; j < 2; j++) + { + int pi = (j == 0) ? seg[0] : seg[1]; + if (bndind.Elem(pi) == 0) + bndind.Elem(pi) = seg.edgenr; + else if (bndind.Elem(pi) != seg.edgenr) + singv.Set (pi); + } + } + } + + + + for (int i = 1; i <= mtets.Size(); i++) + mtets.Elem(i).incorder = 1; + for (int i = 1; i <= mtets.Size(); i++) + { + if (!mtets.Elem(i).marked) + mtets.Elem(i).incorder = 0; + for (int j = 0; j < 4; j++) + if (singv.Test (mtets.Elem(i).pnums[j])) + mtets.Elem(i).incorder = 0; + } + for (int i = 1; i <= mtets.Size(); i++) + if (mtets.Elem(i).incorder) + mtets.Elem(i).marked = 0; + + + for (int i = 1; i <= mprisms.Size(); i++) + mprisms.Elem(i).incorder = 1; + for (int i = 1; i <= mprisms.Size(); i++) + { + if (!mprisms.Elem(i).marked) + mprisms.Elem(i).incorder = 0; + for (int j = 0; j < 6; j++) + if (singv.Test (mprisms.Elem(i).pnums[j])) + mprisms.Elem(i).incorder = 0; + } + for (int i = 1; i <= mprisms.Size(); i++) + if (mprisms.Elem(i).incorder) + mprisms.Elem(i).marked = 0; + + + for (int i = 1; i <= mtris.Size(); i++) + mtris.Elem(i).incorder = 1; + for (int i = 1; i <= mtris.Size(); i++) + { + if (!mtris.Elem(i).marked) + mtris.Elem(i).incorder = 0; + for (int j = 0; j < 3; j++) + if (singv.Test (mtris.Elem(i).pnums[j])) + mtris.Elem(i).incorder = 0; + } + for (int i = 1; i <= mtris.Size(); i++) + { + if (mtris.Elem(i).incorder) + mtris.Elem(i).marked = 0; + } + } + + + + int hangingvol, hangingsurf, hangingedge; + + //cout << "write?" << endl; + //string yn; + //cin >> yn; + + (*testout) << "refine volume elements" << endl; + do + { + // refine volume elements + + int nel = mtets.Size(); + for (int i = 1; i <= nel; i++) + if (mtets.Elem(i).marked) + { + MarkedTet oldtet; + MarkedTet newtet1, newtet2; + PointIndex newp; + + + oldtet = mtets.Get(i); + //if(yn == "y") + // (*testout) << "bisected tet " << oldtet; + INDEX_2 edge(oldtet.pnums[oldtet.tetedge1], + oldtet.pnums[oldtet.tetedge2]); + edge.Sort(); + if (cutedges.Used (edge)) + { + newp = cutedges.Get(edge); + } + else + { + Point<3> npt = Center (mesh.Point (edge.I1()), + mesh.Point (edge.I2())); + newp = mesh.AddPoint (npt); + cutedges.Set (edge, newp); + } + + BTBisectTet (oldtet, newp, newtet1, newtet2); + + mtets.Elem(i) = newtet1; + mtets.Append (newtet2); + +#ifdef DEBUG + *testout << "tet1 has elnr = " << i << ", tet2 has elnr = " << mtets.Size() << endl; +#endif + //if(yn == "y") + // (*testout) << "and got " << newtet1 << "and " << newtet2 << endl; + + mesh.mlparentelement.Append (i); + } + + int npr = mprisms.Size(); + for (int i = 1; i <= npr; i++) + if (mprisms.Elem(i).marked) + { + MarkedPrism oldprism; + MarkedPrism newprism1, newprism2; + PointIndex newp1, newp2; + + oldprism = mprisms.Get(i); + int pi1 = 0; + if (pi1 == oldprism.markededge) + pi1++; + int pi2 = 3-pi1-oldprism.markededge; + + INDEX_2 edge1(oldprism.pnums[pi1], + oldprism.pnums[pi2]); + INDEX_2 edge2(oldprism.pnums[pi1+3], + oldprism.pnums[pi2+3]); + edge1.Sort(); + edge2.Sort(); + + if (cutedges.Used (edge1)) + newp1 = cutedges.Get(edge1); + else + { + Point<3> npt = Center (mesh.Point (edge1.I1()), + mesh.Point (edge1.I2())); + newp1 = mesh.AddPoint (npt); + cutedges.Set (edge1, newp1); + } + if (cutedges.Used (edge2)) + newp2 = cutedges.Get(edge2); + else + { + Point<3> npt = Center (mesh.Point (edge2.I1()), + mesh.Point (edge2.I2())); + newp2 = mesh.AddPoint (npt); + cutedges.Set (edge2, newp2); + } + + + BTBisectPrism (oldprism, newp1, newp2, newprism1, newprism2); + //if(yn == "y") + // (*testout) << "bisected prism " << oldprism << "and got " << newprism1 << "and " << newprism2 << endl; + mprisms.Elem(i) = newprism1; + mprisms.Append (newprism2); + } + + int nid = mids.Size(); + for (int i = 1; i <= nid; i++) + if (mids.Elem(i).marked) + { + MarkedIdentification oldid,newid1,newid2; + Array newp; + + oldid = mids.Get(i); + + Array edges; + edges.Append(INDEX_2(oldid.pnums[oldid.markededge], + oldid.pnums[(oldid.markededge+1)%oldid.np])); + edges.Append(INDEX_2(oldid.pnums[oldid.markededge + oldid.np], + oldid.pnums[(oldid.markededge+1)%oldid.np + oldid.np])); + + if(oldid.np == 4) + { + edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np], + oldid.pnums[(oldid.markededge+3)%oldid.np])); + edges.Append(INDEX_2(oldid.pnums[(oldid.markededge+2)%oldid.np + oldid.np], + oldid.pnums[(oldid.markededge+3)%oldid.np + oldid.np])); + } + for (int j = 0; j < edges.Size(); j++) + { + edges[j].Sort(); + + if(cutedges.Used(edges[j])) + newp.Append(cutedges.Get(edges[j])); + else + { + Point<3> npt = Center (mesh.Point (edges[j].I1()), + mesh.Point (edges[j].I2())); + newp.Append(mesh.AddPoint(npt)); + cutedges.Set(edges[j],newp[j]); + } + } + + BTBisectIdentification(oldid,newp,newid1,newid2); + mids.Elem(i) = newid1; + mids.Append(newid2); + } + + + //IdentifyCutEdges(mesh, cutedges); + + + hangingvol = + MarkHangingTets (mtets, cutedges) + + MarkHangingPrisms (mprisms, cutedges) + + MarkHangingIdentifications (mids, cutedges); + + + int nsel = mtris.Size(); + + for (int i = 1; i <= nsel; i++) + if (mtris.Elem(i).marked) + { + MarkedTri oldtri; + MarkedTri newtri1, newtri2; + PointIndex newp; + + oldtri = mtris.Get(i); + int oldpi1 = oldtri.pnums[(oldtri.markededge+1)%3]; + int oldpi2 = oldtri.pnums[(oldtri.markededge+2)%3]; + INDEX_2 edge(oldpi1, oldpi2); + edge.Sort(); + + // cerr << "edge = " << edge.I1() << "-" << edge.I2() << endl; + + if (cutedges.Used (edge)) + { + newp = cutedges.Get(edge); + } + else + { + Point<3> npt = Center (mesh.Point (edge.I1()), + mesh.Point (edge.I2())); + newp = mesh.AddPoint (npt); + cutedges.Set (edge, newp); + } + // newp = cutedges.Get(edge); + + int si = mesh.GetFaceDescriptor (oldtri.surfid).SurfNr(); + // geom->GetSurface(si)->Project (mesh.Point(newp)); + PointGeomInfo npgi; + +// cerr << "project point " << newp << " old: " << mesh.Point(newp); + if (mesh[newp].Type() != EDGEPOINT) + PointBetween (mesh.Point (oldpi1), mesh.Point (oldpi2), + 0.5, si, + oldtri.pgeominfo[(oldtri.markededge+1)%3], + oldtri.pgeominfo[(oldtri.markededge+2)%3], + mesh.Point (newp), npgi); +// cerr << " new: " << mesh.Point(newp) << endl; + + BTBisectTri (oldtri, newp, npgi, newtri1, newtri2); + //if(yn == "y") + // (*testout) << "bisected tri " << oldtri << "and got " << newtri1 << "and " << newtri2 << endl; + + + mtris.Elem(i) = newtri1; + mtris.Append (newtri2); + mesh.mlparentsurfaceelement.Append (i); + } + + int nquad = mquads.Size(); + for (int i = 1; i <= nquad; i++) + if (mquads.Elem(i).marked) + { + MarkedQuad oldquad; + MarkedQuad newquad1, newquad2; + PointIndex newp1, newp2; + + oldquad = mquads.Get(i); + /* + INDEX_2 edge1(oldquad.pnums[0], + oldquad.pnums[1]); + INDEX_2 edge2(oldquad.pnums[2], + oldquad.pnums[3]); + */ + INDEX_2 edge1, edge2; + PointGeomInfo pgi11, pgi12, pgi21, pgi22; + if (oldquad.markededge==0 || oldquad.markededge==2) + { + edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0]; + edge1.I2()=oldquad.pnums[1]; pgi12=oldquad.pgeominfo[1]; + edge2.I1()=oldquad.pnums[2]; pgi21=oldquad.pgeominfo[2]; + edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3]; + } + else // 3 || 1 + { + edge1.I1()=oldquad.pnums[0]; pgi11=oldquad.pgeominfo[0]; + edge1.I2()=oldquad.pnums[2]; pgi12=oldquad.pgeominfo[2]; + edge2.I1()=oldquad.pnums[1]; pgi21=oldquad.pgeominfo[1]; + edge2.I2()=oldquad.pnums[3]; pgi22=oldquad.pgeominfo[3]; + } + + edge1.Sort(); + edge2.Sort(); + + if (cutedges.Used (edge1)) + { + newp1 = cutedges.Get(edge1); + } + else + { + Point<3> np1 = Center (mesh.Point (edge1.I1()), + mesh.Point (edge1.I2())); + newp1 = mesh.AddPoint (np1); + cutedges.Set (edge1, newp1); + } + + if (cutedges.Used (edge2)) + { + newp2 = cutedges.Get(edge2); + } + else + { + Point<3> np2 = Center (mesh.Point (edge2.I1()), + mesh.Point (edge2.I2())); + newp2 = mesh.AddPoint (np2); + cutedges.Set (edge2, newp2); + } + + PointGeomInfo npgi1, npgi2; + + int si = mesh.GetFaceDescriptor (oldquad.surfid).SurfNr(); + // geom->GetSurface(si)->Project (mesh.Point(newp1)); + // geom->GetSurface(si)->Project (mesh.Point(newp2)); + +// (*testout) +// cerr << "project point 1 " << newp1 << " old: " << mesh.Point(newp1); + PointBetween (mesh.Point (edge1.I1()), mesh.Point (edge1.I2()), + 0.5, si, + pgi11, + pgi12, + mesh.Point (newp1), npgi1); +// (*testout) +// cerr << " new: " << mesh.Point(newp1) << endl; + + +// cerr << "project point 2 " << newp2 << " old: " << mesh.Point(newp2); + PointBetween (mesh.Point (edge2.I1()), mesh.Point (edge2.I2()), + 0.5, si, + pgi21, + pgi22, + mesh.Point (newp2), npgi2); +// cerr << " new: " << mesh.Point(newp2) << endl; + + + BTBisectQuad (oldquad, newp1, npgi1, newp2, npgi2, + newquad1, newquad2); + + mquads.Elem(i) = newquad1; + mquads.Append (newquad2); + } + + + hangingsurf = + MarkHangingTris (mtris, cutedges) + + MarkHangingQuads (mquads, cutedges); + + hangingedge = 0; + + int nseg = mesh.GetNSeg (); + for (int i = 1; i <= nseg; i++) + { + Segment & seg = mesh.LineSegment (i); + INDEX_2 edge(seg[0], seg[1]); + edge.Sort(); + if (cutedges.Used (edge)) + { + hangingedge = 1; + Segment nseg1 = seg; + Segment nseg2 = seg; + + int newpi = cutedges.Get(edge); + + nseg1[1] = newpi; + nseg2[0] = newpi; + + EdgePointGeomInfo newepgi; + + +// +// cerr << "move edgepoint " << newpi << " from " << mesh.Point(newpi); + PointBetween (mesh.Point (seg[0]), mesh.Point (seg[1]), + 0.5, seg.surfnr1, seg.surfnr2, + seg.epgeominfo[0], seg.epgeominfo[1], + mesh.Point (newpi), newepgi); +// cerr << " to " << mesh.Point (newpi) << endl; + + + nseg1.epgeominfo[1] = newepgi; + nseg2.epgeominfo[0] = newepgi; + + mesh.LineSegment (i) = nseg1; + mesh.AddSegment (nseg2); + } + } + } + while (hangingvol || hangingsurf || hangingedge); + + /* + if (printmessage_importance>0) + { + ostringstream strstr; + strstr << mtets.Size() << " tets" << endl + << mtris.Size() << " trigs" << endl; + if (mprisms.Size()) + { + strstr << mprisms.Size() << " prisms" << endl + << mquads.Size() << " quads" << endl; + } + strstr << mesh.GetNP() << " points"; + PrintMessage(4,strstr.str()); + } + */ + PrintMessage (4, mtets.Size(), " tets"); + PrintMessage (4, mtris.Size(), " trigs"); + if (mprisms.Size()) + { + PrintMessage (4, mprisms.Size(), " prisms"); + PrintMessage (4, mquads.Size(), " quads"); + } + PrintMessage (4, mesh.GetNP(), " points"); + } + + + // (*testout) << "mtets = " << mtets << endl; + + if (opt.refine_hp) + { + // + Array v_order (mesh.GetNP()); + v_order = 0; + if (mesh.GetDimension() == 3) + { + for (int i = 1; i <= mtets.Size(); i++) + if (mtets.Elem(i).incorder) + mtets.Elem(i).order++; + + for (int i = 0; i < mtets.Size(); i++) + for (int j = 0; j < 4; j++) + if (int(mtets[i].order) > v_order.Elem(mtets[i].pnums[j])) + v_order.Elem(mtets[i].pnums[j]) = mtets[i].order; + for (int i = 0; i < mtets.Size(); i++) + for (int j = 0; j < 4; j++) + if (int(mtets[i].order) < v_order.Elem(mtets[i].pnums[j])-1) + mtets[i].order = v_order.Elem(mtets[i].pnums[j])-1; + } + else + { + for (int i = 1; i <= mtris.Size(); i++) + if (mtris.Elem(i).incorder) + { + mtris.Elem(i).order++; + } + + for (int i = 0; i < mtris.Size(); i++) + for (int j = 0; j < 3; j++) + if (int(mtris[i].order) > v_order.Elem(mtris[i].pnums[j])) + v_order.Elem(mtris[i].pnums[j]) = mtris[i].order; + for (int i = 0; i < mtris.Size(); i++) + { + for (int j = 0; j < 3; j++) + if (int(mtris[i].order) < v_order.Elem(mtris[i].pnums[j])-1) + mtris[i].order = v_order.Elem(mtris[i].pnums[j])-1; + } + } + } + + mtets.SetAllocSize (mtets.Size()); + mprisms.SetAllocSize (mprisms.Size()); + mids.SetAllocSize (mids.Size()); + mtris.SetAllocSize (mtris.Size()); + mquads.SetAllocSize (mquads.Size()); + + + mesh.ClearVolumeElements(); + mesh.VolumeElements().SetAllocSize (mtets.Size()+mprisms.Size()); + for (int i = 1; i <= mtets.Size(); i++) + { + Element el(TET); + el.SetIndex (mtets.Get(i).matindex); + for (int j = 1; j <= 4; j++) + el.PNum(j) = mtets.Get(i).pnums[j-1]; + el.SetOrder (mtets.Get(i).order); + mesh.AddVolumeElement (el); + } + for (int i = 1; i <= mprisms.Size(); i++) + { + Element el(PRISM); + el.SetIndex (mprisms.Get(i).matindex); + for (int j = 1; j <= 6; j++) + el.PNum(j) = mprisms.Get(i).pnums[j-1]; + el.SetOrder (mprisms.Get(i).order); + + // degenerated prism ? + static const int map1[] = { 3, 2, 5, 6, 1 }; + static const int map2[] = { 1, 3, 6, 4, 2 }; + static const int map3[] = { 2, 1, 4, 5, 3 }; + + + const int * map = NULL; + int deg1 = 0, deg2 = 0, deg3 = 0; + // int deg = 0; + if (el.PNum(1) == el.PNum(4)) { map = map1; deg1 = 1; } + if (el.PNum(2) == el.PNum(5)) { map = map2; deg2 = 1; } + if (el.PNum(3) == el.PNum(6)) { map = map3; deg3 = 1; } + + switch (deg1+deg2+deg3) + { + case 1: + { + for (int j = 1; j <= 5; j++) + el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1]; + + el.SetType (PYRAMID); + break; + } + case 2: + { + static const int tetmap1[] = { 1, 2, 3, 4 }; + static const int tetmap2[] = { 2, 3, 1, 5 }; + static const int tetmap3[] = { 3, 1, 2, 6 }; + if (!deg1) map = tetmap1; + if (!deg2) map = tetmap2; + if (!deg3) map = tetmap3; + for (int j = 1; j <= 4; j++) + el.PNum(j) = mprisms.Get(i).pnums[map[j-1]-1]; + /* + if (!deg1) el.PNum(4) = el.PNum(4); + if (!deg2) el.PNum(4) = el.PNum(5); + if (!deg3) el.PNum(4) = el.PNum(6); + */ + el.SetType(TET); + break; + } + default: + ; + } + mesh.AddVolumeElement (el); + } + + mesh.ClearSurfaceElements(); + for (int i = 1; i <= mtris.Size(); i++) + { + Element2d el(TRIG); + el.SetIndex (mtris.Get(i).surfid); + el.SetOrder (mtris.Get(i).order); + for (int j = 1; j <= 3; j++) + { + el.PNum(j) = mtris.Get(i).pnums[j-1]; + el.GeomInfoPi(j) = mtris.Get(i).pgeominfo[j-1]; + } + mesh.AddSurfaceElement (el); + } + for (int i = 1; i <= mquads.Size(); i++) + { + Element2d el(QUAD); + el.SetIndex (mquads.Get(i).surfid); + for (int j = 1; j <= 4; j++) + el.PNum(j) = mquads.Get(i).pnums[j-1]; + Swap (el.PNum(3), el.PNum(4)); + mesh.AddSurfaceElement (el); + } + + + + // write multilevel hierarchy to mesh: + np = mesh.GetNP(); + mesh.mlbetweennodes.SetSize(np); + if (mesh.mglevels <= 2) + { + PrintMessage(4,"RESETTING mlbetweennodes"); + for (int i = 1; i <= np; i++) + { + mesh.mlbetweennodes.Elem(i).I1() = 0; + mesh.mlbetweennodes.Elem(i).I2() = 0; + } + } + + /* + for (i = 1; i <= cutedges.GetNBags(); i++) + for (j = 1; j <= cutedges.GetBagSize(i); j++) + { + INDEX_2 edge; + int newpi; + cutedges.GetData (i, j, edge, newpi); + mesh.mlbetweennodes.Elem(newpi) = edge; + } + */ + + BitArray isnewpoint(np); + isnewpoint.Clear(); + + for (int i = 1; i <= cutedges.Size(); i++) + if (cutedges.UsedPos(i)) + { + INDEX_2 edge; + PointIndex newpi; + cutedges.GetData (i, edge, newpi); + isnewpoint.Set(newpi); + mesh.mlbetweennodes.Elem(newpi) = edge; + } + + + /* + mesh.PrintMemInfo (cout); + cout << "tets "; + mtets.PrintMemInfo (cout); + cout << "prims "; + mprisms.PrintMemInfo (cout); + cout << "tris "; + mtris.PrintMemInfo (cout); + cout << "quads "; + mquads.PrintMemInfo (cout); + cout << "cutedges "; + cutedges.PrintMemInfo (cout); + */ + + + /* + + // find connected nodes (close nodes) + TABLE conto(np); + for (i = 1; i <= mprisms.Size(); i++) + for (j = 1; j <= 6; j++) + { + int n1 = mprisms.Get(i).pnums[j-1]; + int n2 = mprisms.Get(i).pnums[(j+2)%6]; + // if (n1 != n2) + { + int found = 0; + for (k = 1; k <= conto.EntrySize(n1); k++) + if (conto.Get(n1, k) == n2) + { + found = 1; + break; + } + if (!found) + conto.Add (n1, n2); + } + } + mesh.connectedtonode.SetSize(np); + for (i = 1; i <= np; i++) + mesh.connectedtonode.Elem(i) = 0; + + + // (*testout) << "connection table: " << endl; + // for (i = 1; i <= np; i++) + // { + // (*testout) << "node " << i << ": "; + // for (j = 1; j <= conto.EntrySize(i); j++) + // (*testout) << conto.Get(i, j) << " "; + // (*testout) << endl; + // } + + + for (i = 1; i <= np; i++) + if (mesh.connectedtonode.Elem(i) == 0) + { + mesh.connectedtonode.Elem(i) = i; + ConnectToNodeRec (i, i, conto, mesh.connectedtonode); + } + */ + + // mesh.BuildConnectedNodes(); + + + + + mesh.ComputeNVertices(); + mesh.RebuildSurfaceElementLists(); + + + // update identification tables + for (int i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) + { + Array identmap; + + mesh.GetIdentifications().GetMap (i, identmap); + + + /* + for (j = 1; j <= cutedges.GetNBags(); j++) + for (k = 1; k <= cutedges.GetBagSize(j); k++) + { + INDEX_2 i2; + int newpi; + cutedges.GetData (j, k, i2, newpi); + INDEX_2 oi2(identmap.Get(i2.I1()), + identmap.Get(i2.I2())); + oi2.Sort(); + if (cutedges.Used (oi2)) + { + int onewpi = cutedges.Get(oi2); + mesh.GetIdentifications().Add (newpi, onewpi, i); + } + } + */ + + for (int j = 1; j <= cutedges.Size(); j++) + if (cutedges.UsedPos(j)) + { + INDEX_2 i2; + PointIndex newpi; + cutedges.GetData (j, i2, newpi); + INDEX_2 oi2(identmap.Get(i2.I1()), + identmap.Get(i2.I2())); + oi2.Sort(); + if (cutedges.Used (oi2)) + { + PointIndex onewpi = cutedges.Get(oi2); + mesh.GetIdentifications().Add (newpi, onewpi, i); + } + } + } + + + // Repair works only for tets! + bool do_repair = mesh.PureTetMesh (); + + do_repair = false; // JS, March 2009: multigrid crashes + + //if(mesh.mglevels == 3) + // noprojection = true; + + //noprojection = true; + + if(noprojection) + { + do_repair = false; + for(int ii=1; ii<=mesh.GetNP(); ii++) + { + if(isnewpoint.Test(ii) && mesh.mlbetweennodes[ii][0] > 0) + { + mesh.Point(ii) = Center(mesh.Point(mesh.mlbetweennodes[ii][0]), + mesh.Point(mesh.mlbetweennodes[ii][1])); + } + } + } + + + // Check/Repair + + static bool repaired_once; + if(mesh.mglevels == 1) + repaired_once = false; + + //mesh.Save("before.vol"); + + static int reptimer = NgProfiler::CreateTimer("check/repair"); + NgProfiler::RegionTimer * regt(NULL); + regt = new NgProfiler::RegionTimer(reptimer); + + Array bad_elts; + Array pure_badness; + + if(do_repair || quality_loss != NULL) + { + pure_badness.SetSize(mesh.GetNP()+2); + GetPureBadness(mesh,pure_badness,isnewpoint); + } + + + if(do_repair) // by Markus W + { + const double max_worsening = 1; + + const bool uselocalworsening = false; + + bool repaired = false; + + Validate(mesh,bad_elts,pure_badness,max_worsening,uselocalworsening); + + if (printmessage_importance>0) + { + ostringstream strstr; + for(int ii=0; ii 0) + { + clock_t t1(clock()); + + + // update id-maps + int j=0; + for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + mesh.GetIdentifications().GetMap(i,*idmaps[j],true); + j++; + } + } + + + // do the repair + try + { + RepairBisection(mesh,bad_elts,isnewpoint,*this, + pure_badness, + max_worsening,uselocalworsening, + idmaps); + repaired = true; + repaired_once = true; + } + catch(NgException & ex) + { + PrintMessage(1,string("Problem: ") + ex.What()); + } + + + if (printmessage_importance>0) + { + ostringstream strstr; + strstr << "Time for Repair: " << double(clock() - t1)/double(CLOCKS_PER_SEC) << endl + << "bad elements after repair: " << bad_elts << endl; + PrintMessage(1,strstr.str()); + } + + if(quality_loss != NULL) + Validate(mesh,bad_elts,pure_badness,1e100,uselocalworsening,quality_loss); + + if(idmaps.Size() == 0) + UpdateEdgeMarks(mesh,idmaps); + + /* + if(1==1) + UpdateEdgeMarks(mesh,idmaps); + else + mesh.mglevels = 1; + */ + + //mesh.ImproveMesh(); + + } + } + delete regt; + + + + for(int i=0; i & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const + { + newp = p1+secpoint*(p2-p1); + } + + void Refinement :: PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const + { + cout << "base class edge point between" << endl; + newp = p1+secpoint*(p2-p1); + } + + + Vec<3> Refinement :: GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & ap1) const + { + cerr << "Refinement::GetTangent not overloaded" << endl; + return Vec<3> (0,0,0); + } + + Vec<3> Refinement :: GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const + { + cerr << "Refinement::GetNormal not overloaded" << endl; + return Vec<3> (0,0,0); + } + + + void Refinement :: ProjectToSurface (Point<3> & p, int surfi) const + { + if (printmessage_importance>0) + cerr << "Refinement :: ProjectToSurface ERROR: no geometry set" << endl; + }; + + void Refinement :: ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const + { + cerr << "Refinement::ProjectToEdge not overloaded" << endl; + } +} diff --git a/libsrc/meshing/bisect.hpp b/libsrc/meshing/bisect.hpp new file mode 100644 index 00000000..2da9b97e --- /dev/null +++ b/libsrc/meshing/bisect.hpp @@ -0,0 +1,102 @@ +#ifndef BISECT +#define BISECT + +class BisectionOptions +{ +public: + const char * outfilename; + const char * mlfilename; + const char * refinementfilename; + const char * femcode; + int maxlevel; + int usemarkedelements; + bool refine_hp; + bool refine_p; + BisectionOptions (); +}; + +class ZRefinementOptions +{ +public: + int minref; + ZRefinementOptions(); +}; + + +/* +extern void BisectTets (Mesh &, const CSGeometry *, + BisectionOptions & opt); +*/ + +extern void BisectTetsCopyMesh (Mesh &, const class CSGeometry *, + BisectionOptions & opt); + +extern void ZRefinement (Mesh &, const class NetgenGeometry *, + ZRefinementOptions & opt); + + + + + +class DLL_HEADER Refinement +{ + MeshOptimize2d * optimizer2d; + +public: + Refinement (); + virtual ~Refinement (); + + void Refine (Mesh & mesh) const; + void Refine (Mesh & mesh); + void Bisect (Mesh & mesh, class BisectionOptions & opt, Array * quality_loss = NULL) const; + + void MakeSecondOrder (Mesh & mesh) const; + void MakeSecondOrder (Mesh & mesh); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const; + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const; + + virtual Vec<3> GetTangent (const Point<3> & p, int surfi1, int surfi2, + const EdgePointGeomInfo & egi) const; + + virtual Vec<3> GetNormal (const Point<3> & p, int surfi1, + const PointGeomInfo & gi) const; + + + virtual void ProjectToSurface (Point<3> & p, int surfi) const; + + virtual void ProjectToSurface (Point<3> & p, int surfi, const PointGeomInfo & /* gi */) const + { + ProjectToSurface (p, surfi); + } + + virtual void ProjectToEdge (Point<3> & p, int surfi1, int surfi2, const EdgePointGeomInfo & egi) const; + + + void ValidateSecondOrder (Mesh & mesh); + void ValidateRefinedMesh (Mesh & mesh, + Array & parents); + + MeshOptimize2d * Get2dOptimizer(void) const + { + return optimizer2d; + } + void Set2dOptimizer(MeshOptimize2d * opti) + { + optimizer2d = opti; + } + + + virtual void LocalizeEdgePoints(Mesh & /* mesh */) const {;} +}; + +#endif diff --git a/libsrc/meshing/boundarylayer.cpp b/libsrc/meshing/boundarylayer.cpp new file mode 100644 index 00000000..dbf40437 --- /dev/null +++ b/libsrc/meshing/boundarylayer.cpp @@ -0,0 +1,610 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + + void InsertVirtualBoundaryLayer (Mesh & mesh) + { + cout << "Insert virt. b.l." << endl; + + int surfid; + + cout << "Boundary Nr:"; + cin >> surfid; + + int i, j; + int np = mesh.GetNP(); + + cout << "Old NP: " << mesh.GetNP() << endl; + cout << "Trigs: " << mesh.GetNSE() << endl; + + BitArray bndnodes(np); + Array mapto(np); + + bndnodes.Clear(); + for (i = 1; i <= mesh.GetNSeg(); i++) + { + int snr = mesh.LineSegment(i).edgenr; + cout << "snr = " << snr << endl; + if (snr == surfid) + { + bndnodes.Set (mesh.LineSegment(i)[0]); + bndnodes.Set (mesh.LineSegment(i)[1]); + } + } + for (i = 1; i <= mesh.GetNSeg(); i++) + { + int snr = mesh.LineSegment(i).edgenr; + if (snr != surfid) + { + bndnodes.Clear (mesh.LineSegment(i)[0]); + bndnodes.Clear (mesh.LineSegment(i)[1]); + } + } + + for (i = 1; i <= np; i++) + { + if (bndnodes.Test(i)) + mapto.Elem(i) = mesh.AddPoint (mesh.Point (i)); + else + mapto.Elem(i) = 0; + } + + for (i = 1; i <= mesh.GetNSE(); i++) + { + Element2d & el = mesh.SurfaceElement(i); + for (j = 1; j <= el.GetNP(); j++) + if (mapto.Get(el.PNum(j))) + el.PNum(j) = mapto.Get(el.PNum(j)); + } + + + int nq = 0; + for (i = 1; i <= mesh.GetNSeg(); i++) + { + int snr = mesh.LineSegment(i).edgenr; + if (snr == surfid) + { + int p1 = mesh.LineSegment(i)[0]; + int p2 = mesh.LineSegment(i)[1]; + int p3 = mapto.Get (p1); + if (!p3) p3 = p1; + int p4 = mapto.Get (p2); + if (!p4) p4 = p2; + + Element2d el(QUAD); + el.PNum(1) = p1; + el.PNum(2) = p2; + el.PNum(3) = p3; + el.PNum(4) = p4; + el.SetIndex (2); + mesh.AddSurfaceElement (el); + nq++; + } + } + + cout << "New NP: " << mesh.GetNP() << endl; + cout << "Quads: " << nq << endl; + } + + + + + +/* + Philippose Rajan - 11 June 2009 + + Function to calculate the surface normal at a given + vertex of a surface element, with respect to that + surface element. + + This function is used by the boundary layer generation + function, in order to calculate the effective direction + in which the prismatic layer should grow +*/ + void GetSurfaceNormal(Mesh & mesh, Element2d & el, int Vertex, Vec3d & SurfaceNormal) + { + int Vertex_A; + int Vertex_B; + + Vertex_A = Vertex + 1; + if(Vertex_A > el.GetNP()) Vertex_A = 1; + + Vertex_B = Vertex - 1; + if(Vertex_B <= 0) Vertex_B = el.GetNP(); + + Vec3d Vect_A,Vect_B; + + Vect_A = mesh.Point(el.PNum(Vertex_A)) - mesh.Point(el.PNum(Vertex)); + Vect_B = mesh.Point(el.PNum(Vertex_B)) - mesh.Point(el.PNum(Vertex)); + + SurfaceNormal = Cross(Vect_A,Vect_B); + SurfaceNormal.Normalize(); + } + + + + + +/* + Philippose Rajan - 11 June 2009 + + Added an initial experimental function for + generating prismatic boundary layers on + a given set of surfaces. + + The number of layers, height of the first layer + and the growth / shrink factor can be specified + by the user + + Currently, the layer height is calculated using: + height = h_first_layer * (growth_factor^(num_layers - 1)) +*/ + void GenerateBoundaryLayer (Mesh & mesh, MeshingParameters & mp) + { + int i, j; + + ofstream dbg("BndLayerDebug.log"); + + // Angle between a surface element and a growth-vector below which + // a prism is project onto that surface as a quad + // (in degrees) + double angleThreshold = 5.0; + + cout << "Generate Prismatic Boundary Layers (Experimental)...." << endl; + + // Use an array to support creation of boundary + // layers for multiple surfaces in the future... + Array surfid; + int surfinp = 0; + int prismlayers = 1; + double hfirst = 0.01; + double growthfactor = 1.0; + + // Monitor and print out the number of prism and quad elements + // added to the mesh + int numprisms = 0; + int numquads = 0; + + while(surfinp >= 0) + { + cout << "Enter Surface ID (-1 to end list): "; + cin >> surfinp; + if(surfinp >= 0) surfid.Append(surfinp); + } + + cout << "Number of surfaces entered = " << surfid.Size() << endl; + cout << "Selected surfaces are:" << endl; + + for(i = 1; i <= surfid.Size(); i++) + { + cout << "Surface " << i << ": " << surfid.Elem(i) << endl; + } + + cout << endl << "Enter number of prism layers: "; + cin >> prismlayers; + if(prismlayers < 1) prismlayers = 1; + + cout << "Enter height of first layer: "; + cin >> hfirst; + if(hfirst <= 0.0) hfirst = 0.01; + + cout << "Enter layer growth / shrink factor: "; + cin >> growthfactor; + if(growthfactor <= 0.0) growthfactor = 0.5; + + cout << "Old NP: " << mesh.GetNP() << endl; + cout << "Old NSE: " << mesh.GetNSE() << endl; + + for(int layer = prismlayers; layer >= 1; layer--) + { + cout << "Generating layer: " << layer << endl; + + const MeshTopology& meshtopo = mesh.GetTopology(); + const_cast (meshtopo).SetBuildEdges(true); + const_cast (meshtopo).SetBuildFaces(true); + const_cast (meshtopo).Update(); + + double layerht = hfirst; + + if(growthfactor == 1) + { + layerht = layer * hfirst; + } + else + { + layerht = hfirst*(pow(growthfactor,(layer+1)) - 1)/(growthfactor - 1); + } + + cout << "Layer Height = " << layerht << endl; + + // Need to store the old number of points and + // surface elements because there are new points and + // surface elements being added during the process + int np = mesh.GetNP(); + int nse = mesh.GetNSE(); + + // Safety measure to ensure no issues with mesh + // consistency + int nseg = mesh.GetNSeg(); + + // Indicate which points need to be remapped + BitArray bndnodes(np); + + // Map of the old points to the new points + Array mapto(np); + + // Growth vectors for the prismatic layer based on + // the effective surface normal at a given point + Array growthvectors(np); + + // Bit array to identify all the points belonging + // to the surface of interest + bndnodes.Clear(); + + // Run through all the surface elements and mark the points + // belonging to those where a boundary layer has to be created. + // In addition, also calculate the effective surface normal + // vectors at each of those points to determine the mesh motion + // direction + cout << "Marking points for remapping...." << endl; + + for (i = 1; i <= nse; i++) + { + int snr = mesh.SurfaceElement(i).GetIndex(); + // cout << "snr = " << snr << endl; + if (surfid.Contains(snr)) + { + Element2d & sel = mesh.SurfaceElement(i); + int selNP = sel.GetNP(); + for(j = 1; j <= selNP; j++) + { + // Set the bitarray to indicate that the + // point is part of the required set + bndnodes.Set(sel.PNum(j)); + + // Vec3d& surfacenormal = Vec3d(); ???? + Vec3d surfacenormal; + + // Calculate the surface normal at the current point + // with respect to the current surface element + GetSurfaceNormal(mesh,sel,j,surfacenormal); + + // Add the surface normal to the already existent one + // (This gives the effective normal direction at corners + // and curved areas) + growthvectors.Elem(sel.PNum(j)) = growthvectors.Elem(sel.PNum(j)) + + surfacenormal; + } + } + } + + // Add additional points into the mesh structure in order to + // clone the surface elements. + // Also invert the growth vectors so that they point inwards, + // and normalize them + cout << "Cloning points and calculating growth vectors...." << endl; + + for (i = 1; i <= np; i++) + { + if (bndnodes.Test(i)) + { + mapto.Elem(i) = mesh.AddPoint (mesh.Point (i)); + + growthvectors.Elem(i).Normalize(); + growthvectors.Elem(i) *= -1.0; + } + else + { + mapto.Elem(i) = 0; + growthvectors.Elem(i) = Vec3d(0,0,0); + } + } + + + // Add quad surface elements at edges for surfaces which + // dont have boundary layers + + // Bit array to keep track of segments already processed + BitArray segsel(nseg); + + // Set them all to "1" to initially activate all segments + segsel.Set(); + + cout << "Adding 2D Quad elements on required surfaces...." << endl; + + for (i = 1; i <= nseg; i++) + { + int seg_p1 = mesh.LineSegment(i)[0]; + int seg_p2 = mesh.LineSegment(i)[1]; + + // Only go in if the segment is still active, and if both its + // surface index is part of the "hit-list" + if(segsel.Test(i) && surfid.Contains(mesh.LineSegment(i).si)) + { + // clear the bit to indicate that this segment has been processed + segsel.Clear(i); + + // Find matching segment pair on other surface + for(j = 1; j <= nseg; j++) + { + int segpair_p1 = mesh.LineSegment(j)[1]; + int segpair_p2 = mesh.LineSegment(j)[0]; + + // Find the segment pair on the neighbouring surface element + // Identified by: seg1[0] = seg_pair[1] and seg1[1] = seg_pair[0] + if(segsel.Test(j) && ((segpair_p1 == seg_p1) && (segpair_p2 == seg_p2))) + { + // clear bit to indicate that processing of this segment is done + segsel.Clear(j); + + // Only worry about those surfaces which are not in the + // boundary layer list + if(!surfid.Contains(mesh.LineSegment(j).si)) + { + int pnt_commelem = 0; + int pnum_commelem = 0; + Array pnt1_elems; + Array pnt2_elems; + + + meshtopo.GetVertexSurfaceElements(segpair_p1,pnt1_elems); + meshtopo.GetVertexSurfaceElements(segpair_p2,pnt2_elems); + for(int k = 1; k <= pnt1_elems.Size(); k++) + { + Element2d pnt1_sel = mesh.SurfaceElement(pnt1_elems.Elem(k)); + for(int l = 1; l <= pnt2_elems.Size(); l++) + { + Element2d pnt2_sel = mesh.SurfaceElement(pnt2_elems.Elem(l)); + if((pnt1_sel.GetIndex() == mesh.LineSegment(j).si) + && (pnt2_sel.GetIndex() == mesh.LineSegment(j).si) + && (pnt1_elems.Elem(k) == pnt2_elems.Elem(l))) + { + pnt_commelem = pnt1_elems.Elem(k); + } + } + } + + for(int k = 1; k <= mesh.SurfaceElement(pnt_commelem).GetNP(); k++) + { + if((mesh.SurfaceElement(pnt_commelem).PNum(k) != segpair_p1) + && (mesh.SurfaceElement(pnt_commelem).PNum(k) != segpair_p2)) + { + pnum_commelem = mesh.SurfaceElement(pnt_commelem).PNum(k); + } + } + + Vec3d surfelem_vect, surfelem_vect1; + + Element2d & commsel = mesh.SurfaceElement(pnt_commelem); + + dbg << "NP= " << commsel.GetNP() << " : "; + + for(int k = 1; k <= commsel.GetNP(); k++) + { + GetSurfaceNormal(mesh,commsel,k,surfelem_vect1); + surfelem_vect += surfelem_vect1; + } + + surfelem_vect.Normalize(); + + double surfangle = Angle(growthvectors.Elem(segpair_p1),surfelem_vect); + + dbg << "V1= " << surfelem_vect1 + << " : V2= " << surfelem_vect1 + << " : V= " << surfelem_vect + << " : GV= " << growthvectors.Elem(segpair_p1) + << " : Angle= " << surfangle * 180 / 3.141592; + + + // remap the segments to the new points + mesh.LineSegment(i)[0] = mapto.Get(seg_p1); + mesh.LineSegment(i)[1] = mapto.Get(seg_p2); + mesh.LineSegment(j)[1] = mapto.Get(seg_p1); + mesh.LineSegment(j)[0] = mapto.Get(seg_p2); + + if((surfangle < (90 + angleThreshold) * 3.141592 / 180.0) + && (surfangle > (90 - angleThreshold) * 3.141592 / 180.0)) + { + dbg << " : quad\n"; + // Since the surface is lower than the threshold, change the effective + // prism growth vector to match with the surface vector, so that + // the Quad which is created lies on the original surface + //growthvectors.Elem(segpair_p1) = surfelem_vect; + + // Add a quad element to account for the prism volume + // element which is going to be added + Element2d sel(QUAD); + sel.PNum(4) = mapto.Get(seg_p1); + sel.PNum(3) = mapto.Get(seg_p2); + sel.PNum(2) = segpair_p2; + sel.PNum(1) = segpair_p1; + sel.SetIndex(mesh.LineSegment(j).si); + mesh.AddSurfaceElement(sel); + numquads++; + } + else + { + dbg << "\n"; + for (int k = 1; k <= pnt1_elems.Size(); k++) + { + Element2d & pnt_sel = mesh.SurfaceElement(pnt1_elems.Elem(k)); + if(pnt_sel.GetIndex() == mesh.LineSegment(j).si) + { + for(int l = 1; l <= pnt_sel.GetNP(); l++) + { + if(pnt_sel.PNum(l) == segpair_p1) + { + pnt_sel.PNum(l) = mapto.Get(seg_p1); + } + else if(pnt_sel.PNum(l) == segpair_p2) + { + pnt_sel.PNum(l) = mapto.Get(seg_p2); + } + } + } + } + + for (int k = 1; k <= pnt2_elems.Size(); k++) + { + Element2d & pnt_sel = mesh.SurfaceElement(pnt2_elems.Elem(k)); + if(pnt_sel.GetIndex() == mesh.LineSegment(j).si) + { + for(int l = 1; l <= pnt_sel.GetNP(); l++) + { + if(pnt_sel.PNum(l) == segpair_p1) + { + pnt_sel.PNum(l) = mapto.Get(seg_p1); + } + else if(pnt_sel.PNum(l) == segpair_p2) + { + pnt_sel.PNum(l) = mapto.Get(seg_p2); + } + } + } + } + } + } + else + { + // If the code comes here, it indicates that we are at + // a line segment pair which is at the intersection + // of two surfaces, both of which have to grow boundary + // layers.... here too, remapping the segments to the + // new points is required + mesh.LineSegment(i)[0] = mapto.Get(seg_p1); + mesh.LineSegment(i)[1] = mapto.Get(seg_p2); + mesh.LineSegment(j)[1] = mapto.Get(seg_p1); + mesh.LineSegment(j)[0] = mapto.Get(seg_p2); + } + } + } + } + } + + // Add prismatic cells at the boundaries + cout << "Generating prism boundary layer volume elements...." << endl; + + for (i = 1; i <= nse; i++) + { + Element2d & sel = mesh.SurfaceElement(i); + if(surfid.Contains(sel.GetIndex())) + { + Element el(PRISM); + for (j = 1; j <= sel.GetNP(); j++) + { + // Check (Doublecheck) if the corresponding point has a + // copy available for remapping + if (mapto.Get(sel.PNum(j))) + { + // Define the points of the newly added Prism cell + el.PNum(j+3) = mapto.Get(sel.PNum(j)); + el.PNum(j) = sel.PNum(j); + } + } + + el.SetIndex(1); + el.Invert(); + mesh.AddVolumeElement(el); + numprisms++; + } + } + + // Finally switch the point indices of the surface elements + // to the newly added ones + cout << "Transferring boundary layer surface elements to new vertex references...." << endl; + + for (i = 1; i <= nse; i++) + { + Element2d & sel = mesh.SurfaceElement(i); + if(surfid.Contains(sel.GetIndex())) + { + for (j = 1; j <= sel.GetNP(); j++) + { + // Check (Doublecheck) if the corresponding point has a + // copy available for remapping + if (mapto.Get(sel.PNum(j))) + { + // Map the surface elements to the new points + sel.PNum(j) = mapto.Get(sel.PNum(j)); + } + } + } + } + + // Lock all the prism points so that the rest of the mesh can be + // optimised without invalidating the entire mesh + for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++) + { + if(bndnodes.Test(i)) mesh.AddLockedPoint(pi); + } + + // Now, actually pull back the old surface points to create + // the actual boundary layers + cout << "Moving and optimising boundary layer points...." << endl; + + for (i = 1; i <= np; i++) + { + Array vertelems; + + if(bndnodes.Test(i)) + { + MeshPoint pointtomove; + + pointtomove = mesh.Point(i); + + if(layer == prismlayers) + { + mesh.Point(i).SetPoint(pointtomove + layerht * growthvectors.Elem(i)); + + meshtopo.GetVertexElements(i,vertelems); + + for(j = 1; j <= vertelems.Size(); j++) + { + // double sfact = 0.9; + Element volel = mesh.VolumeElement(vertelems.Elem(j)); + if(((volel.GetType() == TET) || (volel.GetType() == TET10)) && (!volel.IsDeleted())) + { + //while((volel.Volume(mesh.Points()) <= 0.0) && (sfact >= 0.0)) + //{ + // mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i))); + // mesh.ImproveMesh(); + + // // Try to move the point back by one step but + // // if the volume drops to below zero, double back + // mesh.Point(i).SetPoint(pointtomove + ((sfact + 0.1) * layerht * growthvectors.Elem(i))); + // if(volel.Volume(mesh.Points()) <= 0.0) + // { + // mesh.Point(i).SetPoint(pointtomove + (sfact * layerht * growthvectors.Elem(i))); + // } + // sfact -= 0.1; + //} + volel.Delete(); + } + } + + mesh.Compress(); + } + else + { + mesh.Point(i).SetPoint(pointtomove + layerht * growthvectors.Elem(i)); + } + } + } + } + + // Optimise the tet part of the volume mesh after all the modifications + // to the system are completed + //OptimizeVolume(mparam,mesh); + + cout << "New NP: " << mesh.GetNP() << endl; + cout << "Num of Quads: " << numquads << endl; + cout << "Num of Prisms: " << numprisms << endl; + cout << "Boundary Layer Generation....Done!" << endl; + + dbg.close(); + } + +} + diff --git a/libsrc/meshing/boundarylayer.hpp b/libsrc/meshing/boundarylayer.hpp new file mode 100644 index 00000000..4bd46984 --- /dev/null +++ b/libsrc/meshing/boundarylayer.hpp @@ -0,0 +1,13 @@ +#ifndef FILE_BOUNDARYLAYER +#define FILE_BOUNDARYLAYER + + +/// +extern void InsertVirtualBoundaryLayer (Mesh & mesh); + +/// Create a typical prismatic boundary layer on the given +/// surfaces +extern void GenerateBoundaryLayer (Mesh & mesh, MeshingParameters & mp); + + +#endif diff --git a/libsrc/meshing/classifyhpel.hpp b/libsrc/meshing/classifyhpel.hpp new file mode 100644 index 00000000..c1555371 --- /dev/null +++ b/libsrc/meshing/classifyhpel.hpp @@ -0,0 +1,1728 @@ +HPREF_ELEMENT_TYPE ClassifyTet(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint) +{ + int ep1(0), ep2(0), ep3(0), ep4(0), cp1(0), cp2(0), cp3(0), cp4(0), fp1, fp2, fp3, fp4; + int isedge1(0), isedge2(0), isedge3(0), isedge4(0), isedge5(0), isedge6(0); + int isfedge1, isfedge2, isfedge3, isfedge4, isfedge5, isfedge6; + int isface1(0), isface2(0), isface3(0), isface4(0); + + HPREF_ELEMENT_TYPE type = HP_NONE; + + + int debug = 0; + for (int j = 0;j < 4; j++) + { + if (el.pnums[j] == 444) debug++; + if (el.pnums[j] == 115) debug++; + if (el.pnums[j] == 382) debug++; + if (el.pnums[j] == 281) debug++; + } + if (debug < 4) debug = 0; + + + + for (int j = 0; j < 4; j++) + for (int k = 0; k < 4; k++) + { + if (j == k) continue; + if (type) break; + + int pi3 = 0; + while (pi3 == j || pi3 == k) pi3++; + int pi4 = 6 - j - k - pi3; + + // preserve orientation + int sort[4]; + sort[0] = j; sort[1] = k; sort[2] = pi3; sort[3] = pi4; + int cnt = 0; + for (int jj = 0; jj < 4; jj++) + for (int kk = 0; kk < 3; kk++) + if (sort[kk] > sort[kk+1]) + { + cnt++; + Swap (sort[kk], sort[kk+1]); + } + if (cnt % 2 == 1) Swap (pi3, pi4); + + ep1 = edgepoint.Test (el.pnums[j]); + ep2 = edgepoint.Test (el.pnums[k]); + ep3 = edgepoint.Test (el.pnums[pi3]); + ep4 = edgepoint.Test (el.pnums[pi4]); + + cp1 = cornerpoint.Test (el.pnums[j]); + cp2 = cornerpoint.Test (el.pnums[k]); + cp3 = cornerpoint.Test (el.pnums[pi3]); + cp4 = cornerpoint.Test (el.pnums[pi4]); + + isedge1 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[k])); + isedge2 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi3])); + isedge3 = edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi4])); + isedge4 = edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi3])); + isedge5 = edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi4])); + isedge6 = edges.Used (INDEX_2::Sort (el.pnums[pi3], el.pnums[pi4])); + + if (debug) + { + cout << "debug" << endl; + *testout << "debug" << endl; + *testout << "ep = " << ep1 << ep2 << ep3 << ep4 << endl; + *testout << "cp = " << cp1 << cp2 << cp3 << cp4 << endl; + *testout << "edge = " << isedge1 << isedge2 << isedge3 << isedge4 << isedge5 << isedge6 << endl; + } + + + isface1 = isface2 = isface3 = isface4 = 0; + for (int l = 0; l < 4; l++) + { + INDEX_3 i3(0,0,0); + switch (l) + { + case 0: i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi3]; i3.I1() = el.pnums[pi4]; break; + case 1: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[pi3]; i3.I1() = el.pnums[pi4]; break; + case 2: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi4]; break; + case 3: i3.I1() = el.pnums[j]; i3.I1() = el.pnums[k]; i3.I1() = el.pnums[pi3]; break; + } + i3.Sort(); + if (faces.Used (i3)) + { + int domnr = faces.Get(i3); + if (domnr == -1 || domnr == el.GetIndex()) + { + switch (l) + { + case 0: isface1 = 1; break; + case 1: isface2 = 1; break; + case 2: isface3 = 1; break; + case 3: isface4 = 1; break; + } + } + } + } + /* + isface1 = faces.Used (INDEX_3::Sort (el.pnums[k], el.pnums[pi3], el.pnums[pi4])); + isface2 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[pi3], el.pnums[pi4])); + isface3 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[k], el.pnums[pi4])); + isface4 = faces.Used (INDEX_3::Sort (el.pnums[j], el.pnums[k], el.pnums[pi3])); + */ + + isfedge1 = isfedge2 = isfedge3 = isfedge4 = isfedge5 = isfedge6 = 0; + for (int l = 0; l < 6; l++) + { + INDEX_2 i2(0,0); + switch (l) + { + case 0: i2.I1() = el.pnums[j]; i2.I2() = el[k]; break; + case 1: i2.I1() = el.pnums[j]; i2.I2() = el.pnums[pi3]; break; + case 2: i2.I1() = el.pnums[j]; i2.I2() = el.pnums[pi4]; break; + case 3: i2.I1() = el.pnums[k]; i2.I2() = el.pnums[pi3]; break; + case 4: i2.I1() = el.pnums[k]; i2.I2() = el.pnums[pi4]; break; + case 5: i2.I1() = el.pnums[pi3]; i2.I2() = el.pnums[pi4]; break; + } + i2.Sort(); + if (face_edges.Used (i2)) + { + int domnr = face_edges.Get(i2); + if (domnr == -1 || domnr == el.GetIndex()) + { + switch (l) + { + case 0: isfedge1 = 1; break; + case 1: isfedge2 = 1; break; + case 2: isfedge3 = 1; break; + case 3: isfedge4 = 1; break; + case 4: isfedge5 = 1; break; + case 5: isfedge6 = 1; break; + } + } + } + } + /* + isfedge1 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[k])); + isfedge2 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi3])); + isfedge3 = face_edges.Used (INDEX_2::Sort (el.pnums[j], el.pnums[pi4])); + isfedge4 = face_edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi3])); + isfedge5 = face_edges.Used (INDEX_2::Sort (el.pnums[k], el.pnums[pi4])); + isfedge6 = face_edges.Used (INDEX_2::Sort (el.pnums[pi3], el.pnums[pi4])); + */ + + fp1 = fp2 = fp3 = fp4 = 0; + for (int l = 0; l < 4; l++) + { + int pti(0); + switch (l) + { + case 0: pti = el.pnums[j]; break; + case 1: pti = el.pnums[k]; break; + case 2: pti = el.pnums[pi3]; break; + case 3: pti = el.pnums[pi4]; break; + } + int domnr = facepoint[pti]; + if (domnr == -1 || domnr == el.GetIndex()) + { + switch (l) + { + case 0: fp1 = 1; break; + case 1: fp2 = 1; break; + case 2: fp3 = 1; break; + case 3: fp4 = 1; break; + } + } + } + + /* + fp1 = facepoint[el.pnums[j]] != 0; + fp2 = facepoint[el.pnums[k]] != 0; + fp3 = facepoint[el.pnums[pi3]] != 0; + fp4 = facepoint[el.pnums[pi4]] != 0; + */ + + + switch (isface1+isface2+isface3+isface4) + { + case 0: + { + isedge1 |= isfedge1; + isedge2 |= isfedge2; + isedge3 |= isfedge3; + isedge4 |= isfedge4; + isedge5 |= isfedge5; + isedge6 |= isfedge6; + + ep1 |= fp1; + ep2 |= fp2; + ep3 |= fp3; + ep4 |= fp4; + + switch (isedge1+isedge2+isedge3+isedge4+isedge5+isedge6) + { + case 0: + { + if (!ep1 && !ep2 && !ep3 && !ep4) + type = HP_TET; + + if (ep1 && !ep2 && !ep3 && !ep4) + type = HP_TET_0E_1V; + + if (ep1 && ep2 && !ep3 && !ep4) + type = HP_TET_0E_2V; + + if (ep1 && ep2 && ep3 && !ep4) + type = HP_TET_0E_3V; + + if (ep1 && ep2 && ep3 && ep4) + type = HP_TET_0E_4V; + + break; + } + + case 1: + { + if (!isedge1) break; + + if (!cp1 && !cp2 && !ep3 && !ep4) + type = HP_TET_1E_0V; + + if (cp1 && !cp2 && !ep3 && !ep4) + type = HP_TET_1E_1VA; + + if (!cp1 && !cp2 && !ep3 && ep4) + type = HP_TET_1E_1VB; + + if (cp1 && cp2 && !ep3 && !ep4) + type = HP_TET_1E_2VA; + + if (cp1 && !cp2 && ep3 && !ep4) + type = HP_TET_1E_2VB; + + if (cp1 && !cp2 && !ep3 && ep4) + type = HP_TET_1E_2VC; + + if (!cp1 && !cp2 && ep3 && ep4) + type = HP_TET_1E_2VD; + + if (cp1 && cp2 && ep3 && !ep4) + type = HP_TET_1E_3VA; + + if (cp1 && !cp2 && ep3 && ep4) + type = HP_TET_1E_3VB; + + if (cp1 && cp2 && ep3 && ep4) + type = HP_TET_1E_4V; + + break; + } + case 2: + { + if (isedge1 && isedge2) + { + if (!cp2 && !cp3 && !ep4) + type = HP_TET_2EA_0V; + + if (cp2 && !cp3 && !ep4) + type = HP_TET_2EA_1VA; + if (!cp2 && cp3 && !ep4) + type = HP_TET_2EA_1VB; + + if (!cp2 && !cp3 && ep4) + type = HP_TET_2EA_1VC; + + if (cp2 && cp3 && !ep4) + type = HP_TET_2EA_2VA; + if (cp2 && !cp3 && ep4) + type = HP_TET_2EA_2VB; + if (!cp2 && cp3 && ep4) + type = HP_TET_2EA_2VC; + + if (cp2 && cp3 && ep4) + type = HP_TET_2EA_3V; + } + if (isedge1 && isedge6) + { + if (!cp1 && !cp2 && !cp3 && !cp4) + type = HP_TET_2EB_0V; + if (cp1 && !cp2 && !cp3 && !cp4) + type = HP_TET_2EB_1V; + if (cp1 && cp2 && !cp3 && !cp4) + type = HP_TET_2EB_2VA; + if (cp1 && !cp2 && cp3 && !cp4) + type = HP_TET_2EB_2VB; + if (cp1 && !cp2 && !cp3 && cp4) + type = HP_TET_2EB_2VC; + if (cp1 && cp2 && cp3 && !cp4) + type = HP_TET_2EB_3V; + if (cp1 && cp2 && cp3 && cp4) + type = HP_TET_2EB_4V; + } + break; + } + case 3: + { + if (isedge1 && isedge2 && isedge3) + { + if (!cp2 && !cp3 && !cp4) + type = HP_TET_3EA_0V; + if (cp2 && !cp3 && !cp4) + type = HP_TET_3EA_1V; + if (cp2 && cp3 && !cp4) + type = HP_TET_3EA_2V; + if (cp2 && cp3 && cp4) + type = HP_TET_3EA_3V; + } + if (isedge1 && isedge3 && isedge4) + { + if (!cp3 && !cp4) + type = HP_TET_3EB_0V; + if (cp3 && !cp4) + type = HP_TET_3EB_1V; + if (cp3 && cp4) + type = HP_TET_3EB_2V; + } + if (isedge1 && isedge2 && isedge5) + { + if (!cp3 && !cp4) + type = HP_TET_3EC_0V; + if (cp3 && !cp4) + type = HP_TET_3EC_1V; + if (cp3 && cp4) + type = HP_TET_3EC_2V; + } + break; + } + } + break; + } + + + + case 1: // one singular face + { + if (!isface1) break; + + switch (isfedge1+isfedge2+isfedge3+isedge4+isedge5+isedge6) + { + case 0: + { + if (!fp1 && !ep2 && !ep3 && !ep4) + type = HP_TET_1F_0E_0V; + if (fp1 && !ep2 && !ep3 && !ep4) + type = HP_TET_1F_0E_1VB; + if (!fp1 && ep2 && !ep3 & !ep4) + type = HP_TET_1F_0E_1VA; + break; + } + case 1: + { + if (isfedge1) + { + if (!ep1 && !ep3 && !ep4) + type = HP_TET_1F_1EA_0V; + } + if (isedge4) // V1-V3 + { + if (!ep1 && !cp2 && !cp3 && !ep4) + type = HP_TET_1F_1EB_0V; + } + break; + } + } + break; + } + + + case 2: // two singular faces + { + if (!isface1 || !isface2) break; + + switch (isfedge1+isedge2+isedge3+isedge4+isedge5) + { + case 0: + { + if (!ep1 && !ep2 && !cp3 && !cp4) + type = HP_TET_2F_0E_0V; + break; + } + } + break; + } + + + } + + if (type != HP_NONE) + { + int pnums[4]; + pnums[0] = el.pnums[j]; + pnums[1] = el.pnums[k]; + pnums[2] = el.pnums[pi3]; + pnums[3] = el.pnums[pi4]; + for(k=0;k<4;k++) el.pnums[k] = pnums[k]; + break; + } + } + + + if (debug) cout << "type = " << type << endl; + + if (type == HP_NONE) + { + // cnt_undef++; + (*testout) << "undefined element" << endl + << "cp = " << cp1 << cp2 << cp3 << cp4 << endl + << "ep = " << ep1 << ep2 << ep3 << ep4 << endl + << "isedge = " << isedge1 << isedge2 << isedge3 + << isedge4 << isedge5 << isedge6 << endl + << "isface = " << isface1 << isface2 << isface3 << isface4 << endl; + cout << "undefined element !!! " << endl; + + + } + return(type); +} + + + +HPREF_ELEMENT_TYPE ClassifyPrism(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint) +{ + + HPREF_ELEMENT_TYPE type = HP_NONE; + + int p[6]; + for(int m=1;m<=6;m++) + { + int point_sing[6]={0,0,0,0,0,0}; + int face_sing[5]={0,0,0,0,0}; + int edge_sing[9]={0,0,0,0,0,0,0,0,0}; + + if(m<4) + { + p[0]= m; p[1]=m%3+1; p[2]=(m%3+1)%3+1; + for(int l=3;l<6;l++) p[l]=p[l-3]+3; + } + else + { + p[0] = m; p[1]=(m%3+1)%3+4; p[2]=m%3+4; + for(int l=3;l<6;l++) p[l]=p[l-3]-3; + } + + for(int j=0;j<6;j++) + { + if(cornerpoint.Test(el.PNum(p[j]))) { point_sing[p[j]-1]=3;} + else if(edgepoint.Test(el.PNum(p[j]))) point_sing[p[j]-1]=2; + else if (facepoint[el.PNum(p[j])] == -1 || facepoint[el.PNum(p[j])] == el.GetIndex()) + point_sing[p[j]-1] = 1; + } + + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges1 (PRISM); + for(int k=0;k<9;k++) + { + INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); + if (edges.Used(i2)) edge_sing[k] = 2; + else edge_sing[k] = face_edges.Used(i2); + } + + const ELEMENT_FACE * elfaces = MeshTopology::GetFaces1 (PRISM); + for (int k=0;k<5;k++) + { + INDEX_3 i3; + + if(k<2) + i3 = INDEX_3::Sort(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], + el.pnums[p[elfaces[k][2]-1]-1]); + else + { + INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + } + + if (faces.Used (i3)) + { + int domnr = faces.Get(i3); + if (domnr == -1 || domnr == el.GetIndex()) + face_sing[k] = 1; + + } + } + if (face_sing[1] > face_sing[0]) {m=m+2; continue;} + + + //int cp = 0; + + int qfsing = face_sing[2] + face_sing[3] + face_sing[4]; + int tfsing = face_sing[0] + face_sing[1]; + int evsing = edge_sing[6] + edge_sing[7] + edge_sing[8]; + int ehsing = edge_sing[0] + edge_sing[1] + edge_sing[2] + edge_sing[3] + edge_sing[4] + edge_sing[5]; + + if (qfsing + tfsing + evsing + ehsing == 0) + { type = HP_PRISM; break;} + + HPREF_ELEMENT_TYPE types[] = {HP_NONE,HP_NONE,HP_NONE}; + + int fb = (1-face_sing[4])* face_sing[3] * (face_sing[2] + face_sing[3]) + 3*face_sing[4]*face_sing[3]*face_sing[2]; + int sve[3] = {edge_sing[7] , edge_sing[8], edge_sing[6]}; + + + if(fb!=qfsing) continue; + + + switch(fb) + { + case 0: + if (evsing == 0 && ehsing==3*tfsing) + { + types[0] = HP_PRISM; + types[1] = HP_PRISM_1FA_0E_0V; + types[2] = HP_PRISM_2FA_0E_0V; + } + if(evsing > 0 && sve[0] == evsing) // 1 vertical edge 1-4 + { + types[0] = HP_PRISM_SINGEDGE; + types[1] = HP_PRISM_1FA_1E_0V; + types[2] = HP_PRISM_2FA_1E_0V; + } + + if(sve[0] > 0 && sve[1] > 0 && sve[2] == 0) + { + types[0] = HP_PRISM_SINGEDGE_V12; + types[1] = HP_PRISM_1FA_2E_0V; + types[2] = HP_PRISM_2FA_2E_0V; + } + if(sve[0] > 0 && sve[1] > 0 && sve[2] > 0) + { + types[0] = HP_PRISM_3E_0V; + types[1] = HP_PRISM_1FA_3E_0V; + types[2] = HP_PRISM_2FA_3E_0V; + + if ( edge_sing[0] > 1 && edge_sing[2] > 1 && + edge_sing[4] > 1 && edge_sing[5] > 1 && tfsing==0) + types[0] = HP_PRISM_3E_4EH; + } + + break; + case 1: + if(sve[0] <= 1 && sve[1] <= 1) + { + if(sve[2]==0) + { + types[0] = HP_PRISM_1FB_0E_0V; + types[1] = HP_PRISM_1FA_1FB_0E_0V; + types[2] = HP_PRISM_2FA_1FB_0E_0V; + } + else + { + types[0] = HP_PRISM_1FB_1EC_0V; + types[1] = HP_PRISM_1FA_1FB_1EC_0V; + types[2] = HP_PRISM_2FA_1FB_1EC_0V; + } + } + + if(sve[0] > 1 && sve[2] >= 1 && sve[1] <= 1) + { + types[0] = HP_PRISM_1FB_2EB_0V; + types[1] = HP_PRISM_1FA_1FB_2EB_0V; + types[2] = HP_PRISM_2FA_1FB_2EB_0V; + } + + if(sve[0] > 1 && sve[1] <= 1 && sve[2] == 0) // ea && !eb + { + types[0] = HP_PRISM_1FB_1EA_0V; + types[1] = HP_PRISM_1FA_1FB_1EA_0V; + types[2] = HP_PRISM_2FA_1FB_1EA_0V; + } + + if(sve[0] <= 1 && sve[1] > 1 && sve[2] == 0) + types[1] = HP_PRISM_1FA_1FB_1EB_0V; + + if(sve[0] > 1 && sve[1]>1) + if(sve[2] == 0) // ea && eb + { + types[0] = HP_PRISM_1FB_2EA_0V; + types[1] = HP_PRISM_1FA_1FB_2EA_0V; + types[2] = HP_PRISM_2FA_1FB_2EA_0V; + } + if(sve[0] <= 1 && sve[1] > 1 && sve[2] >0) + types[1] = HP_PRISM_1FA_1FB_2EC_0V; + + if(sve[0] > 1 && sve[1] > 1 && sve[2] >= 1) //sve[2] can also be a face-edge + { + types[0] = HP_PRISM_1FB_3E_0V; + types[1] = HP_PRISM_1FA_1FB_3E_0V; + types[2] = HP_PRISM_2FA_1FB_3E_0V; + } + + break; + + case 2: + if(sve[0] <= 1) + cout << " **** WARNING: Edge between to different singular faces should be marked singular " << endl; + + if(sve[1] <= 1) + if(sve[2] <=1) + { + types[0] = HP_PRISM_2FB_0E_0V; + types[1] = HP_PRISM_1FA_2FB_0E_0V; + types[2] = HP_PRISM_2FA_2FB_0E_0V; + } + else + { + types[0] = HP_PRISM_2FB_1EC_0V; + types[1] = HP_PRISM_1FA_2FB_1EC_0V; + types[2] = HP_PRISM_2FA_2FB_1EC_0V; + } + else + if(sve[2] <= 1) + types[1] = HP_PRISM_1FA_2FB_1EB_0V; + else + { + types[0] = HP_PRISM_2FB_3E_0V; + types[1] = HP_PRISM_1FA_2FB_3E_0V; + types[2] = HP_PRISM_2FA_2FB_3E_0V; + } + + break; + + case 3: + types[0] = HP_PRISM_3FB_0V; + types[1] = HP_PRISM_1FA_3FB_0V; + types[2] = HP_PRISM_2FA_3FB_0V; + break; + } + type = types[tfsing]; + + + if(type != HP_NONE) + break; + } + + /* + *testout << " Prism with pnums " << endl; + for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; + *testout << endl; + */ + + if(type != HP_NONE) + { + int pnums[6]; + for(int j=0;j<6;j++) pnums[j] = el.PNum (p[j]); + for(int k=0;k<6;k++) el.pnums[k] = pnums[k]; + } + + /* *testout << " Classified Prism with pnums " << endl; + for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; + *testout << endl; + */ + return(type); +} + + +// #ifdef SABINE +HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint, int dim, const FaceDescriptor & fd) + +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + int pnums[3]; + int p[3]; + + INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]); + i3.Sort(); + bool sing_face = faces.Used (i3); + + // *testout << " facepoint " << facepoint << endl; + + + // Try all rotations of the trig + for (int j=0;j<3;j++) + { + int point_sing[3] = {0,0,0}; + int edge_sing[3] = {0,0,0}; + // *testout << " actual rotation of trig points " ; + for(int m=0;m<3;m++) + { + p[m] = (j+m)%3 +1; // local vertex number + pnums[m] = el.PNum(p[m]); // global vertex number + // *testout << pnums[m] << " \t "; + } + // *testout << endl ; + + if(dim == 3) + { + // face point + for(int k=0;k<3;k++) + if(!sing_face) + { + // *testout << " fp [" << k << "] = " << facepoint[pnums[k]] << endl; + // *testout << " fd.DomainIn()" << fd.DomainIn() << endl; + // *testout << " fd.DomainOut()" << fd.DomainOut() << endl; + if( facepoint[pnums[k]] && (facepoint[pnums[k]] ==-1 || + facepoint[pnums[k]] == fd.DomainIn() || facepoint[pnums[k]] == fd.DomainOut())) + point_sing[p[k]-1] = 1; + } + // if point is on face_edge in next step sing = 2 + + /* *testout << " pointsing NACH FACEPOints ... FALLS EDGEPOINT UMSETZEN" ; + for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ; + *testout << endl; */ + } + + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges1(TRIG); + + if(dim==3) + { + for(int k=0;k<3;k++) + { + int ep1=p[eledges[k][0]-1]; + int ep2=p[eledges[k][1]-1]; + INDEX_2 i2(el.PNum(ep1),el.PNum(ep2)); + + if(edges.Used(i2)) + { + + edge_sing[k]=2; + point_sing[ep1-1] = 2; + point_sing[ep2-1] = 2; + } + else // face_edge? + { + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1) // edge not face_edge acc. to surface in which trig lies + { + if(face_edges.Get(i2)==-1 ||face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut() ) + { + edge_sing[k]=1; + } + else + { + point_sing[ep1-1] = 0; // set to edge_point + point_sing[ep2-1] = 0; // set to edge_point + } + } + } + + /* *testout << " pointsing NACH edges UND FACEEDGES UMSETZEN ... " ; + for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ; + *testout << endl; + */ + } + } + /* + *testout << " dim " << dim << endl; + *testout << " edgepoint_dom " << edgepoint_dom << endl; + */ + if(dim==2) + { + for(int k=0;k<3;k++) + { + int ep1=p[eledges[k][0]-1]; + int ep2=p[eledges[k][1]-1]; + + INDEX_2 i2(el.PNum(ep1),el.PNum(ep2)); + + if(edges.Used(i2)) + { + + if(edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep1-1])) || + edgepoint_dom.Used(INDEX_2(-1,pnums[ep1-1])) || + edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep2-1])) || + edgepoint_dom.Used(INDEX_2(-1,pnums[ep2-1]))) + { + edge_sing[k]=2; + point_sing[ep1-1] = 2; + point_sing[ep2-1] = 2; + } + } + + } + } + + + + for(int k=0;k<3;k++) + if(edgepoint.Test(pnums[k])) //edgepoint, but not member of sing_edge on trig -> cp + { + INDEX_2 i2a=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+1)%3])); + INDEX_2 i2b=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+2)%3])); + + if(!edges.Used(i2a) && !edges.Used(i2b)) + point_sing[p[k]-1] = 3; + } + + for(int k=0;k<3;k++) + if(cornerpoint.Test(el.PNum(p[k]))) + point_sing[p[k]-1] = 3; + + *testout << "point_sing = " << point_sing[0] << point_sing[1] << point_sing[2] << endl; + + if(edge_sing[0] + edge_sing[1] + edge_sing[2] == 0) + { + int ps = point_sing[0] + point_sing[1] + point_sing[2]; + + if(ps==0) + type = HP_TRIG; + else if(point_sing[p[0]-1] && !point_sing[p[1]-1] && !point_sing[p[2]-1]) + type = HP_TRIG_SINGCORNER; + else if(point_sing[p[0]-1] && point_sing[p[1]-1] && !point_sing[p[2]-1]) + type = HP_TRIG_SINGCORNER12; + else if(point_sing[p[0]-1] && point_sing[p[1]-1] && point_sing[p[2]-1]) + { + if(dim==2) type = HP_TRIG_SINGCORNER123_2D; + else type = HP_TRIG_SINGCORNER123; + } + } + else + if (edge_sing[2] && !edge_sing[0] && !edge_sing[1]) //E[2]=(1,2) + { + int code = 0; + if(point_sing[p[0]-1] > edge_sing[2]) code+=1; + if(point_sing[p[1]-1] > edge_sing[2]) code+=2; + if(point_sing[p[2]-1]) code+=4; + + HPREF_ELEMENT_TYPE types[] = + { + HP_TRIG_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER12, + HP_TRIG_SINGEDGECORNER3, + HP_TRIG_SINGEDGECORNER13, + HP_TRIG_SINGEDGECORNER23, + HP_TRIG_SINGEDGECORNER123, + }; + type = types[code]; + + } // E[0] = [0,2], E[1] =[1,2], E[2] = [0,1] + else + if(edge_sing[2] && !edge_sing[1] && edge_sing[0]) + { + if(point_sing[p[2]-1] <= edge_sing[0] ) + { + if(point_sing[p[1]-1]<= edge_sing[2]) type = HP_TRIG_SINGEDGES; + else type = HP_TRIG_SINGEDGES2; + } + else + { + if(point_sing[p[1]-1]<= edge_sing[2]) + type = HP_TRIG_SINGEDGES3; + else type = HP_TRIG_SINGEDGES23; + } + } + else if (edge_sing[2] && edge_sing[1] && edge_sing[0]) + type = HP_TRIG_3SINGEDGES; + + // cout << " run for " << j << " gives type " << type << endl; + //*testout << " run for " << j << " gives type " << type << endl; + + if(type!=HP_NONE) break; + } + + *testout << "type = " << type << endl; + + for(int k=0;k<3;k++) el[k] = pnums[k]; + /*if(type != HP_NONE) + { + + cout << " TRIG with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << endl; + cout << " type " << type << endl; + } + */ + return(type); +} +#ifdef HPREF_OLD +HPREF_ELEMENT_TYPE ClassifyTrig(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint, int dim, const FaceDescriptor & fd) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + int pnums[3]; + + INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]); + i3.Sort(); + bool sing_face = faces.Used (i3); + + + for (int j = 1; j <= 3; j++) + { + int ep1 = edgepoint.Test (el.PNumMod (j)); + int ep2 = edgepoint.Test (el.PNumMod (j+1)); + int ep3 = edgepoint.Test (el.PNumMod (j+2)); + + if (dim == 2) + { + // JS, Dec 11 + ep1 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j))) || + edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j))); + ep2 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+1))) || + edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+1))); + ep3 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+2))) || + edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+2))); + /* + ep1 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j))); + ep2 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+1))); + ep3 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+2))); + */ + // ep3 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+2))); + } + + + + int cp1 = cornerpoint.Test (el.PNumMod (j)); + int cp2 = cornerpoint.Test (el.PNumMod (j+1)); + int cp3 = cornerpoint.Test (el.PNumMod (j+2)); + + ep1 |= cp1; + ep2 |= cp2; + ep3 |= cp3; + + + // (*testout) << "cp = " << cp1 << cp2 << cp3 << ", ep = " << ep1 << ep2 << ep3 << endl; + + int p[3] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2)}; + if(ep1) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[0], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp1 = 1; + } + if(ep2) + { + INDEX_2 i2a=INDEX_2::Sort(p[1], p[0]); + INDEX_2 i2b=INDEX_2::Sort(p[1], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp2 = 1; + } + if(ep3) + { + INDEX_2 i2a=INDEX_2::Sort(p[2], p[0]); + INDEX_2 i2b=INDEX_2::Sort(p[2], p[1]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp3= 1; + } + + + int isedge1=0, isedge2=0, isedge3=0; + if(dim == 3 ) + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + isedge1 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge1=1; + ep1 = 1; ep2=1; + } + + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + isedge2 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge2=1; + ep2 = 1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + isedge3 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge3=1; + ep1 = 1; ep3=1; + } + + // cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl; + + if (!sing_face) + { + /* + if (!isedge1) { cp1 |= ep1; cp2 |= ep2; } + if (!isedge2) { cp2 |= ep2; cp3 |= ep3; } + if (!isedge3) { cp3 |= ep3; cp1 |= ep1; } + */ + ep1 |= facepoint [el.PNumMod(j)] != 0; + ep2 |= facepoint [el.PNumMod(j+1)] != 0; + ep3 |= facepoint [el.PNumMod(j+2)] != 0; + + + isedge1 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1))); + isedge2 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+1), el.PNumMod(j+2))); + isedge3 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+2), el.PNumMod(j+3))); + } + } + + if(dim ==2) + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + i2.Sort(); + isedge1 = edges.Used (i2); + if(isedge1) + { + ep1 = 1; ep2=1; + } + + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + i2.Sort(); + isedge2 = edges.Used (i2); + if(isedge2) + { + ep2 = 1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + i2.Sort(); + isedge3 = edges.Used (i2); + if(isedge3) + { + ep1 = 1; ep3=1; + } + + + } + + + /* + cout << " used " << face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1))) << endl; + + cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl; + cout << " ep " << ep1 << "\t" << ep2 << " \t " << ep3 << endl; + cout << " cp " << cp1 << "\t" << cp2 << " \t " << cp3 << endl; + */ + + + + if (isedge1 + isedge2 + isedge3 == 0) + { + if (!ep1 && !ep2 && !ep3) + type = HP_TRIG; + + if (ep1 && !ep2 && !ep3) + type = HP_TRIG_SINGCORNER; + + if (ep1 && ep2 && !ep3) + type = HP_TRIG_SINGCORNER12; + + if (ep1 && ep2 && ep3) + { + if (dim == 2) + type = HP_TRIG_SINGCORNER123_2D; + else + type = HP_TRIG_SINGCORNER123; + } + + if (type != HP_NONE) + { + pnums[0] = el.PNumMod (j); + pnums[1] = el.PNumMod (j+1); + pnums[2] = el.PNumMod (j+2); + break; + } + } + + if (isedge1 && !isedge2 && !isedge3) + { + int code = 0; + if (cp1) code += 1; + if (cp2) code += 2; + if (ep3) code += 4; + + HPREF_ELEMENT_TYPE types[] = + { + HP_TRIG_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER12, + HP_TRIG_SINGEDGECORNER3, + HP_TRIG_SINGEDGECORNER13, + HP_TRIG_SINGEDGECORNER23, + HP_TRIG_SINGEDGECORNER123, + }; + type = types[code]; + pnums[0] = el.PNumMod (j); + pnums[1] = el.PNumMod (j+1); + pnums[2] = el.PNumMod (j+2); + break; + } + + + if (isedge1 && !isedge2 && isedge3) + { + if (!cp3) + { + if (!cp2) type = HP_TRIG_SINGEDGES; + else type = HP_TRIG_SINGEDGES2; + } + else + { + if (!cp2) type = HP_TRIG_SINGEDGES3; + else type = HP_TRIG_SINGEDGES23; + } + + pnums[0] = el.PNumMod (j); + pnums[1] = el.PNumMod (j+1); + pnums[2] = el.PNumMod (j+2); + break; + } + + if (isedge1 && isedge2 && isedge3) + { + type = HP_TRIG_3SINGEDGES; + pnums[0] = el.PNumMod (j); + pnums[1] = el.PNumMod (j+1); + pnums[2] = el.PNumMod (j+2); + break; + } + } + + for(int k=0;k<3;k++) el[k] = pnums[k]; + /*if(type != HP_NONE) + { + + cout << " TRIG with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << endl; + cout << " type " << type << endl; + } + */ + return(type); +} +#endif +HPREF_ELEMENT_TYPE ClassifyQuad(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint, int dim, const FaceDescriptor & fd) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + int ep1(-1), ep2(-1), ep3(-1), ep4(-1), cp1(-1), cp2(-1), cp3(-1), cp4(-1); + int isedge1, isedge2, isedge3, isedge4; + + *testout << "edges = " << edges << endl; + + for (int j = 1; j <= 4; j++) + { + ep1 = edgepoint.Test (el.PNumMod (j)); + ep2 = edgepoint.Test (el.PNumMod (j+1)); + ep3 = edgepoint.Test (el.PNumMod (j+2)); + ep4 = edgepoint.Test (el.PNumMod (j+3)); + + if (dim == 2) + { + ep1 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j))); + ep2 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+1))); + ep3 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+2))); + ep4 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+3))); + } + + cp1 = cornerpoint.Test (el.PNumMod (j)); + cp2 = cornerpoint.Test (el.PNumMod (j+1)); + cp3 = cornerpoint.Test (el.PNumMod (j+2)); + cp4 = cornerpoint.Test (el.PNumMod (j+3)); + + ep1 |= cp1; + ep2 |= cp2; + ep3 |= cp3; + ep4 |= cp4; + + int p[4] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2), el.PNumMod(j+4)}; + //int epp[4] = { ep1, ep2, ep3, ep4}; + int cpp[4] = { cp1, cp2, cp3, cp4}; + for(int k=0;k<0;k++) + { + INDEX_2 i2a=INDEX_2::Sort(p[k], p[(k+1)%4]); + INDEX_2 i2b=INDEX_2::Sort(p[k], p[(k-1)%4]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cpp[k] = 1; + } + cp1= cpp[0]; cp2=cpp[1]; cp3=cpp[2]; cp4=cpp[3]; + + + if(dim ==3) + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + // i2.Sort(); + isedge1 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge1=1; + ep1 = 1; ep2=1; + } + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + // i2.Sort(); + isedge2 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge2=1; + ep2=1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + // i2.Sort(); + isedge3 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge3=1; + ep3=1; ep4=1; + } + i2 = INDEX_2(el.PNumMod (j+3), el.PNumMod (j+4)); + // i2.Sort(); + isedge4 = edges.Used (i2); + i2.Sort(); + if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1 && + (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) + { + isedge4=1; + ep4=1; ep1=1; + } + + + //MH*********************************************************************************************************** + if(ep1) + if(edgepoint.Test(p[0])) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[0], p[3]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp1 = 1; + } + if(ep2) + if(edgepoint.Test(p[1])) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[1], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp2 = 1; + } + if(ep3) + if(edgepoint.Test(p[2])) + { + INDEX_2 i2a=INDEX_2::Sort(p[2], p[1]); + INDEX_2 i2b=INDEX_2::Sort(p[3], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp3 = 1; + } + if(ep4) + if(edgepoint.Test(p[3])) + { + INDEX_2 i2a=INDEX_2::Sort(p[0], p[3]); + INDEX_2 i2b=INDEX_2::Sort(p[3], p[2]); + if(!edges.Used(i2a) && !edges.Used(i2b)) + cp4 = 1; + } + //MH***************************************************************************************************************************** + } + else + { + INDEX_2 i2; + i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1)); + i2.Sort(); + isedge1 = edges.Used (i2); + if(isedge1) + { + ep1 = 1; ep2=1; + } + i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2)); + i2.Sort(); + isedge2 = edges.Used (i2); + if(isedge2) + { + ep2=1; ep3=1; + } + i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3)); + i2.Sort(); + isedge3 = edges.Used (i2); + + if(isedge3) + { + ep3=1; ep4=1; + } + i2 = INDEX_2(el.PNumMod (j+3), el.PNumMod (j+4)); + i2.Sort(); + isedge4 = edges.Used (i2); + if(isedge4) + { + ep4=1; ep1=1; + } + } + + int sumcp = cp1 + cp2 + cp3 + cp4; + int sumep = ep1 + ep2 + ep3 + ep4; + int sumedge = isedge1 + isedge2 + isedge3 + isedge4; + + *testout << "isedge = " << isedge1 << isedge2 << isedge3 << isedge4 << endl; + *testout << "iscp = " << cp1 << cp2 << cp3 << cp4 << endl; + *testout << "isep = " << ep1 << ep2 << ep3 << ep4 << endl; + + switch (sumedge) + { + case 0: + { + switch (sumep) + { + case 0: + type = HP_QUAD; + break; + case 1: + if (ep1) type = HP_QUAD_SINGCORNER; + break; + case 2: + { + if (ep1 && ep2) type = HP_QUAD_0E_2VA; + if (ep1 && ep3) type = HP_QUAD_0E_2VB; + break; + } + case 3: + if (!ep4) type = HP_QUAD_0E_3V; + break; + case 4: + type = HP_QUAD_0E_4V; + break; + } + break; + } + case 1: + { + if (isedge1) + { + switch (cp1+cp2+ep3+ep4) + { + case 0: + type = HP_QUAD_SINGEDGE; + break; + case 1: + { + if (cp1) type = HP_QUAD_1E_1VA; + if (cp2) type = HP_QUAD_1E_1VB; + if (ep3) type = HP_QUAD_1E_1VC; + if (ep4) type = HP_QUAD_1E_1VD; + break; + } + case 2: + { + if (cp1 && cp2) type = HP_QUAD_1E_2VA; + if (cp1 && ep3) type = HP_QUAD_1E_2VB; + if (cp1 && ep4) type = HP_QUAD_1E_2VC; + if (cp2 && ep3) type = HP_QUAD_1E_2VD; + if (cp2 && ep4) type = HP_QUAD_1E_2VE; + if (ep3 && ep4) type = HP_QUAD_1E_2VF; + break; + } + case 3: + { + if (cp1 && cp2 && ep3) type = HP_QUAD_1E_3VA; + if (cp1 && cp2 && ep4) type = HP_QUAD_1E_3VB; + if (cp1 && ep3 && ep4) type = HP_QUAD_1E_3VC; + if (cp2 && ep3 && ep4) type = HP_QUAD_1E_3VD; + break; + } + case 4: + { + type = HP_QUAD_1E_4V; + break; + } + } + } + break; + } + case 2: + { + if (isedge1 && isedge4) + { + if (!cp2 && !ep3 && !cp4) + type = HP_QUAD_2E; + + if (cp2 && !ep3 && !cp4) + type = HP_QUAD_2E_1VA; + if (!cp2 && ep3 && !cp4) + type = HP_QUAD_2E_1VB; + if (!cp2 && !ep3 && cp4) + type = HP_QUAD_2E_1VC; + + if (cp2 && ep3 && !cp4) + type = HP_QUAD_2E_2VA; + if (cp2 && !ep3 && cp4) + type = HP_QUAD_2E_2VB; + if (!cp2 && ep3 && cp4) + type = HP_QUAD_2E_2VC; + + if (cp2 && ep3 && cp4) + type = HP_QUAD_2E_3V; + } + if (isedge1 && isedge3) + { + switch (sumcp) + { + case 0: + type = HP_QUAD_2EB_0V; break; + case 1: + { + if (cp1) type = HP_QUAD_2EB_1VA; + if (cp2) type = HP_QUAD_2EB_1VB; + break; + } + case 2: + { + if (cp1 && cp2) { type = HP_QUAD_2EB_2VA; } + if (cp1 && cp3) { type = HP_QUAD_2EB_2VB; } + if (cp1 && cp4) { type = HP_QUAD_2EB_2VC; } + if (cp2 && cp4) { type = HP_QUAD_2EB_2VD; } + break; + } + case 3: + { + if (cp1 && cp2 && cp3) { type = HP_QUAD_2EB_3VA; } + if (cp1 && cp2 && cp4) { type = HP_QUAD_2EB_3VB; } + break; + } + case 4: + { + type = HP_QUAD_2EB_4V; break; + } + } + } + break; + } + + case 3: + { + if (isedge1 && isedge2 && isedge4) + { + if (!cp3 && !cp4) type = HP_QUAD_3E; + if (cp3 && !cp4) type = HP_QUAD_3E_3VA; + if (!cp3 && cp4) type = HP_QUAD_3E_3VB; + if (cp3 && cp4) type = HP_QUAD_3E_4V; + } + break; + } + + case 4: + { + type = HP_QUAD_4E; + break; + } + } + + if (type != HP_NONE) + { + int pnums[4]; + pnums[0] = el.PNumMod (j); + pnums[1] = el.PNumMod (j+1); + pnums[2] = el.PNumMod (j+2); + pnums[3] = el.PNumMod (j+3); + for (int k=0;k<4;k++) el[k] = pnums[k]; + + /* cout << " QUAD with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << "\t" << pnums[3] + << endl << " of type " << type << endl; */ + + break; + } + } + if (type == HP_NONE) + { + (*testout) << "undefined element" << endl + << "cp = " << cp1 << cp2 << cp3 << cp4 << endl + << "ep = " << ep1 << ep2 << ep3 << ep4 << endl + << "isedge = " << isedge1 << isedge2 << isedge3 + << isedge4 << endl; + } + + *testout << "quad type = " << type << endl; + + return type; +} + + +HPREF_ELEMENT_TYPE ClassifyHex(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + // implementation only for HP_HEX_1F_0E_0V + // HP_HEX_1FA_1FB_0E_0V + // HP_HEX + // up to now other cases are refine dummies + + // indices of bot,top-faces combinations + int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; + int p[8]; + const ELEMENT_FACE * elfaces = MeshTopology::GetFaces1 (HEX); + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges1 (HEX); + + for(int m=0;m<6 && type == HP_NONE;m++) + for(int j=0;j<4 && type == HP_NONE;j++) + { + int point_sing[8]={0,0,0,0,0,0,0,0}; + int face_sing[6] = {0,0,0,0,0,0}; + int edge_sing[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; + int spoint=0, sface=0, sedge=0; + for(int l=0;l<4;l++) + { + p[l] = elfaces[index[m][0]][(4-j-l)%4]; + p[l+4] = elfaces[index[m][1]][(j+l)%4]; + } + + for(int l=0;l<8;l++) + if(cornerpoint.Test(el.PNum(p[l]))) + { + point_sing[p[l]-1]=3; + spoint++; + } + else if(edgepoint.Test(el.PNum(p[l]))) point_sing[p[l]-1]=2; + else if (facepoint[el.PNum(p[l])] == -1 || facepoint[el.PNum(p[l])] == el.GetIndex()) + point_sing[p[l]-1] = 1; + + for(int k=0;k<12;k++) + { + INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); + if (edges.Used(i2)) + { + edge_sing[k] = 2; + sedge++; + } + else edge_sing[k] = face_edges.Used(i2); + } + + for (int k=0;k<6;k++) + { + INDEX_3 i3; + + + INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + + if (faces.Used (i3)) + { + + int domnr = faces.Get(i3); + if (domnr == -1 || domnr == el.GetIndex()) + { + face_sing[k] = 1; + sface++; + } + + } + } + + if(!sface && !sedge && !spoint) type = HP_HEX; + if(!sedge && !spoint) + { + if(face_sing[0] && face_sing[2] && sface==2) + type = HP_HEX_1FA_1FB_0E_0V; + if (face_sing[0] && sface==1) + type = HP_HEX_1F_0E_0V; + } + + el.type=type; + + if(type != HP_NONE) + { + int pnums[8]; + for(int l=0;l<8;l++) pnums[l] = el[p[l]-1]; + for(int l=0;l<8;l++) el[l] = pnums[l]; + /* cout << " HEX with pnums " << pnums[0] << "\t" << + pnums[1] << "\t" << pnums[2] << "\t" << pnums[3] << "\t" << + pnums[4] << "\t" << pnums[5] << endl << " of type " << type << endl; */ + break; + } + } + + return (type); + +} + +HPREF_ELEMENT_TYPE ClassifySegm(HPRefElement & hpel, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint) +{ + + int cp1 = cornerpoint.Test (hpel[0]); + int cp2 = cornerpoint.Test (hpel[1]); + + INDEX_2 i2; + i2 = INDEX_2(hpel[0], hpel[1]); + i2.Sort(); + if (!edges.Used (i2)) + { + cp1 = edgepoint.Test (hpel[0]); + cp2 = edgepoint.Test (hpel[1]); + } + + if(!edges.Used(i2) && !face_edges.Used(i2)) + { + if(facepoint[hpel[0]]!=0) cp1=1; + if(facepoint[hpel[1]]!=0) cp2=1; + } + + if(edges.Used(i2) && !face_edges.Used(i2)) + { + if(facepoint[hpel[0]]) cp1 = 1; + if(facepoint[hpel[1]]) cp2 = 1; + } + + if (!cp1 && !cp2) + hpel.type = HP_SEGM; + else if (cp1 && !cp2) + hpel.type = HP_SEGM_SINGCORNERL; + else if (!cp1 && cp2) + hpel.type = HP_SEGM_SINGCORNERR; + else + hpel.type = HP_SEGM_SINGCORNERS; + + // cout << " SEGM found with " << hpel[0] << " \t" << hpel[1] << endl << " of type " << hpel.type << endl; + return(hpel.type) ; +} + + +HPREF_ELEMENT_TYPE ClassifyPyramid(HPRefElement & el, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint) +{ + HPREF_ELEMENT_TYPE type = HP_NONE; + + // implementation only for HP_PYRAMID + // HP_PYRAMID_0E_1V + // HP_PYRAMID_EDGES + // HP_PYRAMID_1FB_0E_1VA + // up to now other cases are refine dummies + + // indices of bot,top-faces combinations + // int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; + + const ELEMENT_FACE * elfaces = MeshTopology::GetFaces1 (PYRAMID); + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges1 (PYRAMID); + + int point_sing[5]={0,0,0,0,0}; + int face_sing[5] = {0,0,0,0,0}; + int edge_sing[8] = {0,0,0,0,0,0,0,0}; + + int spoint=0, sedge=0, sface=0; + + for(int m=0;m<4 && type == HP_NONE;m++) + { + int p[5] = {m%4, m%4+1, m%4+2, m%4+3, 4}; + + for(int l=0;l<5;l++) + { + if(cornerpoint.Test(el.pnums[p[l]])) + point_sing[l]=3; + + else if(edgepoint.Test(el.pnums[p[l]])) + point_sing[l]=2; + + else if (facepoint[el.pnums[p[l]]] == -1 || facepoint[el.pnums[p[l]]] == el.GetIndex()) + point_sing[l] = 1; + + spoint += point_sing[l]; + } + + for(int k=0;k<8;k++) + { + INDEX_2 i2 = INDEX_2 :: Sort(el.pnums[p[eledges[k][0]-1]], + el.pnums[p[eledges[k][1]-1]]); + if (edges.Used(i2)) + edge_sing[k] = 2; + else + edge_sing[k] = face_edges.Used(i2); + + sedge += edge_sing[k]; + } + + for (int k=0;k<5;k++) + { + INDEX_3 i3; + INDEX_4 i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]], el.pnums[p[elfaces[k][1]-1]], el.pnums[p[elfaces[k][2]-1]], + el.pnums[p[elfaces[k][3]-1]]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + + if (faces.Used (i3)) + { + + int domnr = faces.Get(i3); + if (domnr == -1 || domnr == el.GetIndex()) + face_sing[k] = 1; + } + sface +=face_sing[k]; + } + + if(!sface && !spoint && !sedge) return(HP_PYRAMID); + + if(!sface && !sedge && point_sing[p[0]] == spoint) + type = HP_PYRAMID_0E_1V; + + if(!sface && edge_sing[0] + edge_sing[2] == sedge && + spoint == point_sing[0] + point_sing[1] + point_sing[3]) + type = HP_PYRAMID_EDGES; + + if(sface && sface == face_sing[0] && spoint == point_sing[4] + 2) + type = HP_PYRAMID_1FB_0E_1VA; + + + if(type != HP_NONE) + { + int pnums[8]; + for(int l=0;l<5;l++) pnums[l] = el[p[l]]; + for(int l=0;l<5;l++) el[l] = pnums[l]; + el.type=type; + break; + } + } + + return (type); + +} diff --git a/libsrc/meshing/clusters.cpp b/libsrc/meshing/clusters.cpp new file mode 100644 index 00000000..ddc399c9 --- /dev/null +++ b/libsrc/meshing/clusters.cpp @@ -0,0 +1,282 @@ +#include + +#include "meshing.hpp" + +namespace netgen +{ + + AnisotropicClusters :: AnisotropicClusters (const Mesh & amesh) + : mesh(amesh) + { + ; + } + + AnisotropicClusters :: ~AnisotropicClusters () + { + ; + } + + void AnisotropicClusters :: Update() + { + const MeshTopology & top = mesh.GetTopology(); + + bool hasedges = top.HasEdges(); + bool hasfaces = top.HasFaces(); + + if (!hasedges || !hasfaces) return; + + if (id == 0) + PrintMessage (3, "Update clusters"); + + nv = mesh.GetNV(); + ned = top.GetNEdges(); + nfa = top.GetNFaces(); + ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + + cluster_reps.SetSize (nv+ned+nfa+ne); + cluster_reps = -1; + + Array llist (nv+ned+nfa+ne); + llist = 0; + + Array nnums, ednums, fanums; + int changed; + + + + for (int i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + ELEMENT_TYPE typ = el.GetType(); + + top.GetElementEdges (i, ednums); + top.GetElementFaces (i, fanums); + + int elnv = top.GetNVertices (typ); + int elned = ednums.Size(); + int elnfa = fanums.Size(); + + nnums.SetSize(elnv+elned+elnfa+1); + for (int j = 1; j <= elnv; j++) + nnums.Elem(j) = el.PNum(j); + for (int j = 1; j <= elned; j++) + nnums.Elem(elnv+j) = nv+ednums.Elem(j); + for (int j = 1; j <= elnfa; j++) + nnums.Elem(elnv+elned+j) = nv+ned+fanums.Elem(j); + nnums.Elem(elnv+elned+elnfa+1) = nv+ned+nfa+i; + + for (int j = 0; j < nnums.Size(); j++) + cluster_reps.Elem(nnums[j]) = nnums[j]; + } + + + + for (int i = 1; i <= nse; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + ELEMENT_TYPE typ = el.GetType(); + + top.GetSurfaceElementEdges (i, ednums); + int fanum = top.GetSurfaceElementFace (i); + + int elnv = top.GetNVertices (typ); + int elned = ednums.Size(); + + nnums.SetSize(elnv+elned+1); + for (int j = 1; j <= elnv; j++) + nnums.Elem(j) = el.PNum(j); + for (int j = 1; j <= elned; j++) + nnums.Elem(elnv+j) = nv+ednums.Elem(j); + nnums.Elem(elnv+elned+1) = fanum; + + for (int j = 0; j < nnums.Size(); j++) + cluster_reps.Elem(nnums[j]) = nnums[j]; + } + + static const int hex_cluster[] = + { + 1, 2, 3, 4, 1, 2, 3, 4, + 5, 6, 7, 8, 5, 6, 7, 8, 1, 2, 3, 4, + 9, 9, 5, 8, 6, 7, + 9 + }; + + static const int prism_cluster[] = + { + 1, 2, 3, 1, 2, 3, + 4, 5, 6, 4, 5, 6, 3, 1, 2, + 7, 7, 4, 5, 6, + 7 + }; + + static const int pyramid_cluster[] = + { + 1, 2, 2, 1, 3, + 4, 2, 1, 4, 6, 5, 5, 6, + 7, 5, 7, 6, 4, + 7 + }; + static const int tet_cluster14[] = + { 1, 2, 3, 1, 1, 4, 5, 4, 5, 6, 7, 5, 4, 7, 7 }; + + static const int tet_cluster12[] = + { 1, 1, 2, 3, 4, 4, 5, 1, 6, 6, 7, 7, 4, 6, 7 }; + + static const int tet_cluster13[] = + { 1, 2, 1, 3, 4, 6, 4, 5, 1, 5, 7, 4, 7, 5, 7 }; + + static const int tet_cluster23[] = + { 2, 1, 1, 3, 6, 5, 5, 4, 4, 1, 5, 7, 7, 4, 7 }; + + static const int tet_cluster24[] = + { 2, 1, 3, 1, 4, 1, 5, 4, 6, 5, 5, 7, 4, 7, 7 }; + + static const int tet_cluster34[] = + { 2, 3, 1, 1, 4, 5, 1, 6, 4, 5, 5, 4, 7, 7, 7 }; + + int cnt = 0; + + do + { + + cnt++; + changed = 0; + + for (int i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + ELEMENT_TYPE typ = el.GetType(); + + top.GetElementEdges (i, ednums); + top.GetElementFaces (i, fanums); + + int elnv = top.GetNVertices (typ); + int elned = ednums.Size(); + int elnfa = fanums.Size(); + + nnums.SetSize(elnv+elned+elnfa+1); + for (int j = 1; j <= elnv; j++) + nnums.Elem(j) = el.PNum(j); + for (int j = 1; j <= elned; j++) + nnums.Elem(elnv+j) = nv+ednums.Elem(j); + for (int j = 1; j <= elnfa; j++) + nnums.Elem(elnv+elned+j) = nv+ned+fanums.Elem(j); + nnums.Elem(elnv+elned+elnfa+1) = nv+ned+nfa+i; + + + const int * clustertab = NULL; + switch (typ) + { + case PRISM: + case PRISM12: + clustertab = prism_cluster; + break; + case HEX: + clustertab = hex_cluster; + break; + case PYRAMID: + clustertab = pyramid_cluster; + break; + case TET: + case TET10: + if (cluster_reps.Get(el.PNum(1)) == + cluster_reps.Get(el.PNum(2))) + clustertab = tet_cluster12; + else if (cluster_reps.Get(el.PNum(1)) == + cluster_reps.Get(el.PNum(3))) + clustertab = tet_cluster13; + else if (cluster_reps.Get(el.PNum(1)) == + cluster_reps.Get(el.PNum(4))) + clustertab = tet_cluster14; + else if (cluster_reps.Get(el.PNum(2)) == + cluster_reps.Get(el.PNum(3))) + clustertab = tet_cluster23; + else if (cluster_reps.Get(el.PNum(2)) == + cluster_reps.Get(el.PNum(4))) + clustertab = tet_cluster24; + else if (cluster_reps.Get(el.PNum(3)) == + cluster_reps.Get(el.PNum(4))) + clustertab = tet_cluster34; + + else + clustertab = NULL; + break; + default: + clustertab = NULL; + } + + if (clustertab) + for (int j = 0; j < nnums.Size(); j++) + for (int k = 0; k < j; k++) + if (clustertab[j] == clustertab[k]) + { + int jj = nnums[j]; + int kk = nnums[k]; + + if (cluster_reps.Get(kk) < cluster_reps.Get(jj)) + swap (jj,kk); + + if (cluster_reps.Get(jj) < cluster_reps.Get(kk)) + { + /* + cluster_reps.Elem(kk) = cluster_reps.Get(jj); + changed = 1; + */ + + int rep = cluster_reps.Get(jj); + int next = cluster_reps.Get(kk); + do + { + int cur = next; + next = llist.Elem(next); + + cluster_reps.Elem(cur) = rep; + llist.Elem(cur) = llist.Elem(rep); + llist.Elem(rep) = cur; + } + while (next); + changed = 1; + } + } + + /* + if (clustertab) + { + if (typ == PYRAMID) + (*testout) << "pyramid"; + else if (typ == PRISM || typ == PRISM12) + (*testout) << "prism"; + else if (typ == TET || typ == TET10) + (*testout) << "tet"; + else + (*testout) << "unknown type" << endl; + + (*testout) << ", nnums = "; + for (j = 0; j < nnums.Size(); j++) + (*testout) << "node " << j << " = " << nnums[j] << ", rep = " + << cluster_reps.Get(nnums[j]) << endl; + } + */ + } + } + while (changed); + + /* + (*testout) << "cluster reps:" << endl; + for (i = 1; i <= cluster_reps.Size(); i++) + { + (*testout) << i << ": "; + if (i <= nv) + (*testout) << "v" << i << " "; + else if (i <= nv+ned) + (*testout) << "e" << i-nv << " "; + else if (i <= nv+ned+nfa) + (*testout) << "f" << i-nv-ned << " "; + else + (*testout) << "c" << i-nv-ned-nfa << " "; + (*testout) << cluster_reps.Get(i) << endl; + } + */ + } +} diff --git a/libsrc/meshing/clusters.hpp b/libsrc/meshing/clusters.hpp new file mode 100644 index 00000000..fa0de93a --- /dev/null +++ b/libsrc/meshing/clusters.hpp @@ -0,0 +1,42 @@ +#ifndef CLUSTERS +#define CLUSTERS + +/**************************************************************************/ +/* File: clusers.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 28. Apr. 01 */ +/**************************************************************************/ + +/* + Anisotropic clusters + + nodes, edges, faces, elements +*/ + + +class AnisotropicClusters +{ + const Mesh & mesh; + + int nv, ned, nfa, ne; + + // connected nodes, nodes = vertices, edges, faces, elements + Array cluster_reps; + +public: + AnisotropicClusters (const Mesh & amesh); + ~AnisotropicClusters(); + + void Update(); + + int GetVertexRepresentant (int vnr) const + { return cluster_reps.Get(vnr); } + int GetEdgeRepresentant (int ednr) const + { return cluster_reps.Get(nv+ednr); } + int GetFaceRepresentant (int fnr) const + { return cluster_reps.Get(nv+ned+fnr); } + int GetElementRepresentant (int enr) const + { return cluster_reps.Get(nv+ned+nfa+enr); } +}; + +#endif diff --git a/libsrc/meshing/curvedelems.cpp b/libsrc/meshing/curvedelems.cpp new file mode 100644 index 00000000..ad322e1c --- /dev/null +++ b/libsrc/meshing/curvedelems.cpp @@ -0,0 +1,3792 @@ +#include + +#include "meshing.hpp" + +#include "../general/autodiff.hpp" + + +namespace netgen +{ + + // bool rational = true; + + + static void ComputeGaussRule (int n, Array & xi, Array & wi) + { + xi.SetSize (n); + wi.SetSize (n); + + int m = (n+1)/2; + double p1, p2, p3; + double pp, z, z1; + for (int i = 1; i <= m; i++) + { + z = cos ( M_PI * (i - 0.25) / (n + 0.5)); + while(1) + { + p1 = 1; p2 = 0; + for (int j = 1; j <= n; j++) + { + p3 = p2; p2 = p1; + p1 = ((2 * j - 1) * z * p2 - (j - 1) * p3) / j; + } + // p1 is legendre polynomial + + pp = n * (z*p1-p2) / (z*z - 1); + z1 = z; + z = z1-p1/pp; + + if (fabs (z - z1) < 1e-14) break; + } + + xi[i-1] = 0.5 * (1 - z); + xi[n-i] = 0.5 * (1 + z); + wi[i-1] = wi[n-i] = 1.0 / ( (1 - z * z) * pp * pp); + } + } + + + + // compute edge bubbles up to order n, x \in (-1, 1) + static void CalcEdgeShape (int n, double x, double * shape) + { + double p1 = x, p2 = -1, p3 = 0; + for (int j=2; j<=n; j++) + { + p3=p2; p2=p1; + p1=( (2*j-3) * x * p2 - (j-3) * p3) / j; + shape[j-2] = p1; + } + } + + static void CalcEdgeDx (int n, double x, double * dshape) + { + double p1 = x, p2 = -1, p3 = 0; + double p1dx = 1, p2dx = 0, p3dx = 0; + + for (int j=2; j<=n; j++) + { + p3=p2; p2=p1; + p3dx = p2dx; p2dx = p1dx; + + p1=( (2*j-3) * x * p2 - (j-3) * p3) / j; + p1dx = ( (2*j-3) * (x * p2dx + p2) - (j-3) * p3dx) / j; + + dshape[j-2] = p1dx; + } + } + + static void CalcEdgeShapeDx (int n, double x, double * shape, double * dshape) + { + double p1 = x, p2 = -1, p3 = 0; + double p1dx = 1, p2dx = 0, p3dx = 0; + + for (int j=2; j<=n; j++) + { + p3=p2; p2=p1; + p3dx = p2dx; p2dx = p1dx; + + p1=( (2*j-3) * x * p2 - (j-3) * p3) / j; + p1dx = ( (2*j-3) * (x * p2dx + p2) - (j-3) * p3dx) / j; + + shape[j-2] = p1; + dshape[j-2] = p1dx; + } + } + + // compute L_i(x/t) * t^i + static void CalcScaledEdgeShape (int n, double x, double t, double * shape) + { + static bool init = false; + static double coefs[100][2]; + if (!init) + { + for (int j = 0; j < 100; j++) + { + coefs[j][0] = double(2*j+1)/(j+2); + coefs[j][1] = -double(j-1)/(j+2); + } + init = true; + } + + double p1 = x, p2 = -1, p3 = 0; + double tt = t*t; + for (int j=0; j<=n-2; j++) + { + p3=p2; p2=p1; + p1= coefs[j][0] * x * p2 + coefs[j][1] * tt*p3; + // p1=( (2*j+1) * x * p2 - t*t*(j-1) * p3) / (j+2); + shape[j] = p1; + } + } + + template + static void CalcScaledEdgeShapeDxDt (int n, double x, double t, double * dshape) + { + double p1 = x, p2 = -1, p3 = 0; + double p1dx = 1, p1dt = 0; + double p2dx = 0, p2dt = 0; + double p3dx = 0, p3dt = 0; + + for (int j=0; j<=n-2; j++) + { + p3=p2; p3dx=p2dx; p3dt = p2dt; + p2=p1; p2dx=p1dx; p2dt = p1dt; + + p1 = ( (2*j+1) * x * p2 - t*t*(j-1) * p3) / (j+2); + p1dx = ( (2*j+1) * (x * p2dx + p2) - t*t*(j-1) * p3dx) / (j+2); + p1dt = ( (2*j+1) * x * p2dt - (j-1)* (t*t*p3dt+2*t*p3)) / (j+2); + + // shape[j] = p1; + dshape[DIST*j ] = p1dx; + dshape[DIST*j+1] = p1dt; + } + } + + + template + static void LegendrePolynomial (int n, Tx x, Tres * values) + { + switch (n) + { + case 0: + values[0] = 1; + break; + case 1: + values[0] = 1; + values[1] = x; + break; + + default: + + if (n < 0) return; + + Tx p1 = 1.0, p2 = 0.0, p3; + + values[0] = 1.0; + for (int j=1; j<=n; j++) + { + p3 = p2; p2 = p1; + p1 = ((2.0*j-1.0)*x*p2 - (j-1.0)*p3) / j; + values[j] = p1; + } + } + } + + template + static void ScaledLegendrePolynomial (int n, Tx x, Tt t, Tres * values) + { + switch (n) + { + case 0: + values[0] = 1.0; + break; + + case 1: + values[0] = 1.0; + values[1] = x; + break; + + default: + + if (n < 0) return; + + Tx p1 = 1.0, p2 = 0.0, p3; + values[0] = 1.0; + for (int j=1; j<=n; j++) + { + p3 = p2; p2 = p1; + p1 = ((2.0*j-1.0)*x*p2 - t*t*(j-1.0)*p3) / j; + values[j] = p1; + } + } + } + + class RecPol + { + protected: + int maxorder; + double *a, *b, *c; + public: + RecPol (int amaxorder) + { + maxorder = amaxorder; + a = new double[maxorder+1]; + b = new double[maxorder+1]; + c = new double[maxorder+1]; + } + ~RecPol () + { + delete [] a; + delete [] b; + delete [] c; + } + + template + void Evaluate (int n, S x, T * values) + { + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) + p2 = values[0] = 1.0; + if (n >= 1) + p1 = values[1] = a[0]+b[0]*x; + + for (int i = 1; i < n; i++) + { + p3 = p2; p2=p1; + p1 = (a[i]+b[i]*x)*p2-c[i]*p3; + values[i+1] = p1; + } + } + + template + void EvaluateScaled (int n, S x, S y, T * values) + { + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) + p2 = values[0] = 1.0; + if (n >= 1) + p1 = values[1] = a[0]*y+b[0]*x; + + for (int i = 1; i < n; i++) + { + p3 = p2; p2=p1; + p1 = (a[i]*y+b[i]*x)*p2-c[i]*y*y*p3; + values[i+1] = p1; + } + } + }; + + class JacobiRecPol : public RecPol + { + public: + JacobiRecPol (int amo, double al, double be) + : RecPol (amo) + { + for (int i = 0; i <= maxorder; i++) + { + double den = 2*(i+1)*(i+al+be+1)*(2*i+al+be); + a[i] = (2*i+al+be+1)*(al*al-be*be) / den; + b[i] = (2*i+al+be)*(2*i+al+be+1)*(2*i+al+be+2) / den; + c[i] = 2*(i+al)*(i+be)*(2*i+al+be+2) / den; + } + } + }; + + + + template + inline void JacobiPolynomial (int n, S x, double alpha, double beta, T * values) + { + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) + p2 = values[0] = 1.0; + if (n >= 1) + p1 = values[1] = 0.5 * (2*(alpha+1)+(alpha+beta+2)*(x-1)); + + for (int i = 1; i < n; i++) + { + p3 = p2; p2=p1; + p1 = + 1.0 / ( 2 * (i+1) * (i+alpha+beta+1) * (2*i+alpha+beta) ) * + ( + ( (2*i+alpha+beta+1)*(alpha*alpha-beta*beta) + + (2*i+alpha+beta)*(2*i+alpha+beta+1)*(2*i+alpha+beta+2) * x) + * p2 + - 2*(i+alpha)*(i+beta) * (2*i+alpha+beta+2) * p3 + ); + values[i+1] = p1; + } + } + + + + + template + inline void ScaledJacobiPolynomial (int n, S x, St t, double alpha, double beta, T * values) + { + /* + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) values[0] = 1.0; + */ + + S p1 = 1.0, p2 = 0.0, p3; + + if (n >= 0) + p2 = values[0] = 1.0; + if (n >= 1) + p1 = values[1] = 0.5 * (2*(alpha+1)*t+(alpha+beta+2)*(x-t)); + + for (int i=1; i < n; i++) + { + p3 = p2; p2=p1; + p1 = + 1.0 / ( 2 * (i+1) * (i+alpha+beta+1) * (2*i+alpha+beta) ) * + ( + ( (2*i+alpha+beta+1)*(alpha*alpha-beta*beta) * t + + (2*i+alpha+beta)*(2*i+alpha+beta+1)*(2*i+alpha+beta+2) * x) + * p2 + - 2*(i+alpha)*(i+beta) * (2*i+alpha+beta+2) * t * t * p3 + ); + values[i+1] = p1; + } + } + + + static Array jacpols2; + + + // compute face bubbles up to order n, 0 < y, y-x < 1, x+y < 1 + template + static void CalcTrigShape (int n, Tx x, Ty y, Ts * shape) + { + // static int timer = NgProfiler::CreateTimer ("Curvedels - CalcTrigShape"); + // NgProfiler::RegionTimer reg (timer); + + if (n < 3) return; + Tx hx[50], hy[50*50]; + // ScaledJacobiPolynomial (n-3, x, 1-y, 2, 2, hx); + /* + cout << "scaled jacobi, old: " << endl; + for (int i = 0; i <= n-3; i++) + cout << i << ": " << hx[i] << endl; + */ + jacpols2[2] -> EvaluateScaled (n-3, x, 1-y, hx); + /* + cout << "scaled jacobi, new: " << endl; + for (int i = 0; i <= n-3; i++) + cout << i << ": " << hx[i] << endl; + */ + // for (int ix = 0; ix <= n-3; ix++) + // JacobiPolynomial (n-3, 2*y-1, 2*ix+5, 2, hy+50*ix); + + for (int ix = 0; ix <= n-3; ix++) + jacpols2[2*ix+5] -> Evaluate (n-3, 2*y-1, hy+50*ix); + + int ii = 0; + + Tx bub = (1+x-y)*y*(1-x-y); + for (int ix = 0; ix <= n-3; ix++) + hx[ix] *= bub; + + for (int iy = 0; iy <= n-3; iy++) + for (int ix = 0; ix <= n-3-iy; ix++) + shape[ii++] = hx[ix]*hy[iy+50*ix]; + } + + + static void CalcTrigShapeDxDy (int n, double x, double y, double * dshape) + { + if (n < 3) return; + + AutoDiff<2> adx(x, 0); + AutoDiff<2> ady(y, 1); + AutoDiff<2> res[2000]; + CalcTrigShape (n, adx, ady, &res[0]); + int ndof = (n-1)*(n-2)/2; + for (int i = 0; i < ndof; i++) + { + dshape[2*i] = res[i].DValue(0); + dshape[2*i+1] = res[i].DValue(1); + } + } + + + // compute face bubbles up to order n, 0 < y, y-x < 1, x+y < 1 + template + static void CalcScaledTrigShape (int n, Tx x, Ty y, Tt t, Tr * shape) + { + if (n < 3) return; + + Tx hx[50], hy[50*50]; + // ScaledLegendrePolynomial (n-3, (2*x-1), t-y, hx); + ScaledJacobiPolynomial (n-3, x, t-y, 2, 2, hx); + + // ScaledLegendrePolynomial (n-3, (2*y-1), t, hy); + for (int ix = 0; ix <= n-3; ix++) + jacpols2[2*ix+5] -> EvaluateScaled (n-3, 2*y-1, t, hy+50*ix); + // ScaledJacobiPolynomial (n-3, 2*y-1, t, 2*ix+5, 2, hy+50*ix); + + + int ii = 0; + Tx bub = (t+x-y)*y*(t-x-y); + for (int iy = 0; iy <= n-3; iy++) + for (int ix = 0; ix <= n-3-iy; ix++) + shape[ii++] = bub * hx[ix]*hy[iy+50*ix]; + } + + + // compute face bubbles up to order n, 0 < y, y-x < 1, x+y < 1 + static void CalcScaledTrigShapeDxDyDt (int n, double x, double y, double t, double * dshape) + { + if (n < 3) return; + AutoDiff<3> adx(x, 0); + AutoDiff<3> ady(y, 1); + AutoDiff<3> adt(t, 2); + AutoDiff<3> res[2000]; + CalcScaledTrigShape (n, adx, ady, adt, &res[0]); + int ndof = (n-1)*(n-2)/2; + for (int i = 0; i < ndof; i++) + { + dshape[3*i] = res[i].DValue(0); + dshape[3*i+1] = res[i].DValue(1); + dshape[3*i+2] = res[i].DValue(2); + } + } + + + + CurvedElements :: CurvedElements (const Mesh & amesh) + : mesh (amesh) + { + order = 1; + rational = 0; + ishighorder = 0; + } + + + CurvedElements :: ~CurvedElements() + { + for (int i = 0; i < jacpols2.Size(); i++) + delete jacpols2[i]; + jacpols2.SetSize(0); + } + + + void CurvedElements :: BuildCurvedElements(const Refinement * ref, int aorder, + bool arational) + { + bool working = (ntasks == 1) || (id > 0); + + ishighorder = 0; + order = 1; + + +#ifdef PARALLEL + enum { MPI_TAG_CURVE = MPI_TAG_MESH+20 }; + + const ParallelMeshTopology & partop = mesh.GetParallelTopology (); + MPI_Comm curve_comm; + MPI_Comm_dup (MPI_COMM_WORLD, &curve_comm); + Array procs; +#endif + + if (working) + order = aorder; + + if (mesh.coarsemesh) + { + mesh.coarsemesh->GetCurvedElements().BuildCurvedElements (ref, aorder, arational); + order = aorder; + rational = arational; + ishighorder = (order > 1); + return; + } + + + PrintMessage (1, "Curve elements, order = ", aorder); + if (rational) PrintMessage (1, "curved elements with rational splines"); + + if (working) + const_cast (mesh).UpdateTopology(); + const MeshTopology & top = mesh.GetTopology(); + + rational = arational; + + Array edgenrs; + int nedges = top.GetNEdges(); + int nfaces = top.GetNFaces(); + + edgeorder.SetSize (nedges); + faceorder.SetSize (nfaces); + + edgeorder = 1; + faceorder = 1; + + if (rational) + { + edgeweight.SetSize (nedges); + edgeweight = 1.0; + } + + + if (aorder <= 1) + { + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + if (mesh[ei].GetType() == TET10) + ishighorder = 1; + return; + } + + + if (rational) aorder = 2; + + if (working) + { + if (mesh.GetDimension() == 3) + for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) + { + top.GetEdges (i, edgenrs); + for (int j = 0; j < edgenrs.Size(); j++) + edgeorder[edgenrs[j]] = aorder; + faceorder[top.GetFace (i)] = aorder; + } + for (SegmentIndex i = 0; i < mesh.GetNSeg(); i++) + edgeorder[top.GetEdge (i)] = aorder; + } + + if (rational) + { + edgeorder = 2; + faceorder = 1; + } + + +#ifdef PARALLEL + TABLE send_orders(ntasks), recv_orders(ntasks); + + if (ntasks > 1 && working) + { + for (int e = 0; e < edgeorder.Size(); e++) + { + partop.GetDistantEdgeNums (e+1, procs); + for (int j = 0; j < procs.Size(); j++) + send_orders.Add (procs[j], edgeorder[e]); + } + for (int f = 0; f < faceorder.Size(); f++) + { + partop.GetDistantFaceNums (f+1, procs); + for (int j = 0; j < procs.Size(); j++) + send_orders.Add (procs[j], faceorder[f]); + } + } + + + MyMPI_ExchangeTable (send_orders, recv_orders, MPI_TAG_CURVE, curve_comm); + + if (ntasks > 1 && working) + { + Array cnt(ntasks); + cnt = 0; + for (int e = 0; e < edgeorder.Size(); e++) + { + partop.GetDistantEdgeNums (e+1, procs); + for (int j = 0; j < procs.Size(); j++) + edgeorder[e] = max(edgeorder[e], recv_orders[procs[j]][cnt[procs[j]]++]); + } + for (int f = 0; f < faceorder.Size(); f++) + { + partop.GetDistantFaceNums (f+1, procs); + for (int j = 0; j < procs.Size(); j++) + faceorder[f] = max(faceorder[f], recv_orders[procs[j]][cnt[procs[j]]++]); + } + } +#endif + + + edgecoeffsindex.SetSize (nedges+1); + int nd = 0; + for (int i = 0; i < nedges; i++) + { + edgecoeffsindex[i] = nd; + nd += max (0, edgeorder[i]-1); + } + edgecoeffsindex[nedges] = nd; + + edgecoeffs.SetSize (nd); + edgecoeffs = Vec<3> (0,0,0); + + + facecoeffsindex.SetSize (nfaces+1); + nd = 0; + for (int i = 0; i < nfaces; i++) + { + facecoeffsindex[i] = nd; + if (top.GetFaceType(i+1) == TRIG) + nd += max (0, (faceorder[i]-1)*(faceorder[i]-2)/2); + else + nd += max (0, sqr(faceorder[i]-1)); + } + facecoeffsindex[nfaces] = nd; + + facecoeffs.SetSize (nd); + facecoeffs = Vec<3> (0,0,0); + + + if (!ref || aorder <= 1) + { + order = aorder; + return; + } + + Array xi, weight; + + ComputeGaussRule (aorder+4, xi, weight); // on (0,1) + + if (!jacpols2.Size()) + { + jacpols2.SetSize (100); + for (int i = 0; i < 100; i++) + jacpols2[i] = new JacobiRecPol (100, i, 2); + } + + PrintMessage (3, "Curving edges"); + + if (mesh.GetDimension() == 3 || rational) + { + Array surfnr(nedges); + Array gi0(nedges); + Array gi1(nedges); + surfnr = -1; + + if (working) + for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) + { + top.GetEdges (i, edgenrs); + const Element2d & el = mesh[i]; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges0 (el.GetType()); + + for (int i2 = 0; i2 < edgenrs.Size(); i2++) + { + PointIndex pi1 = el[edges[i2][0]]; + PointIndex pi2 = el[edges[i2][1]]; + + bool swap = pi1 > pi2; + + Point<3> p1 = mesh[pi1]; + Point<3> p2 = mesh[pi2]; + + int order1 = edgeorder[edgenrs[i2]]; + int ndof = max (0, order1-1); + + surfnr[edgenrs[i2]] = mesh.GetFaceDescriptor(el.GetIndex()).SurfNr(); + gi0[edgenrs[i2]] = el.GeomInfoPi(edges[i2][0]+1); + gi1[edgenrs[i2]] = el.GeomInfoPi(edges[i2][1]+1); + } + } + + +#ifdef PARALLEL + if (ntasks > 1) + { + // distribute it ... + TABLE senddata(ntasks), recvdata(ntasks); + if (working) + for (int e = 0; e < nedges; e++) + { + partop.GetDistantEdgeNums (e+1, procs); + for (int j = 0; j < procs.Size(); j++) + { + senddata.Add (procs[j], surfnr[e]); + if (surfnr[e] != -1) + { + senddata.Add (procs[j], gi0[e].trignum); + senddata.Add (procs[j], gi0[e].u); + senddata.Add (procs[j], gi0[e].v); + senddata.Add (procs[j], gi1[e].trignum); + senddata.Add (procs[j], gi1[e].u); + senddata.Add (procs[j], gi1[e].v); + } + } + } + + MyMPI_ExchangeTable (senddata, recvdata, MPI_TAG_CURVE, curve_comm); + + + Array cnt(ntasks); + cnt = 0; + if (working) + for (int e = 0; e < nedges; e++) + { + partop.GetDistantEdgeNums (e+1, procs); + for (int j = 0; j < procs.Size(); j++) + { + int surfnr1 = recvdata[procs[j]][cnt[procs[j]]++]; + if (surfnr1 != -1) + { + surfnr[e] = surfnr1; + gi0[e].trignum = int (recvdata[procs[j]][cnt[procs[j]]++]); + gi0[e].u = recvdata[procs[j]][cnt[procs[j]]++]; + gi0[e].v = recvdata[procs[j]][cnt[procs[j]]++]; + gi1[e].trignum = int (recvdata[procs[j]][cnt[procs[j]]++]); + gi1[e].u = recvdata[procs[j]][cnt[procs[j]]++]; + gi1[e].v = recvdata[procs[j]][cnt[procs[j]]++]; + } + } + } + + } +#endif + + + if (working) + for (int e = 0; e < surfnr.Size(); e++) + { + if (surfnr[e] == -1) continue; + SetThreadPercent(double(e)/surfnr.Size()*100.); + + PointIndex pi1, pi2; + top.GetEdgeVertices (e+1, pi1, pi2); + bool swap = (pi1 > pi2); + + Point<3> p1 = mesh[pi1]; + Point<3> p2 = mesh[pi2]; + + int order1 = edgeorder[e]; + int ndof = max (0, order1-1); + + if (rational && order1 >= 2) + { + Point<3> pm = Center (p1, p2); + + Vec<3> n1 = ref -> GetNormal (p1, surfnr[e], gi0[e]); + Vec<3> n2 = ref -> GetNormal (p2, surfnr[e], gi1[e]); + + // p3 = pm + alpha1 n1 + alpha2 n2 + + Mat<2> mat, inv; + Vec<2> rhs, sol; + + mat(0,0) = n1*n1; + mat(0,1) = mat(1,0) = n1*n2; + mat(1,1) = n2*n2; + + rhs(0) = n1 * (p1-pm); + rhs(1) = n2 * (p2-pm); + + + Point<3> p3; + + if (fabs (Det (mat)) > 1e-10) + { + CalcInverse (mat, inv); + sol = inv * rhs; + + p3 = pm + sol(0) * n1 + sol(1) * n2; + } + else + p3 = pm; + + edgecoeffs[edgecoeffsindex[e]] = Vec<3> (p3); + + + double wold = 1, w = 1, dw = 0.1; + double dold = 1e99; + while (fabs (dw) > 1e-12) + { + Vec<3> v05 = 0.25 * Vec<3> (p1) + 0.5*w* Vec<3>(p3) + 0.25 * Vec<3> (p2); + v05 /= 1 + (w-1) * 0.5; + Point<3> p05 (v05), pp05(v05); + ref -> ProjectToSurface (pp05, surfnr[e], gi0[e]); + double d = Dist (pp05, p05); + + if (d < dold) + { + dold = d; + wold = w; + w += dw; + } + else + { + dw *= -0.7; + w = wold + dw; + } + } + + edgeweight[e] = w; + continue; + } + + Vector shape(ndof); + DenseMatrix mat(ndof, ndof), inv(ndof, ndof), + rhs(ndof, 3), sol(ndof, 3); + + rhs = 0.0; + mat = 0.0; + for (int j = 0; j < xi.Size(); j++) + { + Point<3> p; + Point<3> pp; + PointGeomInfo ppgi; + + if (swap) + { + p = p1 + xi[j] * (p2-p1); + ref -> PointBetween (p1, p2, xi[j], + surfnr[e], gi0[e], gi1[e], + pp, ppgi); + } + else + { + p = p2 + xi[j] * (p1-p2); + ref -> PointBetween (p2, p1, xi[j], + surfnr[e], gi1[e], gi0[e], + pp, ppgi); + } + + Vec<3> dist = pp - p; + + CalcEdgeShape (order1, 2*xi[j]-1, &shape(0)); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < ndof; l++) + mat(k,l) += weight[j] * shape(k) * shape(l); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < 3; l++) + rhs(k,l) += weight[j] * shape(k) * dist(l); + } + + CalcInverse (mat, inv); + Mult (inv, rhs, sol); + + int first = edgecoeffsindex[e]; + for (int j = 0; j < ndof; j++) + for (int k = 0; k < 3; k++) + edgecoeffs[first+j](k) = sol(j,k); + } + } + + + Array use_edge(nedges); + Array edge_surfnr1(nedges); + Array edge_surfnr2(nedges); + Array swap_edge(nedges); + Array edge_gi0(nedges); + Array edge_gi1(nedges); + use_edge = 0; + + if (working) + for (SegmentIndex i = 0; i < mesh.GetNSeg(); i++) + { + const Segment & seg = mesh[i]; + int edgenr = top.GetEdge (i); + use_edge[edgenr] = 1; + edge_surfnr1[edgenr] = seg.surfnr1; + edge_surfnr2[edgenr] = seg.surfnr2; + edge_gi0[edgenr] = seg.epgeominfo[0]; + edge_gi1[edgenr] = seg.epgeominfo[1]; + swap_edge[edgenr] = int (seg[0] > seg[1]); + } + +#ifdef PARALLEL + if (ntasks > 1) + { + // distribute it ... + TABLE senddata(ntasks), recvdata(ntasks); + if (working) + for (int e = 0; e < nedges; e++) + { + partop.GetDistantEdgeNums (e+1, procs); + for (int j = 0; j < procs.Size(); j++) + { + senddata.Add (procs[j], use_edge[e]); + if (use_edge[e]) + { + senddata.Add (procs[j], edge_surfnr1[e]); + senddata.Add (procs[j], edge_surfnr2[e]); + senddata.Add (procs[j], edge_gi0[e].edgenr); + senddata.Add (procs[j], edge_gi0[e].body); + senddata.Add (procs[j], edge_gi0[e].dist); + senddata.Add (procs[j], edge_gi0[e].u); + senddata.Add (procs[j], edge_gi0[e].v); + senddata.Add (procs[j], edge_gi1[e].edgenr); + senddata.Add (procs[j], edge_gi1[e].body); + senddata.Add (procs[j], edge_gi1[e].dist); + senddata.Add (procs[j], edge_gi1[e].u); + senddata.Add (procs[j], edge_gi1[e].v); + senddata.Add (procs[j], swap_edge[e]); + } + } + } + MyMPI_ExchangeTable (senddata, recvdata, MPI_TAG_CURVE, curve_comm); + Array cnt(ntasks); + cnt = 0; + if (working) + for (int e = 0; e < edge_surfnr1.Size(); e++) + { + partop.GetDistantEdgeNums (e+1, procs); + for (int j = 0; j < procs.Size(); j++) + { + int get_edge = int(recvdata[procs[j]][cnt[procs[j]]++]); + if (get_edge) + { + use_edge[e] = 1; + edge_surfnr1[e] = int (recvdata[procs[j]][cnt[procs[j]]++]); + edge_surfnr2[e] = int (recvdata[procs[j]][cnt[procs[j]]++]); + edge_gi0[e].edgenr = int (recvdata[procs[j]][cnt[procs[j]]++]); + edge_gi0[e].body = int (recvdata[procs[j]][cnt[procs[j]]++]); + edge_gi0[e].dist = recvdata[procs[j]][cnt[procs[j]]++]; + edge_gi0[e].u = recvdata[procs[j]][cnt[procs[j]]++]; + edge_gi0[e].v = recvdata[procs[j]][cnt[procs[j]]++]; + edge_gi1[e].edgenr = int (recvdata[procs[j]][cnt[procs[j]]++]); + edge_gi1[e].body = int (recvdata[procs[j]][cnt[procs[j]]++]); + edge_gi1[e].dist = recvdata[procs[j]][cnt[procs[j]]++]; + edge_gi1[e].u = recvdata[procs[j]][cnt[procs[j]]++]; + edge_gi1[e].v = recvdata[procs[j]][cnt[procs[j]]++]; + swap_edge[e] = recvdata[procs[j]][cnt[procs[j]]++]; + } + } + } + + } +#endif + + if (working) + for (int edgenr = 0; edgenr < use_edge.Size(); edgenr++) + { + int segnr = edgenr; + if (!use_edge[edgenr]) continue; + + SetThreadPercent(double(edgenr)/edge_surfnr1.Size()*100.); + + PointIndex pi1, pi2; + top.GetEdgeVertices (edgenr+1, pi1, pi2); + + bool swap = swap_edge[edgenr]; // (pi1 > pi2); + if (swap) Swap (pi1, pi2); + + Point<3> p1 = mesh[pi1]; + Point<3> p2 = mesh[pi2]; + + int order1 = edgeorder[segnr]; + int ndof = max (0, order1-1); + + if (rational) + { + Vec<3> tau1 = ref -> GetTangent (p1, edge_surfnr2[edgenr], edge_surfnr1[edgenr], + edge_gi0[edgenr]); + Vec<3> tau2 = ref -> GetTangent (p2, edge_surfnr2[edgenr], edge_surfnr1[edgenr], + edge_gi1[edgenr]); + // p1 + alpha1 tau1 = p2 + alpha2 tau2; + + Mat<3,2> mat; + Mat<2,3> inv; + Vec<3> rhs; + Vec<2> sol; + for (int j = 0; j < 3; j++) + { + mat(j,0) = tau1(j); + mat(j,1) = -tau2(j); + rhs(j) = p2(j)-p1(j); + } + CalcInverse (mat, inv); + sol = inv * rhs; + + Point<3> p3 = p1+sol(0) * tau1; + edgecoeffs[edgecoeffsindex[segnr]] = Vec<3> (p3); + + double wold = 1, w = 1, dw = 0.1; + double dold = 1e99; + while (fabs (dw) > 1e-12) + { + Vec<3> v05 = 0.25 * Vec<3> (p1) + 0.5*w* Vec<3>(p3) + 0.25 * Vec<3> (p2); + v05 /= 1 + (w-1) * 0.5; + Point<3> p05 (v05), pp05(v05); + ref -> ProjectToEdge (pp05, edge_surfnr1[edgenr], edge_surfnr2[edgenr], + edge_gi0[edgenr]); + double d = Dist (pp05, p05); + + if (d < dold) + { + dold = d; + wold = w; + w += dw; + } + else + { + dw *= -0.7; + w = wold + dw; + } + // *testout << "w = " << w << ", dw = " << dw << endl; + } + + // cout << "wopt = " << w << ", dopt = " << dold << endl; + edgeweight[segnr] = w; + + // cout << "p1 = " << p1 << ", tau1 = " << tau1 << ", alpha1 = " << sol(0) << endl; + // cout << "p2 = " << p2 << ", tau2 = " << tau2 << ", alpha2 = " << -sol(1) << endl; + // cout << "p+alpha tau = " << p1 + sol(0) * tau1 + // << " =?= " << p2 +sol(1) * tau2 << endl; + + } + + else + + { + Vector shape(ndof); + DenseMatrix mat(ndof, ndof), inv(ndof, ndof), + rhs(ndof, 3), sol(ndof, 3); + + rhs = 0.0; + mat = 0.0; + for (int j = 0; j < xi.Size(); j++) + { + Point<3> p, pp; + EdgePointGeomInfo ppgi; + + if (swap) + { + p = p1 + xi[j] * (p2-p1); + ref -> PointBetween (p1, p2, xi[j], + edge_surfnr2[edgenr], edge_surfnr1[edgenr], + edge_gi0[edgenr], edge_gi1[edgenr], + pp, ppgi); + } + else + { + p = p2 + xi[j] * (p1-p2); + ref -> PointBetween (p2, p1, xi[j], + edge_surfnr2[edgenr], edge_surfnr1[edgenr], + edge_gi1[edgenr], edge_gi0[edgenr], + pp, ppgi); + } + + Vec<3> dist = pp - p; + + CalcEdgeShape (order1, 2*xi[j]-1, &shape(0)); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < ndof; l++) + mat(k,l) += weight[j] * shape(k) * shape(l); + + for (int k = 0; k < ndof; k++) + for (int l = 0; l < 3; l++) + rhs(k,l) += weight[j] * shape(k) * dist(l); + } + + + CalcInverse (mat, inv); + Mult (inv, rhs, sol); + + int first = edgecoeffsindex[segnr]; + for (int j = 0; j < ndof; j++) + for (int k = 0; k < 3; k++) + edgecoeffs[first+j](k) = sol(j,k); + } + } + + + + PrintMessage (3, "Curving faces"); + + Array surfnr(nfaces); + surfnr = -1; + + if (working) + for (SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) + surfnr[top.GetFace(i)] = + mesh.GetFaceDescriptor(mesh[i].GetIndex()).SurfNr(); + +#ifdef PARALLEL + TABLE send_surfnr(ntasks), recv_surfnr(ntasks); + + if (ntasks > 1 && working) + { + for (int f = 0; f < nfaces; f++) + { + partop.GetDistantFaceNums (f+1, procs); + for (int j = 0; j < procs.Size(); j++) + send_surfnr.Add (procs[j], surfnr[f]); + } + } + + MyMPI_ExchangeTable (send_surfnr, recv_surfnr, MPI_TAG_CURVE, curve_comm); + + if (ntasks > 1 && working) + { + Array cnt(ntasks); + cnt = 0; + for (int f = 0; f < nfaces; f++) + { + partop.GetDistantFaceNums (f+1, procs); + for (int j = 0; j < procs.Size(); j++) + surfnr[f] = max(surfnr[f], recv_surfnr[procs[j]][cnt[procs[j]]++]); + } + } +#endif + + if (mesh.GetDimension() == 3 && working) + { + for (int f = 0; f < nfaces; f++) + { + int facenr = f; + if (surfnr[f] == -1) continue; + // if (el.GetType() == TRIG && order >= 3) + if (top.GetFaceType(facenr+1) == TRIG && order >= 3) + { + ArrayMem verts(3); + top.GetFaceVertices (facenr+1, verts); + + int fnums[] = { 0, 1, 2 }; + /* + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + */ + if (verts[fnums[0]] > verts[fnums[1]]) swap (fnums[0], fnums[1]); + if (verts[fnums[1]] > verts[fnums[2]]) swap (fnums[1], fnums[2]); + if (verts[fnums[0]] > verts[fnums[1]]) swap (fnums[0], fnums[1]); + + int order1 = faceorder[facenr]; + int ndof = max (0, (order1-1)*(order1-2)/2); + + Vector shape(ndof), dmat(ndof); + MatrixFixWidth<3> rhs(ndof), sol(ndof); + + rhs = 0.0; + dmat = 0.0; + + int np = sqr(xi.Size()); + Array > xia(np); + Array > xa(np); + + for (int jx = 0, jj = 0; jx < xi.Size(); jx++) + for (int jy = 0; jy < xi.Size(); jy++, jj++) + xia[jj] = Point<2> ((1-xi[jy])*xi[jx], xi[jy]); + + // CalcMultiPointSurfaceTransformation (&xia, i, &xa, NULL); + + Array edgenrs; + top.GetFaceEdges (facenr+1, edgenrs); + for (int k = 0; k < edgenrs.Size(); k++) edgenrs[k]--; + + for (int jj = 0; jj < np; jj++) + { + Point<3> pp(0,0,0); + double lami[] = { xia[jj](0), xia[jj](1), 1-xia[jj](0)-xia[jj](1)}; + + for (int k = 0; k < verts.Size(); k++) + pp += lami[k] * Vec<3> (mesh.Point(verts[k])); + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges0 (TRIG); + for (int k = 0; k < edgenrs.Size(); k++) + { + int eorder = edgeorder[edgenrs[k]]; + if (eorder < 2) continue; + + int first = edgecoeffsindex[edgenrs[k]]; + Vector eshape(eorder-1); + int vi1, vi2; + top.GetEdgeVertices (edgenrs[k]+1, vi1, vi2); + if (vi1 > vi2) swap (vi1, vi2); + int v1 = -1, v2 = -1; + for (int j = 0; j < 3; j++) + { + if (verts[j] == vi1) v1 = j; + if (verts[j] == vi2) v2 = j; + } + + CalcScaledEdgeShape (eorder, lami[v1]-lami[v2], lami[v1]+lami[v2], &eshape(0)); + for (int n = 0; n < eshape.Size(); n++) + pp += eshape(n) * edgecoeffs[first+n]; + } + xa[jj] = pp; + } + + for (int jx = 0, jj = 0; jx < xi.Size(); jx++) + for (int jy = 0; jy < xi.Size(); jy++, jj++) + { + double y = xi[jy]; + double x = (1-y) * xi[jx]; + double lami[] = { x, y, 1-x-y }; + double wi = weight[jx]*weight[jy]*(1-y); + + Point<3> pp = xa[jj]; + // ref -> ProjectToSurface (pp, mesh.GetFaceDescriptor(el.GetIndex()).SurfNr()); + ref -> ProjectToSurface (pp, surfnr[facenr]); + Vec<3> dist = pp-xa[jj]; + + CalcTrigShape (order1, lami[fnums[1]]-lami[fnums[0]], + 1-lami[fnums[1]]-lami[fnums[0]], &shape(0)); + + for (int k = 0; k < ndof; k++) + dmat(k) += wi * shape(k) * shape(k); + + dist *= wi; + for (int k = 0; k < ndof; k++) + for (int l = 0; l < 3; l++) + rhs(k,l) += shape(k) * dist(l); + } + + for (int i = 0; i < ndof; i++) + for (int j = 0; j < 3; j++) + sol(i,j) = rhs(i,j) / dmat(i); // Orthogonal basis ! + + int first = facecoeffsindex[facenr]; + for (int j = 0; j < ndof; j++) + for (int k = 0; k < 3; k++) + facecoeffs[first+j](k) = sol(j,k); + } + } + } + + + // compress edge and face tables + int newbase = 0; + for (int i = 0; i < edgeorder.Size(); i++) + { + bool curved = 0; + int oldbase = edgecoeffsindex[i]; + int nd = edgecoeffsindex[i+1] - edgecoeffsindex[i]; + + for (int j = 0; j < nd; j++) + if (edgecoeffs[oldbase+j].Length() > 1e-12) + curved = 1; + if (rational) curved = 1; + + if (curved && newbase != oldbase) + for (int j = 0; j < nd; j++) + edgecoeffs[newbase+j] = edgecoeffs[oldbase+j]; + + edgecoeffsindex[i] = newbase; + if (!curved) edgeorder[i] = 1; + if (curved) newbase += nd; + } + edgecoeffsindex.Last() = newbase; + + + newbase = 0; + for (int i = 0; i < faceorder.Size(); i++) + { + bool curved = 0; + int oldbase = facecoeffsindex[i]; + int nd = facecoeffsindex[i+1] - facecoeffsindex[i]; + + for (int j = 0; j < nd; j++) + if (facecoeffs[oldbase+j].Length() > 1e-12) + curved = 1; + + if (curved && newbase != oldbase) + for (int j = 0; j < nd; j++) + facecoeffs[newbase+j] = facecoeffs[oldbase+j]; + + facecoeffsindex[i] = newbase; + if (!curved) faceorder[i] = 1; + if (curved) newbase += nd; + } + facecoeffsindex.Last() = newbase; + + if (working) + ishighorder = (order > 1); + // (*testout) << "edgecoeffs = " << endl << edgecoeffs << endl; + // (*testout) << "facecoeffs = " << endl << facecoeffs << endl; + + +#ifdef PARALLEL + MPI_Barrier (curve_comm); + MPI_Comm_free (&curve_comm); +#endif + } + + + + + + + + + + + // *********************** Transform edges ***************************** + + + bool CurvedElements :: IsSegmentCurved (SegmentIndex elnr) const + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + return mesh.coarsemesh->GetCurvedElements().IsSegmentCurved (hpref_el.coarse_elnr); + } + + SegmentInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = 2; + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + info.edgenr = top.GetSegmentEdge (elnr+1)-1; + info.ndof += edgeorder[info.edgenr]-1; + } + + return (info.ndof > info.nv); + } + + + + + + void CurvedElements :: + CalcSegmentTransformation (double xi, SegmentIndex elnr, + Point<3> * x, Vec<3> * dxdxi, bool * curved) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[2] = { xi, 1-xi }; + double dlami[2] = { 1, -1 }; + + double coarse_xi = 0; + double trans = 0; + for (int i = 0; i < 2; i++) + { + coarse_xi += hpref_el.param[i][0] * lami[i]; + trans += hpref_el.param[i][0] * dlami[i]; + } + + mesh.coarsemesh->GetCurvedElements().CalcSegmentTransformation (coarse_xi, hpref_el.coarse_elnr, x, dxdxi, curved); + if (dxdxi) *dxdxi *= trans; + + return; + } + + + Vector shapes, dshapes; + Array > coefs; + + SegmentInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = 2; + + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + info.edgenr = top.GetSegmentEdge (elnr+1)-1; + info.ndof += edgeorder[info.edgenr]-1; + } + + CalcElementShapes (info, xi, shapes); + GetCoefficients (info, coefs); + + *x = 0; + for (int i = 0; i < shapes.Size(); i++) + *x += shapes(i) * coefs[i]; + + + if (dxdxi) + { + CalcElementDShapes (info, xi, dshapes); + + *dxdxi = 0; + for (int i = 0; i < shapes.Size(); i++) + for (int j = 0; j < 3; j++) + (*dxdxi)(j) += dshapes(i) * coefs[i](j); + } + + if (curved) + *curved = (info.order > 1); + + // cout << "Segment, |x| = " << Abs2(Vec<3> (*x) ) << endl; + } + + + + + void CurvedElements :: + CalcElementShapes (SegmentInfo & info, double xi, Vector & shapes) const + { + if (rational && info.order == 2) + { + shapes.SetSize(3); + double w = edgeweight[info.edgenr]; + shapes(0) = xi*xi; + shapes(1) = (1-xi)*(1-xi); + shapes(2) = 2*w*xi*(1-xi); + shapes *= 1.0 / (1 + (w-1) *2*xi*(1-xi)); + return; + } + + + shapes.SetSize(info.ndof); + shapes(0) = xi; + shapes(1) = 1-xi; + + if (info.order >= 2) + { + if (mesh[info.elnr][0] > mesh[info.elnr][1]) + xi = 1-xi; + CalcEdgeShape (edgeorder[info.edgenr], 2*xi-1, &shapes(2)); + } + } + + void CurvedElements :: + CalcElementDShapes (SegmentInfo & info, double xi, Vector & dshapes) const + { + if (rational && info.order == 2) + { + dshapes.SetSize(3); + double wi = edgeweight[info.edgenr]; + double shapes[3]; + shapes[0] = xi*xi; + shapes[1] = (1-xi)*(1-xi); + shapes[2] = 2*wi*xi*(1-xi); + double w = 1 + (wi-1) *2*xi*(1-xi); + double dw = (wi-1) * (2 - 4*xi); + + dshapes(0) = 2*xi; + dshapes(1) = 2*(xi-1); + dshapes(2) = 2*wi*(1-2*xi); + + for (int j = 0;j < 3; j++) + dshapes(j) = dshapes(j) / w - shapes[j] * dw / (w*w); + return; + } + + + + + + + dshapes.SetSize(info.ndof); + dshapes = 0; + dshapes(0) = 1; + dshapes(1) = -1; + + // int order = edgeorder[info.edgenr]; + + if (info.order >= 2) + { + double fac = 2; + if (mesh[info.elnr][0] > mesh[info.elnr][1]) + { + xi = 1-xi; + fac *= -1; + } + CalcEdgeDx (edgeorder[info.edgenr], 2*xi-1, &dshapes(2)); + for (int i = 2; i < dshapes.Size(); i++) + dshapes(i) *= fac; + } + + // ??? not implemented ???? + } + + void CurvedElements :: + GetCoefficients (SegmentInfo & info, Array > & coefs) const + { + const Segment & el = mesh[info.elnr]; + + coefs.SetSize(info.ndof); + + coefs[0] = Vec<3> (mesh[el[0]]); + coefs[1] = Vec<3> (mesh[el[1]]); + + if (info.order >= 2) + { + int first = edgecoeffsindex[info.edgenr]; + int next = edgecoeffsindex[info.edgenr+1]; + for (int i = 0; i < next-first; i++) + coefs[i+2] = edgecoeffs[first+i]; + } + } + + + + + + + + + + + + + + // ********************** Transform surface elements ******************* + + + bool CurvedElements :: IsSurfaceElementCurved (SurfaceElementIndex elnr) const + { + if (!IsHighOrder()) return false; + + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + return mesh.coarsemesh->GetCurvedElements().IsSurfaceElementCurved (hpref_el.coarse_elnr); + } + + const Element2d & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + SurfaceElementInfo info; + info.elnr = elnr; + info.order = order; + + switch (type) + { + case TRIG : info.nv = 3; break; + case QUAD : info.nv = 4; break; + case TRIG6: return true; + default: + cerr << "undef element in CalcSurfaceTrafo" << endl; + } + info.ndof = info.nv; + + // info.ndof = info.nv = ( (type == TRIG) || (type == TRIG6) ) ? 3 : 4; + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + top.GetSurfaceElementEdges (elnr+1, info.edgenrs); + for (int i = 0; i < info.edgenrs.Size(); i++) + info.edgenrs[i]--; + info.facenr = top.GetSurfaceElementFace (elnr+1)-1; + + for (int i = 0; i < info.edgenrs.Size(); i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + } + + return (info.ndof > info.nv); + } + + void CurvedElements :: + CalcSurfaceTransformation (Point<2> xi, SurfaceElementIndex elnr, + Point<3> * x, Mat<3,2> * dxdxi, bool * curved) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[4]; + FlatVector vlami(4, lami); + vlami = 0; + mesh[elnr].GetShapeNew (xi, vlami); + + Mat<2,2> trans; + Mat<3,2> dxdxic; + if (dxdxi) + { + MatrixFixWidth<2> dlami(4); + dlami = 0; + mesh[elnr].GetDShapeNew (xi, dlami); + + trans = 0; + for (int k = 0; k < 2; k++) + for (int l = 0; l < 2; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + } + + Point<2> coarse_xi(0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 2; j++) + coarse_xi(j) += hpref_el.param[i][j] * lami[i]; + + mesh.coarsemesh->GetCurvedElements().CalcSurfaceTransformation (coarse_xi, hpref_el.coarse_elnr, x, &dxdxic, curved); + + if (dxdxi) + *dxdxi = dxdxic * trans; + + return; + } + + + + Vector shapes; + MatrixFixWidth<2> dshapes; + Array > coefs; + + const Element2d & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + SurfaceElementInfo info; + info.elnr = elnr; + info.order = order; + + switch (type) + { + case TRIG : info.nv = 3; break; + case QUAD : info.nv = 4; break; + case TRIG6: info.nv = 6; break; + default: + cerr << "undef element in CalcSurfaceTrafo" << endl; + } + info.ndof = info.nv; + + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + top.GetSurfaceElementEdges (elnr+1, info.edgenrs); + for (int i = 0; i < info.edgenrs.Size(); i++) + info.edgenrs[i]--; + info.facenr = top.GetSurfaceElementFace (elnr+1)-1; + + + bool firsttry = true; + bool problem = false; + + while(firsttry || problem) + { + problem = false; + + for (int i = 0; !problem && i < info.edgenrs.Size(); i++) + { + if(info.edgenrs[i]+1 >= edgecoeffsindex.Size()) + problem = true; + else + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + } + if(info.facenr+1 >= facecoeffsindex.Size()) + problem = true; + else + info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + + if(problem && !firsttry) + throw NgException("something wrong with curved elements"); + + if(problem) + BuildCurvedElements(NULL,order,rational); + + firsttry = false; + } + } + + CalcElementShapes (info, xi, shapes); + GetCoefficients (info, coefs); + + *x = 0; + for (int i = 0; i < coefs.Size(); i++) + *x += shapes(i) * coefs[i]; + + if (dxdxi) + { + CalcElementDShapes (info, xi, dshapes); + + *dxdxi = 0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 2; k++) + (*dxdxi)(j,k) += dshapes(i,k) * coefs[i](j); + } + + if (curved) + *curved = (info.ndof > info.nv); + } + + + + + void CurvedElements :: + CalcElementShapes (SurfaceElementInfo & info, const Point<2> & xi, Vector & shapes) const + { + const Element2d & el = mesh[info.elnr]; + shapes.SetSize(info.ndof); + + if (rational && info.order >= 2) + { + shapes.SetSize(6); + double w = 1; + double lami[3] = { xi(0), xi(1), 1-xi(0)-xi(1) }; + for (int j = 0; j < 3; j++) + shapes(j) = lami[j] * lami[j]; + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (TRIG); + for (int j = 0; j < 3; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + shapes(j+3) = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + } + + shapes *= 1.0 / w; + return; + } + + switch (el.GetType()) + { + case TRIG: + { + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = 1-xi(0)-xi(1); + + if (info.order == 1) return; + + int ii = 3; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges0 (TRIG); + + for (int i = 0; i < 3; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0], vi2 = edges[i][1]; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, shapes(vi1)-shapes(vi2), shapes(vi1)+shapes(vi2), &shapes(ii)); + ii += eorder-1; + } + } + + int forder = faceorder[info.facenr]; + if (forder >= 3) + { + int fnums[] = { 0, 1, 2 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcTrigShape (forder, + shapes(fnums[1])-shapes(fnums[0]), + 1-shapes(fnums[1])-shapes(fnums[0]), &shapes(ii)); + } + break; + } + + case TRIG6: + { + if (shapes.Size() == 3) + { + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = 1-xi(0)-xi(1); + } + else + { + double x = xi(0); + double y = xi(1); + double lam3 = 1-x-y; + + shapes(0) = x * (2*x-1); + shapes(1) = y * (2*y-1); + shapes(2) = lam3 * (2*lam3-1); + shapes(3) = 4 * y * lam3; + shapes(4) = 4 * x * lam3; + shapes(5) = 4 * x * y; + } + break; + } + + case QUAD: + { + shapes(0) = (1-xi(0))*(1-xi(1)); + shapes(1) = xi(0) *(1-xi(1)); + shapes(2) = xi(0) * xi(1) ; + shapes(3) = (1-xi(0))* xi(1) ; + + if (info.order == 1) return; + + double mu[4] = { + 1 - xi(0) + 1 - xi(1), + xi(0) + 1 - xi(1), + xi(0) + xi(1), + 1 - xi(0) + xi(1), + }; + + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (QUAD); + + for (int i = 0; i < 4; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcEdgeShape (eorder, mu[vi1]-mu[vi2], &shapes(ii)); + double lame = shapes(vi1)+shapes(vi2); + for (int j = 0; j < order-1; j++) + shapes(ii+j) *= lame; + ii += eorder-1; + } + } + + for (int i = ii; i < info.ndof; i++) + shapes(i) = 0; + + break; + } + + default: + throw NgException("CurvedElements::CalcShape 2d, element type not handled"); + }; + } + + + void CurvedElements :: + CalcElementDShapes (SurfaceElementInfo & info, const Point<2> & xi, MatrixFixWidth<2> & dshapes) const + { + const Element2d & el = mesh[info.elnr]; + ELEMENT_TYPE type = el.GetType(); + + double lami[4]; + + dshapes.SetSize(info.ndof); + // dshapes = 0; + + // *testout << "calcelementdshapes, info.ndof = " << info.ndof << endl; + + if (rational && info.order >= 2) + { + double w = 1; + double dw[2] = { 0, 0 }; + + + lami[0] = xi(0); lami[1] = xi(1); lami[2] = 1-xi(0)-xi(1); + double dlami[3][2] = { { 1, 0 }, { 0, 1 }, { -1, -1 }}; + double shapes[6]; + + for (int j = 0; j < 3; j++) + { + shapes[j] = lami[j] * lami[j]; + dshapes(j,0) = 2 * lami[j] * dlami[j][0]; + dshapes(j,1) = 2 * lami[j] * dlami[j][1]; + } + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (TRIG); + for (int j = 0; j < 3; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + + shapes[j+3] = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 2; k++) + dshapes(j+3,k) = 2*wi* (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 2; k++) + dw[k] += 2*(wi-1) * (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + } + // shapes *= 1.0 / w; + dshapes *= 1.0 / w; + for (int i = 0; i < 6; i++) + for (int j = 0; j < 2; j++) + dshapes(i,j) -= shapes[i] * dw[j] / (w*w); + return; + } + + + + + + switch (type) + { + case TRIG: + { + dshapes(0,0) = 1; + dshapes(0,1) = 0.0; + dshapes(1,0) = 0.0; + dshapes(1,1) = 1; + dshapes(2,0) = -1; + dshapes(2,1) = -1; + + if (info.order == 1) return; + + // *testout << "info.order = " << info.order << endl; + + + lami[0] = xi(0); + lami[1] = xi(1); + lami[2] = 1-xi(0)-xi(1); + + int ii = 3; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (TRIG); + + for (int i = 0; i < 3; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShapeDxDt<2> (eorder, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &dshapes(ii,0)); + + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dshapes(vi1,j)-dshapes(vi2,j); + trans(1,j) = dshapes(vi1,j)+dshapes(vi2,j); + } + + for (int j = 0; j < eorder-1; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + + ii += eorder-1; + } + } + + int forder = faceorder[info.facenr]; + // *testout << "forder = " << forder << endl; + if (forder >= 3) + { + int fnums[] = { 0, 1, 2 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcTrigShapeDxDy (forder, + lami[fnums[1]]-lami[fnums[0]], + 1-lami[fnums[1]]-lami[fnums[0]], &dshapes(ii,0)); + + int nd = (forder-1)*(forder-2)/2; + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dshapes(fnums[1],j)-dshapes(fnums[0],j); + trans(1,j) = -dshapes(fnums[1],j)-dshapes(fnums[0],j); + } + + for (int j = 0; j < nd; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + } + + break; + } + + case TRIG6: + { + if (dshapes.Height() == 3) + { + dshapes = 0.0; + dshapes(0,0) = 1; + dshapes(1,1) = 1; + dshapes(2,0) = -1; + dshapes(2,1) = -1; + } + else + { + AutoDiff<2> x(xi(0), 0); + AutoDiff<2> y(xi(1), 1); + AutoDiff<2> lam3 = 1-x-y; + AutoDiff<2> shapes[6]; + shapes[0] = x * (2*x-1); + shapes[1] = y * (2*y-1); + shapes[2] = lam3 * (2*lam3-1); + shapes[3] = 4 * y * lam3; + shapes[4] = 4 * x * lam3; + shapes[5] = 4 * x * y; + + for (int i = 0; i < 6; i++) + { + dshapes(i,0) = shapes[i].DValue(0); + dshapes(i,1) = shapes[i].DValue(1); + } + + } + break; + } + + case QUAD: + { + dshapes(0,0) = -(1-xi(1)); + dshapes(0,1) = -(1-xi(0)); + dshapes(1,0) = (1-xi(1)); + dshapes(1,1) = -xi(0); + dshapes(2,0) = xi(1); + dshapes(2,1) = xi(0); + dshapes(3,0) = -xi(1); + dshapes(3,1) = (1-xi(0)); + + if (info.order == 1) return; + + double shapes[4] = { + (1-xi(0))*(1-xi(1)), + xi(0) *(1-xi(1)), + xi(0) * xi(1) , + (1-xi(0))* xi(1) + }; + + double mu[4] = { + 1 - xi(0) + 1 - xi(1), + xi(0) + 1 - xi(1), + xi(0) + xi(1), + 1 - xi(0) + xi(1), + }; + + double dmu[4][2] = { + { -1, -1 }, + { 1, -1 }, + { 1, 1 }, + { -1, 1 } }; + + // double hshapes[20], hdshapes[20]; + ArrayMem hshapes(order+1), hdshapes(order+1); + + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (QUAD); + + for (int i = 0; i < 4; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcEdgeShapeDx (eorder, mu[vi1]-mu[vi2], &hshapes[0], &hdshapes[0]); + + double lame = shapes[vi1]+shapes[vi2]; + double dlame[2] = { + dshapes(vi1, 0) + dshapes(vi2, 0), + dshapes(vi1, 1) + dshapes(vi2, 1) }; + + for (int j = 0; j < eorder-1; j++) + for (int k = 0; k < 2; k++) + dshapes(ii+j, k) = + lame * hdshapes[j] * (dmu[vi1][k]-dmu[vi2][k]) + + dlame[k] * hshapes[j]; + + ii += eorder-1; + } + } + + /* + *testout << "quad, dshape = " << endl << dshapes << endl; + for (int i = 0; i < 2; i++) + { + Point<2> xil = xi, xir = xi; + Vector shapesl(dshapes.Height()), shapesr(dshapes.Height()); + xil(i) -= 1e-6; + xir(i) += 1e-6; + CalcElementShapes (info, xil, shapesl); + CalcElementShapes (info, xir, shapesr); + + for (int j = 0; j < dshapes.Height(); j++) + dshapes(j,i) = 1.0 / 2e-6 * (shapesr(j)-shapesl(j)); + } + + *testout << "quad, num dshape = " << endl << dshapes << endl; + */ + break; + } + default: + throw NgException("CurvedElements::CalcDShape 2d, element type not handled"); + + }; + } + + + template + void CurvedElements :: + GetCoefficients (SurfaceElementInfo & info, Array > & coefs) const + { + const Element2d & el = mesh[info.elnr]; + coefs.SetSize (info.ndof); + + for (int i = 0; i < info.nv; i++) + { + Point<3> hv = mesh[el[i]]; + for (int j = 0; j < DIM_SPACE; j++) + coefs[i](j) = hv(j); + } + + if (info.order == 1) return; + + int ii = info.nv; + + for (int i = 0; i < info.edgenrs.Size(); i++) + { + int first = edgecoeffsindex[info.edgenrs[i]]; + int next = edgecoeffsindex[info.edgenrs[i]+1]; + for (int j = first; j < next; j++, ii++) + for (int k = 0; k < DIM_SPACE; k++) + coefs[ii](k) = edgecoeffs[j](k); + } + + int first = facecoeffsindex[info.facenr]; + int next = facecoeffsindex[info.facenr+1]; + for (int j = first; j < next; j++, ii++) + for (int k = 0; k < DIM_SPACE; k++) + coefs[ii](k) = facecoeffs[j](k); + } + + + template void CurvedElements :: + GetCoefficients<2> (SurfaceElementInfo & info, Array > & coefs) const; + + template void CurvedElements :: + GetCoefficients<3> (SurfaceElementInfo & info, Array > & coefs) const; + + + + + + // ********************** Transform volume elements ******************* + + + bool CurvedElements :: IsElementCurved (ElementIndex elnr) const + { + if (mesh[elnr].GetType() != TET) return true; + + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + return mesh.coarsemesh->GetCurvedElements().IsElementCurved (hpref_el.coarse_elnr); + } + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + int nfaces = MeshTopology::GetNFaces (type); + if (nfaces > 4) + { // not a tet + const ELEMENT_FACE * faces = MeshTopology::GetFaces0 (type); + for (int j = 0; j < nfaces; j++) + { + if (faces[j][3] != -1) + { // a quad face + Point<3> pts[4]; + for (int k = 0; k < 4; k++) + pts[k] = mesh.Point(el[faces[j][k]]); + Vec<3> twist = (pts[1] - pts[0]) - (pts[2]-pts[3]); + if (twist.Length() > 1e-8 * (pts[1]-pts[0]).Length()) + return true; + } + } + } + + + + ElementInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + } + + return (info.ndof > info.nv); + } + + + bool CurvedElements :: IsElementHighOrder (ElementIndex elnr) const + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + return mesh.coarsemesh->GetCurvedElements().IsElementHighOrder (hpref_el.coarse_elnr); + } + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + ElementInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + if (edgecoeffsindex[info.edgenrs[i]+1] > edgecoeffsindex[info.edgenrs[i]]) return true; + for (int i = 0; i < info.nfaces; i++) + if (facecoeffsindex[info.facenrs[i]+1] > facecoeffsindex[info.facenrs[i]]) return true; + } + return false; + } + + + + + + + void CurvedElements :: + CalcElementTransformation (Point<3> xi, ElementIndex elnr, + Point<3> * x, Mat<3,3> * dxdxi, // bool * curved, + void * buffer, bool valid) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[8]; + FlatVector vlami(8, lami); + vlami = 0; + mesh[elnr].GetShapeNew (xi, vlami); + + Mat<3,3> trans, dxdxic; + if (dxdxi) + { + MatrixFixWidth<3> dlami(8); + dlami = 0; + mesh[elnr].GetDShapeNew (xi, dlami); + + trans = 0; + for (int k = 0; k < 3; k++) + for (int l = 0; l < 3; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + } + + Point<3> coarse_xi(0,0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 3; j++) + coarse_xi(j) += hpref_el.param[i][j] * lami[i]; + + mesh.coarsemesh->GetCurvedElements().CalcElementTransformation (coarse_xi, hpref_el.coarse_elnr, x, &dxdxic /* , curved */); + + if (dxdxi) + *dxdxi = dxdxic * trans; + + return; + } + + + Vector shapes; + MatrixFixWidth<3> dshapes; + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + ElementInfo hinfo; + ElementInfo & info = (buffer) ? *static_cast (buffer) : hinfo; + + + if (!valid) + { + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + } + } + + CalcElementShapes (info, xi, shapes); + + Vec<3> * coefs = (info.ndof <= 10) ? + &info.hcoefs[0] : new Vec<3> [info.ndof]; + + if (info.ndof > 10 || !valid) + GetCoefficients (info, coefs); + + if (x) + { + *x = 0; + for (int i = 0; i < shapes.Size(); i++) + *x += shapes(i) * coefs[i]; + } + + if (dxdxi) + { + if (valid && info.order == 1 && info.nv == 4) // a linear tet + { + *dxdxi = info.hdxdxi; + } + else + { + CalcElementDShapes (info, xi, dshapes); + + *dxdxi = 0; + for (int i = 0; i < shapes.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + (*dxdxi)(j,k) += dshapes(i,k) * coefs[i](j); + + info.hdxdxi = *dxdxi; + } + } + + // *testout << "curved_elements, dshapes = " << endl << dshapes << endl; + + // if (curved) *curved = (info.ndof > info.nv); + + if (info.ndof > 10) delete [] coefs; + } + + + + + void CurvedElements :: CalcElementShapes (ElementInfo & info, const Point<3> & xi, Vector & shapes) const + { + const Element & el = mesh[info.elnr]; + + if (rational && info.order >= 2) + { + shapes.SetSize(10); + double w = 1; + double lami[4] = { xi(0), xi(1), xi(2), 1-xi(0)-xi(1)-xi(2) }; + for (int j = 0; j < 4; j++) + shapes(j) = lami[j] * lami[j]; + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (TET); + for (int j = 0; j < 6; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + shapes(j+4) = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + } + + shapes *= 1.0 / w; + return; + } + + shapes.SetSize(info.ndof); + + switch (el.GetType()) + { + case TET: + { + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = xi(2); + shapes(3) = 1-xi(0)-xi(1)-xi(2); + + if (info.order == 1) return; + + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (TET); + for (int i = 0; i < 6; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, shapes(vi1)-shapes(vi2), shapes(vi1)+shapes(vi2), &shapes(ii)); + ii += eorder-1; + } + } + const ELEMENT_FACE * faces = MeshTopology::GetFaces1 (TET); + for (int i = 0; i < 4; i++) + { + int forder = faceorder[info.facenrs[i]]; + if (forder >= 3) + { + int fnums[] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcScaledTrigShape (forder, + shapes(fnums[1])-shapes(fnums[0]), shapes(fnums[2]), + shapes(fnums[0])+shapes(fnums[1])+shapes(fnums[2]), &shapes(ii)); + ii += (forder-1)*(forder-2)/2; + } + } + + break; + } + + case TET10: + { + double x = xi(0); + double y = xi(1); + double z = xi(2); + double lam4 = 1 - x - y - z; + /* + shapes(0) = xi(0); + shapes(1) = xi(1); + shapes(2) = xi(2); + shapes(3) = 1-xi(0)-xi(1)-xi(2); + */ + + shapes(0) = 2 * x * x - x; + shapes(1) = 2 * y * y - y; + shapes(2) = 2 * z * z - z; + shapes(3) = 2 * lam4 * lam4 - lam4; + + shapes(4) = 4 * x * y; + shapes(5) = 4 * x * z; + shapes(6) = 4 * x * lam4; + shapes(7) = 4 * y * z; + shapes(8) = 4 * y * lam4; + shapes(9) = 4 * z * lam4; + + break; + } + + case PRISM: + { + double lami[6] = { xi(0), xi(1), 1-xi(0)-xi(1), xi(0), xi(1), 1-xi(0)-xi(1) }; + double lamiz[6] = { 1-xi(2), 1-xi(2), 1-xi(2), xi(2), xi(2), xi(2) }; + for (int i = 0; i < 6; i++) + shapes(i) = lami[i] * lamiz[i]; + for (int i = 6; i < info.ndof; i++) + shapes(i) = 0; + + if (info.order == 1) return; + + + int ii = 6; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (PRISM); + for (int i = 0; i < 6; i++) // horizontal edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &shapes(ii)); + double facz = (i < 3) ? (1-xi(2)) : xi(2); + for (int j = 0; j < eorder-1; j++) + shapes(ii+j) *= facz; + + ii += eorder-1; + } + } + + for (int i = 6; i < 9; i++) // vertical edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + double bubz = lamiz[vi1]*lamiz[vi2]; + double polyz = lamiz[vi1] - lamiz[vi2]; + double bubxy = lami[vi1]; + + for (int j = 0; j < eorder-1; j++) + { + shapes(ii+j) = bubxy * bubz; + bubz *= polyz; + } + ii += eorder-1; + } + } + + // FACE SHAPES + const ELEMENT_FACE * faces = MeshTopology::GetFaces1 (PRISM); + for (int i = 0; i < 2; i++) + { + int forder = faceorder[info.facenrs[i]]; + if ( forder < 3 ) continue; + int fav[3] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + if(el[fav[1]] > el[fav[2]]) swap(fav[1],fav[2]); + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + + CalcTrigShape (forder, + lami[fav[2]]-lami[fav[1]], lami[fav[0]], + &shapes(ii)); + + int ndf = (forder+1)*(forder+2)/2 - 3 - 3*(forder-1); + for ( int j = 0; j < ndf; j++ ) + shapes(ii+j) *= lamiz[fav[1]]; + ii += ndf; + } + break; + } + + case PYRAMID: + { + shapes = 0.0; + double x = xi(0); + double y = xi(1); + double z = xi(2); + + if (z == 1.) z = 1-1e-10; + shapes[0] = (1-z-x)*(1-z-y) / (1-z); + shapes[1] = x*(1-z-y) / (1-z); + shapes[2] = x*y / (1-z); + shapes[3] = (1-z-x)*y / (1-z); + shapes[4] = z; + + if (info.order == 1) return; + + int ii = 5; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (PYRAMID); + for (int i = 0; i < 4; i++) // horizontal edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = (edges[i][0]-1), vi2 = (edges[i][1]-1); + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShape (eorder, shapes[vi1]-shapes[vi2], shapes[vi1]+shapes[vi2], &shapes(ii)); + double fac = (shapes[vi1]+shapes[vi2]) / (1-z); + for (int j = 0; j < eorder-1; j++) + shapes(ii+j) *= fac; + + ii += eorder-1; + } + } + + + + break; + } + + case HEX: + { + shapes = 0.0; + double x = xi(0); + double y = xi(1); + double z = xi(2); + + shapes[0] = (1-x)*(1-y)*(1-z); + shapes[1] = x *(1-y)*(1-z); + shapes[2] = x * y *(1-z); + shapes[3] = (1-x)* y *(1-z); + shapes[4] = (1-x)*(1-y)*(z); + shapes[5] = x *(1-y)*(z); + shapes[6] = x * y *(z); + shapes[7] = (1-x)* y *(z); + break; + } + + default: + throw NgException("CurvedElements::CalcShape 3d, element type not handled"); + + }; + } + + + void CurvedElements :: + CalcElementDShapes (ElementInfo & info, const Point<3> & xi, MatrixFixWidth<3> & dshapes) const + { + const Element & el = mesh[info.elnr]; + + dshapes.SetSize(info.ndof); + dshapes = 0.0; + + + + if (rational && info.order >= 2) + { + double w = 1; + double dw[3] = { 0, 0, 0 }; + + double lami[4] = { xi(0), xi(1), xi(2), 1-xi(0)-xi(1)-xi(2) }; + double dlami[4][3] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { -1, -1, -1 }}; + double shapes[10]; + + for (int j = 0; j < 4; j++) + { + shapes[j] = lami[j] * lami[j]; + dshapes(j,0) = 2 * lami[j] * dlami[j][0]; + dshapes(j,1) = 2 * lami[j] * dlami[j][1]; + dshapes(j,2) = 2 * lami[j] * dlami[j][2]; + } + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (TET); + for (int j = 0; j < 6; j++) + { + double wi = edgeweight[info.edgenrs[j]]; + + shapes[j+4] = 2 * wi * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 3; k++) + dshapes(j+4,k) = 2*wi* (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + + w += (wi-1) * 2 * lami[edges[j][0]-1] * lami[edges[j][1]-1]; + for (int k = 0; k < 3; k++) + dw[k] += 2*(wi-1) * (lami[edges[j][0]-1] * dlami[edges[j][1]-1][k] + + lami[edges[j][1]-1] * dlami[edges[j][0]-1][k]); + } + // shapes *= 1.0 / w; + dshapes *= 1.0 / w; + for (int i = 0; i < 10; i++) + for (int j = 0; j < 3; j++) + dshapes(i,j) -= shapes[i] * dw[j] / (w*w); + return; + } + + switch (el.GetType()) + { + case TET: + { + dshapes(0,0) = 1; + dshapes(1,1) = 1; + dshapes(2,2) = 1; + dshapes(3,0) = -1; + dshapes(3,1) = -1; + dshapes(3,2) = -1; + + if (info.order == 1) return; + + double lami[] = { xi(0), xi(1), xi(2), 1-xi(0)-xi(1)-xi(2) }; + int ii = 4; + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (TET); + for (int i = 0; i < 6; i++) + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = edges[i][0]-1, vi2 = edges[i][1]-1; + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + CalcScaledEdgeShapeDxDt<3> (eorder, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &dshapes(ii,0)); + + Mat<2,3> trans; + for (int j = 0; j < 3; j++) + { + trans(0,j) = dshapes(vi1,j)-dshapes(vi2,j); + trans(1,j) = dshapes(vi1,j)+dshapes(vi2,j); + } + + for (int j = 0; j < order-1; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + dshapes(ii+j,2) = ddx * trans(0,2) + ddt * trans(1,2); + } + + ii += eorder-1; + } + } + + const ELEMENT_FACE * faces = MeshTopology::GetFaces1 (TET); + for (int i = 0; i < 4; i++) + { + int forder = faceorder[info.facenrs[i]]; + if (forder >= 3) + { + int fnums[] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + if (el[fnums[1]] > el[fnums[2]]) swap (fnums[1], fnums[2]); + if (el[fnums[0]] > el[fnums[1]]) swap (fnums[0], fnums[1]); + + CalcScaledTrigShapeDxDyDt (forder, + lami[fnums[1]]-lami[fnums[0]], + lami[fnums[2]], lami[fnums[0]]+lami[fnums[1]]+lami[fnums[2]], + &dshapes(ii,0)); + + Mat<3,3> trans; + for (int j = 0; j < 3; j++) + { + trans(0,j) = dshapes(fnums[1],j)-dshapes(fnums[0],j); + trans(1,j) = dshapes(fnums[2],j); + trans(2,j) = dshapes(fnums[0],j)+dshapes(fnums[1],j)+dshapes(fnums[2],j); + } + + int nfd = (forder-1)*(forder-2)/2; + for (int j = 0; j < nfd; j++) + { + double ddx = dshapes(ii+j,0); + double ddy = dshapes(ii+j,1); + double ddt = dshapes(ii+j,2); + dshapes(ii+j,0) = ddx * trans(0,0) + ddy * trans(1,0) + ddt * trans(2,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddy * trans(1,1) + ddt * trans(2,1); + dshapes(ii+j,2) = ddx * trans(0,2) + ddy * trans(1,2) + ddt * trans(2,2); + } + + ii += nfd; + } + } + + break; + } + + case TET10: + { + if (dshapes.Height() == 4) + { + dshapes = 0.0; + + dshapes(0,0) = 1; + dshapes(1,1) = 1; + dshapes(2,2) = 1; + dshapes(3,0) = -1; + dshapes(3,1) = -1; + dshapes(3,2) = -1; + } + else + { + AutoDiff<3> x(xi(0), 0); + AutoDiff<3> y(xi(1), 1); + AutoDiff<3> z(xi(2), 2); + AutoDiff<3> lam4 = 1-x-y-z; + AutoDiff<3> shapes[10]; + + shapes[0] = 2 * x * x - x; + shapes[1] = 2 * y * y - y; + shapes[2] = 2 * z * z - z; + shapes[3] = 2 * lam4 * lam4 - lam4; + + shapes[4] = 4 * x * y; + shapes[5] = 4 * x * z; + shapes[6] = 4 * x * lam4; + shapes[7] = 4 * y * z; + shapes[8] = 4 * y * lam4; + shapes[9] = 4 * z * lam4; + + for (int i = 0; i < 10; i++) + { + dshapes(i,0) = shapes[i].DValue(0); + dshapes(i,1) = shapes[i].DValue(1); + dshapes(i,2) = shapes[i].DValue(2); + } + + } + break; + + break; + } + + + case PRISM: + { + double lami[6] = { xi(0), xi(1), 1-xi(0)-xi(1), xi(0), xi(1), 1-xi(0)-xi(1) }; + double lamiz[6] = { 1-xi(2), 1-xi(2), 1-xi(2), xi(2), xi(2), xi(2) }; + double dlamiz[6] = { -1, -1, -1, 1, 1, 1 }; + double dlami[6][2] = + { { 1, 0, }, + { 0, 1, }, + { -1, -1 }, + { 1, 0, }, + { 0, 1, }, + { -1, -1 } }; + for (int i = 0; i < 6; i++) + { + // shapes(i) = lami[i%3] * ( (i < 3) ? (1-xi(2)) : xi(2) ); + dshapes(i,0) = dlami[i%3][0] * ( (i < 3) ? (1-xi(2)) : xi(2) ); + dshapes(i,1) = dlami[i%3][1] * ( (i < 3) ? (1-xi(2)) : xi(2) ); + dshapes(i,2) = lami[i%3] * ( (i < 3) ? -1 : 1 ); + } + + int ii = 6; + + if (info.order == 1) return; + + + const ELEMENT_EDGE * edges = MeshTopology::GetEdges1 (PRISM); + for (int i = 0; i < 6; i++) // horizontal edges + { + int order = edgeorder[info.edgenrs[i]]; + if (order >= 2) + { + int vi1 = (edges[i][0]-1), vi2 = (edges[i][1]-1); + if (el[vi1] > el[vi2]) swap (vi1, vi2); + vi1 = vi1 % 3; + vi2 = vi2 % 3; + + Vector shapei(order+1); + CalcScaledEdgeShapeDxDt<3> (order, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &dshapes(ii,0) ); + CalcScaledEdgeShape(order, lami[vi1]-lami[vi2], lami[vi1]+lami[vi2], &shapei(0) ); + + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dlami[vi1][j]-dlami[vi2][j]; + trans(1,j) = dlami[vi1][j]+dlami[vi2][j]; + } + + for (int j = 0; j < order-1; j++) + { + double ddx = dshapes(ii+j,0); + double ddt = dshapes(ii+j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + + + + double facz = (i < 3) ? (1-xi(2)) : xi(2); + double dfacz = (i < 3) ? (-1) : 1; + for (int j = 0; j < order-1; j++) + { + dshapes(ii+j,0) *= facz; + dshapes(ii+j,1) *= facz; + dshapes(ii+j,2) = shapei(j) * dfacz; + } + + ii += order-1; + } + } + + for (int i = 6; i < 9; i++) // vertical edges + { + int eorder = edgeorder[info.edgenrs[i]]; + if (eorder >= 2) + { + int vi1 = (edges[i][0]-1), vi2 = (edges[i][1]-1); + if (el[vi1] > el[vi2]) swap (vi1, vi2); + + double bubz = lamiz[vi1] * lamiz[vi2]; + double dbubz = dlamiz[vi1]*lamiz[vi2] + lamiz[vi1]*dlamiz[vi2]; + double polyz = lamiz[vi1] - lamiz[vi2]; + double dpolyz = dlamiz[vi1] - dlamiz[vi2]; + double bubxy = lami[(vi1)%3]; + double dbubxydx = dlami[(vi1)%3][0]; + double dbubxydy = dlami[(vi1)%3][1]; + + for (int j = 0; j < eorder-1; j++) + { + dshapes(ii+j,0) = dbubxydx * bubz; + dshapes(ii+j,1) = dbubxydy * bubz; + dshapes(ii+j,2) = bubxy * dbubz; + + dbubz = bubz * dpolyz + dbubz * polyz; + bubz *= polyz; + } + ii += eorder-1; + } + } + + + if (info.order == 2) return; + // FACE SHAPES + const ELEMENT_FACE * faces = MeshTopology::GetFaces1 (PRISM); + for (int i = 0; i < 2; i++) + { + int forder = faceorder[info.facenrs[i]]; + + if ( forder < 3 ) continue; + int ndf = (forder+1)*(forder+2)/2 - 3 - 3*(forder-1); + + int fav[3] = { faces[i][0]-1, faces[i][1]-1, faces[i][2]-1 }; + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + if(el[fav[1]] > el[fav[2]]) swap(fav[1],fav[2]); + if(el[fav[0]] > el[fav[1]]) swap(fav[0],fav[1]); + + MatrixFixWidth<2> dshapei(ndf); + Vector shapei(ndf); + + CalcTrigShapeDxDy (forder, + lami[fav[2]]-lami[fav[1]], lami[fav[0]], + &dshapei(0,0)); + CalcTrigShape (forder, lami[fav[2]]-lami[fav[1]], lami[fav[0]], + &shapei(0)); + + Mat<2,2> trans; + for (int j = 0; j < 2; j++) + { + trans(0,j) = dlami[fav[2]][j]-dlami[fav[1]][j]; + trans(1,j) = dlami[fav[0]][j]; + } + + for (int j = 0; j < ndf; j++) + { + // double ddx = dshapes(ii+j,0); + // double ddt = dshapes(ii+j,1); + double ddx = dshapei(j,0); + double ddt = dshapei(j,1); + dshapes(ii+j,0) = ddx * trans(0,0) + ddt * trans(1,0); + dshapes(ii+j,1) = ddx * trans(0,1) + ddt * trans(1,1); + } + + for ( int j = 0; j < ndf; j++ ) + { + dshapes(ii+j,0) *= lamiz[fav[1]]; + dshapes(ii+j,1) *= lamiz[fav[1]]; + dshapes(ii+j,2) = shapei(j) * dlamiz[fav[1]]; + } + ii += ndf; + } + + break; + + } + + case PYRAMID: + { + dshapes = 0.0; + double x = xi(0); + double y = xi(1); + double z = xi(2); + + if (z == 1.) z = 1-1e-10; + double z1 = 1-z; + double z2 = z1*z1; + + dshapes(0,0) = -(z1-y)/z1; + dshapes(0,1) = -(z1-x)/z1; + dshapes(0,2) = ((x+y+2*z-2)*z1+(z1-y)*(z1-x))/z2; + + dshapes(1,0) = (z1-y)/z1; + dshapes(1,1) = -x/z1; + dshapes(1,2) = (-x*z1+x*(z1-y))/z2; + + dshapes(2,0) = y/z1; + dshapes(2,1) = x/z1; + dshapes(2,2) = x*y/z2; + + dshapes(3,0) = -y/z1; + dshapes(3,1) = (z1-x)/z1; + dshapes(3,2) = (-y*z1+y*(z1-x))/z2; + + dshapes(4,0) = 0; + dshapes(4,1) = 0; + dshapes(4,2) = 1; + /* old: + vdshape[0] = Vec<3>( -(z1-y)/z1, -(z1-x)/z1, ((x+y+2*z-2)*z1+(z1-y)*(z1-x))/z2 ); + vdshape[1] = Vec<3>( (z1-y)/z1, -x/z1, (-x*z1+x*(z1-y))/z2 ); + vdshape[2] = Vec<3>( y/z1, x/z1, x*y/z2 ); + vdshape[3] = Vec<3>( -y/z1, (z1-x)/z1, (-y*z1+y*(z1-x))/z2 ); + vdshape[4] = Vec<3>( 0, 0, 1 ); + */ + break; + } + + case HEX: + { + dshapes = 0.0; + + double x = xi(0); + double y = xi(1); + double z = xi(2); + + // shapes[0] = (1-x)*(1-y)*(1-z); + dshapes(0,0) = - (1-y)*(1-z); + dshapes(0,1) = (1-x) * (-1) * (1-z); + dshapes(0,2) = (1-x) * (1-y) * (-1); + + // shapes[1] = x *(1-y)*(1-z); + dshapes(1,0) = (1-y)*(1-z); + dshapes(1,1) = -x * (1-z); + dshapes(1,2) = -x * (1-y); + + // shapes[2] = x * y *(1-z); + dshapes(2,0) = y * (1-z); + dshapes(2,1) = x * (1-z); + dshapes(2,2) = -x * y; + + // shapes[3] = (1-x)* y *(1-z); + dshapes(3,0) = -y * (1-z); + dshapes(3,1) = (1-x) * (1-z); + dshapes(3,2) = -(1-x) * y; + + // shapes[4] = (1-x)*(1-y)*z; + dshapes(4,0) = - (1-y)*z; + dshapes(4,1) = (1-x) * (-1) * z; + dshapes(4,2) = (1-x) * (1-y) * 1; + + // shapes[5] = x *(1-y)*z; + dshapes(5,0) = (1-y)*z; + dshapes(5,1) = -x * z; + dshapes(5,2) = x * (1-y); + + // shapes[6] = x * y *z; + dshapes(6,0) = y * z; + dshapes(6,1) = x * z; + dshapes(6,2) = x * y; + + // shapes[7] = (1-x)* y *z; + dshapes(7,0) = -y * z; + dshapes(7,1) = (1-x) * z; + dshapes(7,2) = (1-x) * y; + + break; + } + + default: + throw NgException("CurvedElements::CalcDShape 3d, element type not handled"); + } + + /* + DenseMatrix dshapes2 (info.ndof, 3); + Vector shapesl(info.ndof); + Vector shapesr(info.ndof); + + double eps = 1e-6; + for (int i = 0; i < 3; i++) + { + Point<3> xl = xi; + Point<3> xr = xi; + + xl(i) -= eps; + xr(i) += eps; + CalcElementShapes (info, xl, shapesl); + CalcElementShapes (info, xr, shapesr); + + for (int j = 0; j < info.ndof; j++) + dshapes2(j,i) = (shapesr(j)-shapesl(j)) / (2*eps); + } + (*testout) << "dshapes = " << endl << dshapes << endl; + (*testout) << "dshapes2 = " << endl << dshapes2 << endl; + dshapes2 -= dshapes; + (*testout) << "diff = " << endl << dshapes2 << endl; + */ + } + + + + void CurvedElements :: + GetCoefficients (ElementInfo & info, Vec<3> * coefs) const + { + const Element & el = mesh[info.elnr]; + + for (int i = 0; i < info.nv; i++) + coefs[i] = Vec<3> (mesh[el[i]]); + + if (info.order == 1) return; + + int ii = info.nv; + + for (int i = 0; i < info.nedges; i++) + { + int first = edgecoeffsindex[info.edgenrs[i]]; + int next = edgecoeffsindex[info.edgenrs[i]+1]; + for (int j = first; j < next; j++, ii++) + coefs[ii] = edgecoeffs[j]; + } + for (int i = 0; i < info.nfaces; i++) + { + int first = facecoeffsindex[info.facenrs[i]]; + int next = facecoeffsindex[info.facenrs[i]+1]; + for (int j = first; j < next; j++, ii++) + coefs[ii] = facecoeffs[j]; + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + void CurvedElements :: + CalcMultiPointSegmentTransformation (Array * xi, SegmentIndex segnr, + Array > * x, + Array > * dxdxi) + { + ; + } + + + template + void CurvedElements :: + CalcMultiPointSegmentTransformation (SegmentIndex elnr, int n, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) + { + for (int ip = 0; ip < n; ip++) + { + Point<3> xg; + Vec<3> dx; + + // mesh->GetCurvedElements(). + CalcSegmentTransformation (xi[ip*sxi], elnr, xg, dx); + + if (x) + for (int i = 0; i < DIM_SPACE; i++) + x[ip*sx+i] = xg(i); + + if (dxdxi) + for (int i=0; i (SegmentIndex elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + template void CurvedElements :: + CalcMultiPointSegmentTransformation<3> (SegmentIndex elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + + + void CurvedElements :: + CalcMultiPointSurfaceTransformation (Array< Point<2> > * xi, SurfaceElementIndex elnr, + Array< Point<3> > * x, + Array< Mat<3,2> > * dxdxi) + { + double * px = (x) ? &(*x)[0](0) : NULL; + double * pdxdxi = (dxdxi) ? &(*dxdxi)[0](0) : NULL; + + CalcMultiPointSurfaceTransformation <3> (elnr, xi->Size(), + &(*xi)[0](0), 2, + px, 3, + pdxdxi, 6); + } + + + + + template + void CurvedElements :: + CalcMultiPointSurfaceTransformation (SurfaceElementIndex elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) + { + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[4]; + FlatVector vlami(4, lami); + + ArrayMem, 50> coarse_xi (npts); + + for (int pi = 0; pi < npts; pi++) + { + vlami = 0; + Point<2> hxi(xi[pi*sxi], xi[pi*sxi+1]); + mesh[elnr].GetShapeNew ( hxi, vlami); + + Point<2> cxi(0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 2; j++) + cxi(j) += hpref_el.param[i][j] * lami[i]; + + coarse_xi[pi] = cxi; + } + + mesh.coarsemesh->GetCurvedElements(). + CalcMultiPointSurfaceTransformation (hpref_el.coarse_elnr, npts, + &coarse_xi[0](0), &coarse_xi[1](0)-&coarse_xi[0](0), + x, sx, dxdxi, sdxdxi); + + // Mat<3,2> dxdxic; + if (dxdxi) + { + MatrixFixWidth<2> dlami(4); + dlami = 0; + + for (int pi = 0; pi < npts; pi++) + { + Point<2> hxi(xi[pi*sxi], xi[pi*sxi+1]); + mesh[elnr].GetDShapeNew ( hxi, dlami); + + Mat<2,2> trans; + trans = 0; + for (int k = 0; k < 2; k++) + for (int l = 0; l < 2; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + + Mat hdxdxic, hdxdxi; + for (int k = 0; k < 2*DIM_SPACE; k++) + hdxdxic(k) = dxdxi[pi*sdxdxi+k]; + + hdxdxi = hdxdxic * trans; + + for (int k = 0; k < 2*DIM_SPACE; k++) + dxdxi[pi*sdxdxi+k] = hdxdxi(k); + + // dxdxic = (*dxdxi)[pi]; + // (*dxdxi)[pi] = dxdxic * trans; + } + } + + return; + } + + Vector shapes; + MatrixFixWidth<2> dshapes; + Array > coefs; + + + const Element2d & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + SurfaceElementInfo info; + info.elnr = elnr; + info.order = order; + switch (type) + { + case TRIG : info.nv = 3; break; + case QUAD : info.nv = 4; break; + case TRIG6: info.nv = 6; break; + default: + cerr << "undef element in CalcMultPointSurfaceTrao" << endl; + } + info.ndof = info.nv; + + // if (info.order > 1) + // { + // const MeshTopology & top = mesh.GetTopology(); + + // top.GetSurfaceElementEdges (elnr+1, info.edgenrs); + // for (int i = 0; i < info.edgenrs.Size(); i++) + // info.edgenrs[i]--; + // info.facenr = top.GetSurfaceElementFace (elnr+1)-1; + + // for (int i = 0; i < info.edgenrs.Size(); i++) + // info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + // info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + // } + +// Michael Woopen: THESE FOLLOWING LINES ARE COPIED FROM CurvedElements::CalcSurfaceTransformation + + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + top.GetSurfaceElementEdges (elnr+1, info.edgenrs); + for (int i = 0; i < info.edgenrs.Size(); i++) + info.edgenrs[i]--; + info.facenr = top.GetSurfaceElementFace (elnr+1)-1; + + + bool firsttry = true; + bool problem = false; + + while(firsttry || problem) + { + problem = false; + + for (int i = 0; !problem && i < info.edgenrs.Size(); i++) + { + if(info.edgenrs[i]+1 >= edgecoeffsindex.Size()) + problem = true; + else + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + } + if(info.facenr+1 >= facecoeffsindex.Size()) + problem = true; + else + info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + + if(problem && !firsttry) + throw NgException("something wrong with curved elements"); + + if(problem) + BuildCurvedElements(NULL,order,rational); + + firsttry = false; + } + } + +// THESE LAST LINES ARE COPIED FROM CurvedElements::CalcSurfaceTransformation + + GetCoefficients (info, coefs); + + if (x) + { + if (info.order == 1 && type == TRIG) + { + for (int j = 0; j < npts; j++) + { + Point<2> vxi(xi[j*sxi], xi[j*sxi+1]); + + Point val (coefs[2]); + val += vxi(0) * (coefs[0]-coefs[2]); + val += vxi(1) * (coefs[1]-coefs[2]); + + for (int k = 0; k < DIM_SPACE; k++) + x[j*sx+k] = val(k); + } + } + else + for (int j = 0; j < npts; j++) + { + Point<2> vxi(xi[j*sxi], xi[j*sxi+1]); + CalcElementShapes (info, vxi, shapes); + + Point val = 0.0; + for (int i = 0; i < coefs.Size(); i++) + val += shapes(i) * coefs[i]; + + for (int k = 0; k < DIM_SPACE; k++) + x[j*sx+k] = val(k); + } + } + + if (dxdxi) + { + if (info.order == 1 && type == TRIG) + { + Point<2> xij(xi[0], xi[1]); + CalcElementDShapes (info, xij, dshapes); + + Mat<3,2> dxdxij; + dxdxij = 0.0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < DIM_SPACE; j++) + for (int k = 0; k < 2; k++) + dxdxij(j,k) += dshapes(i,k) * coefs[i](j); + + + for (int ip = 0; ip < npts; ip++) + for (int j = 0; j < DIM_SPACE; j++) + for (int k = 0; k < 2; k++) + dxdxi[ip*sdxdxi+2*j+k] = dxdxij(j,k); + } + else + { + for (int j = 0; j < npts; j++) + { + Point<2> vxi(xi[j*sxi], xi[j*sxi+1]); + CalcElementDShapes (info, vxi, dshapes); + + Mat ds; + ds = 0.0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < DIM_SPACE; j++) + for (int k = 0; k < 2; k++) + ds(j,k) += dshapes(i,k) * coefs[i](j); + // (*dxdxi)[ip] = ds; + + for (int k = 0; k < 2*DIM_SPACE; k++) + dxdxi[j*sdxdxi+k] = ds(k); + } + } + } + } + + + + template void CurvedElements :: + CalcMultiPointSurfaceTransformation<2> (SurfaceElementIndex elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + template void CurvedElements :: + CalcMultiPointSurfaceTransformation<3> (SurfaceElementIndex elnr, int npts, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + + + + + + + + + + + + void CurvedElements :: + CalcMultiPointElementTransformation (Array< Point<3> > * xi, ElementIndex elnr, + Array< Point<3> > * x, + Array< Mat<3,3> > * dxdxi) + { + double * px = (x) ? &(*x)[0](0) : NULL; + double * pdxdxi = (dxdxi) ? &(*dxdxi)[0](0) : NULL; + + CalcMultiPointElementTransformation (elnr, xi->Size(), + &(*xi)[0](0), 3, + px, 3, + pdxdxi, 9); + + return; +#ifdef OLD + + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[8]; + FlatVector vlami(8, lami); + + + ArrayMem, 50> coarse_xi (xi->Size()); + + for (int pi = 0; pi < xi->Size(); pi++) + { + vlami = 0; + mesh[elnr].GetShapeNew ( (*xi)[pi], vlami); + + Point<3> cxi(0,0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 3; j++) + cxi(j) += hpref_el.param[i][j] * lami[i]; + + coarse_xi[pi] = cxi; + } + + mesh.coarsemesh->GetCurvedElements(). + CalcMultiPointElementTransformation (&coarse_xi, hpref_el.coarse_elnr, x, dxdxi); + + + Mat<3,3> trans, dxdxic; + if (dxdxi) + { + MatrixFixWidth<3> dlami(8); + dlami = 0; + + for (int pi = 0; pi < xi->Size(); pi++) + { + mesh[elnr].GetDShapeNew ( (*xi)[pi], dlami); + + trans = 0; + for (int k = 0; k < 3; k++) + for (int l = 0; l < 3; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + + dxdxic = (*dxdxi)[pi]; + (*dxdxi)[pi] = dxdxic * trans; + } + } + + return; + } + + + + + + + + + Vector shapes; + MatrixFixWidth<3> dshapes; + + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + ElementInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + // info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + } + + Array > coefs(info.ndof); + GetCoefficients (info, &coefs[0]); + if (x) + { + for (int j = 0; j < xi->Size(); j++) + { + CalcElementShapes (info, (*xi)[j], shapes); + (*x)[j] = 0; + for (int i = 0; i < coefs.Size(); i++) + (*x)[j] += shapes(i) * coefs[i]; + } + } + + if (dxdxi) + { + if (info.order == 1 && type == TET) + { + if (xi->Size() > 0) + { + CalcElementDShapes (info, (*xi)[0], dshapes); + Mat<3,3> ds; + ds = 0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + ds(j,k) += dshapes(i,k) * coefs[i](j); + + for (int ip = 0; ip < xi->Size(); ip++) + (*dxdxi)[ip] = ds; + } + } + else + for (int ip = 0; ip < xi->Size(); ip++) + { + CalcElementDShapes (info, (*xi)[ip], dshapes); + + Mat<3,3> ds; + ds = 0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + ds(j,k) += dshapes(i,k) * coefs[i](j); + (*dxdxi)[ip] = ds; + } + } +#endif + } + + + + void CurvedElements :: + CalcMultiPointElementTransformation (ElementIndex elnr, int n, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi) + { + // static int timer = NgProfiler::CreateTimer ("calcmultipointtrafo, calcshape"); + + if (mesh.coarsemesh) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [mesh[elnr].hp_elnr]; + + // xi umrechnen + double lami[8]; + FlatVector vlami(8, lami); + + + ArrayMem coarse_xi (3*n); + + for (int pi = 0; pi < n; pi++) + { + vlami = 0; + Point<3> pxi; + for (int j = 0; j < 3; j++) + pxi(j) = xi[pi*sxi+j]; + + mesh[elnr].GetShapeNew ( pxi, vlami); + + Point<3> cxi(0,0,0); + for (int i = 0; i < hpref_el.np; i++) + for (int j = 0; j < 3; j++) + cxi(j) += hpref_el.param[i][j] * lami[i]; + + for (int j = 0; j < 3; j++) + coarse_xi[3*pi+j] = cxi(j); + } + + mesh.coarsemesh->GetCurvedElements(). + CalcMultiPointElementTransformation (hpref_el.coarse_elnr, n, + &coarse_xi[0], 3, + x, sx, + dxdxi, sdxdxi); + + Mat<3,3> trans, dxdxic; + if (dxdxi) + { + MatrixFixWidth<3> dlami(8); + dlami = 0; + + for (int pi = 0; pi < n; pi++) + { + Point<3> pxi; + for (int j = 0; j < 3; j++) + pxi(j) = xi[pi*sxi+j]; + + mesh[elnr].GetDShapeNew (pxi, dlami); + + trans = 0; + for (int k = 0; k < 3; k++) + for (int l = 0; l < 3; l++) + for (int i = 0; i < hpref_el.np; i++) + trans(l,k) += hpref_el.param[i][l] * dlami(i, k); + + Mat<3> mat_dxdxic, mat_dxdxi; + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + mat_dxdxic(j,k) = dxdxi[pi*sdxdxi+3*j+k]; + + mat_dxdxi = mat_dxdxic * trans; + + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxi[pi*sdxdxi+3*j+k] = mat_dxdxi(j,k); + + // dxdxic = (*dxdxi)[pi]; + // (*dxdxi)[pi] = dxdxic * trans; + } + } + return; + } + + + + + + + Vector shapes; + MatrixFixWidth<3> dshapes; + + + const Element & el = mesh[elnr]; + ELEMENT_TYPE type = el.GetType(); + + + ElementInfo info; + info.elnr = elnr; + info.order = order; + info.ndof = info.nv = MeshTopology::GetNPoints (type); + if (info.order > 1) + { + const MeshTopology & top = mesh.GetTopology(); + + info.nedges = top.GetElementEdges (elnr+1, info.edgenrs, 0); + for (int i = 0; i < info.nedges; i++) + info.edgenrs[i]--; + + info.nfaces = top.GetElementFaces (elnr+1, info.facenrs, 0); + for (int i = 0; i < info.nfaces; i++) + info.facenrs[i]--; + + for (int i = 0; i < info.nedges; i++) + info.ndof += edgecoeffsindex[info.edgenrs[i]+1] - edgecoeffsindex[info.edgenrs[i]]; + for (int i = 0; i < info.nfaces; i++) + info.ndof += facecoeffsindex[info.facenrs[i]+1] - facecoeffsindex[info.facenrs[i]]; + // info.ndof += facecoeffsindex[info.facenr+1] - facecoeffsindex[info.facenr]; + } + + Array > coefs(info.ndof); + GetCoefficients (info, &coefs[0]); + if (x) + { + for (int j = 0; j < n; j++) + { + Point<3> xij, xj; + for (int k = 0; k < 3; k++) + xij(k) = xi[j*sxi+k]; + + CalcElementShapes (info, xij, shapes); + xj = 0; + for (int i = 0; i < coefs.Size(); i++) + xj += shapes(i) * coefs[i]; + + for (int k = 0; k < 3; k++) + x[j*sx+k] = xj(k); + } + } + + if (dxdxi) + { + if (info.order == 1 && type == TET) + { + if (n > 0) + { + + Point<3> xij; + for (int k = 0; k < 3; k++) + xij(k) = xi[k]; + + CalcElementDShapes (info, xij, dshapes); + + Mat<3> dxdxij; + dxdxij = 0.0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxij(j,k) += dshapes(i,k) * coefs[i](j); + + + for (int ip = 0; ip < n; ip++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxi[ip*sdxdxi+3*j+k] = dxdxij(j,k); + } + } + else + { + for (int ip = 0; ip < n; ip++) + { + Point<3> xij; + for (int k = 0; k < 3; k++) + xij(k) = xi[ip*sxi+k]; + + CalcElementDShapes (info, xij, dshapes); + + Mat<3> dxdxij; + dxdxij = 0.0; + for (int i = 0; i < coefs.Size(); i++) + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxij(j,k) += dshapes(i,k) * coefs[i](j); + + + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + dxdxi[ip*sdxdxi+3*j+k] = dxdxij(j,k); + } + } + } + } + + + + + + + + + +}; + + diff --git a/libsrc/meshing/curvedelems.hpp b/libsrc/meshing/curvedelems.hpp new file mode 100644 index 00000000..11d281ef --- /dev/null +++ b/libsrc/meshing/curvedelems.hpp @@ -0,0 +1,224 @@ +#ifndef CURVEDELEMS +#define CURVEDELEMS + +/**************************************************************************/ +/* File: curvedelems.hpp */ +/* Author: Robert Gaisbauer (first version) */ +/* redesign by Joachim Schoeberl */ +/* Date: 27. Sep. 02, Feb 2006 */ +/**************************************************************************/ + + + + +class Refinement; + + +class CurvedElements +{ + const Mesh & mesh; + + Array edgeorder; + Array faceorder; + + Array edgecoeffsindex; + Array facecoeffsindex; + + Array< Vec<3> > edgecoeffs; + Array< Vec<3> > facecoeffs; + + Array< double > edgeweight; // for rational 2nd order splines + + int order; + bool rational; + + bool ishighorder; + +public: + CurvedElements (const Mesh & amesh); + ~CurvedElements(); + + // bool IsHighOrder() const { return order > 1; } + bool IsHighOrder() const { return ishighorder; } + + // void SetHighOrder (int aorder) { order=aorder; } + void SetIsHighOrder (bool ho) { ishighorder = ho; } + + void BuildCurvedElements(const Refinement * ref, int aorder, bool arational = false); + + int GetOrder () { return order; } + + + bool IsSegmentCurved (SegmentIndex segnr) const; + bool IsSurfaceElementCurved (SurfaceElementIndex sei) const; + bool IsElementCurved (ElementIndex ei) const; + bool IsElementHighOrder (ElementIndex ei) const; + + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> & x) + { CalcSegmentTransformation (xi, segnr, &x, NULL); }; + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Vec<3> & dxdxi) + { CalcSegmentTransformation (xi, segnr, NULL, &dxdxi); }; + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> & x, Vec<3> & dxdxi) + { CalcSegmentTransformation (xi, segnr, &x, &dxdxi, NULL); }; + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> & x, Vec<3> & dxdxi, bool & curved) + { CalcSegmentTransformation (xi, segnr, &x, &dxdxi, &curved); }; + + + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Point<3> & x) + { CalcSurfaceTransformation (xi, elnr, &x, NULL); }; + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Mat<3,2> & dxdxi) + { CalcSurfaceTransformation (xi, elnr, NULL, &dxdxi); }; + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Point<3> & x, Mat<3,2> & dxdxi) + { CalcSurfaceTransformation (xi, elnr, &x, &dxdxi, NULL); }; + + void CalcSurfaceTransformation (const Point<2> & xi, SurfaceElementIndex elnr, + Point<3> & x, Mat<3,2> & dxdxi, bool & curved) + { CalcSurfaceTransformation (xi, elnr, &x, &dxdxi, &curved); }; + + + + + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Point<3> & x) + { CalcElementTransformation (xi, elnr, &x, NULL); }; + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Mat<3,3> & dxdxi) + { CalcElementTransformation (xi, elnr, NULL, &dxdxi); }; + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Point<3> & x, Mat<3,3> & dxdxi) + { CalcElementTransformation (xi, elnr, &x, &dxdxi /* , NULL */ ); }; + + void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + Point<3> & x, Mat<3,3> & dxdxi, + void * buffer, bool valid) + { CalcElementTransformation (xi, elnr, &x, &dxdxi, /* NULL, */ buffer, valid ); }; + + // void CalcElementTransformation (const Point<3> & xi, ElementIndex elnr, + // Point<3> & x, Mat<3,3> & dxdxi) // , bool & curved) + // { CalcElementTransformation (xi, elnr, &x, &dxdxi /* , &curved * ); } + + + + void CalcMultiPointSegmentTransformation (Array * xi, SegmentIndex segnr, + Array > * x, + Array > * dxdxi); + + template + void CalcMultiPointSegmentTransformation (SegmentIndex elnr, int n, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + + void CalcMultiPointSurfaceTransformation (Array< Point<2> > * xi, SurfaceElementIndex elnr, + Array< Point<3> > * x, + Array< Mat<3,2> > * dxdxi); + + template + void CalcMultiPointSurfaceTransformation (SurfaceElementIndex elnr, int n, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + void CalcMultiPointElementTransformation (Array< Point<3> > * xi, ElementIndex elnr, + Array< Point<3> > * x, + Array< Mat<3,3> > * dxdxi); + + void CalcMultiPointElementTransformation (ElementIndex elnr, int n, + const double * xi, size_t sxi, + double * x, size_t sx, + double * dxdxi, size_t sdxdxi); + + + + +private: + + void CalcSegmentTransformation (double xi, SegmentIndex segnr, + Point<3> * x = NULL, Vec<3> * dxdxi = NULL, bool * curved = NULL); + + void CalcSurfaceTransformation (Point<2> xi, SurfaceElementIndex elnr, + Point<3> * x = NULL, Mat<3,2> * dxdxi = NULL, bool * curved = NULL); + + void CalcElementTransformation (Point<3> xi, ElementIndex elnr, + Point<3> * x = NULL, Mat<3,3> * dxdxi = NULL, // bool * curved = NULL, + void * buffer = NULL, bool valid = 0); + + + + + + + class SegmentInfo + { + public: + SegmentIndex elnr; + int order; + int nv; + int ndof; + int edgenr; + }; + + void CalcElementShapes (SegmentInfo & elnr, double xi, Vector & shapes) const; + void GetCoefficients (SegmentInfo & elnr, Array > & coefs) const; + void CalcElementDShapes (SegmentInfo & elnr, double xi, Vector & dshapes) const; + + + class ElementInfo + { + public: + ElementIndex elnr; + int order; + int nv; + int ndof; + int nedges; + int nfaces; + int edgenrs[12]; + int facenrs[6]; + Mat<3> hdxdxi; + Vec<3> hcoefs[10]; // enough for second order tets + }; + + + void CalcElementShapes (ElementInfo & info, const Point<3> & xi, Vector & shapes) const; + void GetCoefficients (ElementInfo & info, Vec<3> * coefs) const; + void CalcElementDShapes (ElementInfo & info, const Point<3> & xi, MatrixFixWidth<3> & dshapes) const; + + + class SurfaceElementInfo + { + public: + SurfaceElementIndex elnr; + int order; + int nv; + int ndof; + ArrayMem edgenrs; + int facenr; + }; + + void CalcElementShapes (SurfaceElementInfo & elinfo, const Point<2> & xi, Vector & shapes) const; + template + void GetCoefficients (SurfaceElementInfo & elinfo, Array > & coefs) const; + void CalcElementDShapes (SurfaceElementInfo & elinfo, const Point<2> & xi, MatrixFixWidth<2> & dshapes) const; +}; + + + +#endif diff --git a/libsrc/meshing/delaunay.cpp b/libsrc/meshing/delaunay.cpp new file mode 100644 index 00000000..9cb37644 --- /dev/null +++ b/libsrc/meshing/delaunay.cpp @@ -0,0 +1,1665 @@ +#include +#include "meshing.hpp" + + + +namespace netgen +{ + + + static const int deltetfaces[][3] = + { { 1, 2, 3 }, + { 2, 0, 3 }, + { 0, 1, 3 }, + { 1, 0, 2 } }; + + + + + + + class DelaunayTet + { + PointIndex pnums[4]; + int nb[4]; + + public: + DelaunayTet () { ; } + + DelaunayTet (const DelaunayTet & el) + { + for (int i = 0; i < 4; i++) + pnums[i] = el[i]; + } + + DelaunayTet (const Element & el) + { + for (int i = 0; i < 4; i++) + pnums[i] = el[i]; + } + + PointIndex & operator[] (int i) { return pnums[i]; } + PointIndex operator[] (int i) const { return pnums[i]; } + + int & NB1(int i) { return nb[i-1]; } + int NB1(int i) const { return nb[i-1]; } + + int & NB(int i) { return nb[i]; } + int NB(int i) const { return nb[i]; } + + + int FaceNr (INDEX_3 & face) const // which face nr is it ? + { + for (int i = 0; i < 3; i++) + if (pnums[i] != face.I1() && + pnums[i] != face.I2() && + pnums[i] != face.I3()) + return i; + return 3; + } + + void GetFace1 (int i, INDEX_3 & face) const + { + face.I(1) = pnums[deltetfaces[i-1][0]]; + face.I(2) = pnums[deltetfaces[i-1][1]]; + face.I(3) = pnums[deltetfaces[i-1][2]]; + } + + void GetFace (int i, INDEX_3 & face) const + { + face.I(1) = pnums[deltetfaces[i][0]]; + face.I(2) = pnums[deltetfaces[i][1]]; + face.I(3) = pnums[deltetfaces[i][2]]; + } + + INDEX_3 GetFace1 (int i) const + { + return INDEX_3 (pnums[deltetfaces[i-1][0]], + pnums[deltetfaces[i-1][1]], + pnums[deltetfaces[i-1][2]]); + } + + INDEX_3 GetFace (int i) const + { + return INDEX_3 (pnums[deltetfaces[i][0]], + pnums[deltetfaces[i][1]], + pnums[deltetfaces[i][2]]); + } + + void GetFace1 (int i, Element2d & face) const + { + // face.SetType(TRIG); + face[0] = pnums[deltetfaces[i-1][0]]; + face[1] = pnums[deltetfaces[i-1][1]]; + face[2] = pnums[deltetfaces[i-1][2]]; + } + }; + + + + + + + + + + /* + Table to maintain neighbour elements + */ + class MeshNB + { + // face nodes -> one element + INDEX_3_CLOSED_HASHTABLE faces; + + // + Array & tets; + + public: + + // estimated number of points + MeshNB (Array & atets, int np) + : faces(200), tets(atets) + { ; } + + // add element with 4 nodes + void Add (int elnr); + + // delete element with 4 nodes + void Delete (int elnr) + { + DelaunayTet & el = tets.Elem(elnr); + for (int i = 0; i < 4; i++) + faces.Set (el.GetFace(i).Sort(), el.NB(i)); + } + + // get neighbour of element elnr in direction fnr + int GetNB (int elnr, int fnr) + { + return tets.Get(elnr).NB1(fnr); + } + + // + void ResetFaceHT (int size) + { + faces.SetSize (size); + } + }; + + + + void MeshNB :: Add (int elnr) + { + DelaunayTet & el = tets.Elem(elnr); + + for (int i = 0; i < 4; i++) + { + INDEX_3 i3 = INDEX_3::Sort (el.GetFace(i)); + + int posnr; + + if (!faces.PositionCreate (i3, posnr)) + { + // face already in use + int othertet = faces.GetData (posnr); + + el.NB(i) = othertet; + if (othertet) + { + int fnr = tets.Get(othertet).FaceNr (i3); + tets.Elem(othertet).NB(fnr) = elnr; + } + } + else + { + faces.SetData (posnr, elnr); + el.NB(i) = 0; + } + } + } + + + + + + + /* + connected lists of cosphereical elements + */ + class SphereList + { + Array links; + public: + SphereList () + { ; } + + void AddElement (int elnr) + { + if (elnr > links.Size()) + links.Append (1); + links.Elem(elnr) = elnr; + } + + void DeleteElement (int elnr) + { + links.Elem(elnr) = 0; + } + + void ConnectElement (int eli, int toi) + { + links.Elem (eli) = links.Get (toi); + links.Elem (toi) = eli; + } + + void GetList (int eli, Array & linked) const; + }; + + + void SphereList :: GetList (int eli, Array & linked) const + { + linked.SetSize (0); + int pi = eli; + + do + { + if (pi <= 0 || pi > links.Size()) + { + cerr << "link, error " << endl; + cerr << "pi = " << pi << " linked.s = " << linked.Size() << endl; + exit(1); + } + if (linked.Size() > links.Size()) + { + cerr << "links have loop" << endl; + exit(1); + } + + linked.Append (pi); + pi = links.Get(pi); + } + while (pi != eli); + } + + + + + + void AddDelaunayPoint (PointIndex newpi, const Point3d & newp, + Array & tempels, + Mesh & mesh, + Box3dTree & tettree, + MeshNB & meshnb, + Array > & centers, Array & radi2, + Array & connected, Array & treesearch, + Array & freelist, SphereList & list, + IndexSet & insphere, IndexSet & closesphere) + { + /* + find any sphere, such that newp is contained in + */ + + DelaunayTet el; + int cfelind = -1; + + const Point<3> * pp[4]; + Point<3> pc; + double r2; + Point3d tpmin, tpmax; + + tettree.GetIntersecting (newp, newp, treesearch); + double quot,minquot(1e20); + + for (int j = 0; j < treesearch.Size(); j++) + { + int jjj = treesearch[j]; + quot = Dist2 (centers.Get(jjj), newp) / radi2.Get(jjj); + + if((cfelind == -1 || quot < 0.99*minquot) && quot < 1) + { + minquot = quot; + el = tempels.Get(jjj); + cfelind = jjj; + if(minquot < 0.917632) + break; + } + } + + + /* + int i, j, k, l; + if (!felind) + { + cerr << "not in any sphere, 1" << endl; + // old, non tree search + + double mindist = 1e10; + for (j = 1; j <= tempels.Size(); j++) + { + if (tempels.Get(j).PNum(1)) + { + double toofar = + Dist2 (centers.Get(j), newp) - radi2.Get(j); + if (toofar < mindist || toofar < 1e-7) + { + mindist = toofar; + cout << " dist2 = " << Dist2 (centers.Get(j), newp) + << " radi2 = " << radi2.Get(j) << endl; + } + if (toofar < 0) + { + el = tempels.Get(j); + felind = j; + cout << "sphere found !" << endl; + break; + } + } + } + cout << "point is too far from sheres: " << mindist << endl; + } + */ + + if (cfelind == -1) + { + PrintWarning ("Delaunay, point not in any sphere"); + return; + } + + + /* + insphere: point is in sphere -> delete element + closesphere: point is close to sphere -> considered for same center + */ + + // save overestimate + insphere.SetMaxIndex (2 * tempels.Size() + 5 * mesh.GetNP()); + closesphere.SetMaxIndex (2 * tempels.Size() + 5 * mesh.GetNP()); + + insphere.Clear(); + closesphere.Clear(); + + + insphere.Add (cfelind); + + int changed = 1; + int nstarti = 1, starti; + + while (changed) + { + changed = 0; + starti = nstarti; + nstarti = insphere.GetArray().Size()+1; + + + // if point in sphere, then it is also closesphere + for (int j = starti; j < nstarti; j++) + { + int helind = insphere.GetArray().Get(j); + if (!closesphere.IsIn (helind)) + closesphere.Add (helind); + } + + // add connected spheres to insphere - list + for (int j = starti; j < nstarti; j++) + { + list.GetList (insphere.GetArray().Get(j), connected); + for (int k = 0; k < connected.Size(); k++) + { + int celind = connected[k]; + + if (tempels.Get(celind)[0] != -1 && + !insphere.IsIn (celind)) + { + changed = 1; + insphere.Add (celind); + } + } + } + + // check neighbour-tets + for (int j = starti; j < nstarti; j++) + for (int k = 1; k <= 4; k++) + { + int helind = insphere.GetArray().Get(j); + int nbind = meshnb.GetNB (helind, k); + + if (nbind && !insphere.IsIn (nbind) ) + { + //changed + //int prec = testout->precision(); + //testout->precision(12); + //(*testout) << "val1 " << Dist2 (centers.Get(nbind), newp) + // << " val2 " << radi2.Get(nbind) * (1+1e-8) + // << " val3 " << radi2.Get(nbind) + // << " val1 / val3 " << Dist2 (centers.Get(nbind), newp)/radi2.Get(nbind) << endl; + //testout->precision(prec); + if (Dist2 (centers.Get(nbind), newp) + < radi2.Get(nbind) * (1+1e-8) ) + closesphere.Add (nbind); + + if (Dist2 (centers.Get(nbind), newp) + < radi2.Get(nbind) * (1 + 1e-12)) + { + // point is in sphere -> remove tet + insphere.Add (nbind); + changed = 1; + } + else + { + /* + Element2d face; + tempels.Get(helind).GetFace (k, face); + + const Point3d & p1 = mesh.Point (face.PNum(1)); + const Point3d & p2 = mesh.Point (face[1]); + const Point3d & p3 = mesh.Point (face[2]); + */ + + INDEX_3 i3 = tempels.Get(helind).GetFace (k-1); + + const Point3d & p1 = mesh.Point ( i3.I1()); + const Point3d & p2 = mesh.Point ( i3.I2()); + const Point3d & p3 = mesh.Point ( i3.I3()); + + + Vec3d v1(p1, p2); + Vec3d v2(p1, p3); + Vec3d n = Cross (v1, v2); + n /= n.Length(); + + if (n * Vec3d (p1, mesh.Point (tempels.Get(helind)[k-1])) > 0) + n *= -1; + + double dist = n * Vec3d (p1, newp); + + + if (dist > -1e-10) // 1e-10 + { + insphere.Add (nbind); + changed = 1; + } + + + } + } + } + } // while (changed) + // (*testout) << "newels: " << endl; + Array newels; + + Element2d face(TRIG); + + for (int j = 1; j <= insphere.GetArray().Size(); j++) + for (int k = 1; k <= 4; k++) + { + // int elind = insphere.GetArray().Get(j); + int celind = insphere.GetArray().Get(j); + int nbind = meshnb.GetNB (celind, k); + + if (!nbind || !insphere.IsIn (nbind)) + { + tempels.Get (celind).GetFace1 (k, face); + + Element newel(TET); + for (int l = 0; l < 3; l++) + newel[l] = face[l]; + newel[3] = newpi; + + newels.Append (newel); + + Vec<3> v1 = mesh[face[1]] - mesh[face[0]]; + Vec<3> v2 = mesh[face[2]] - mesh[face[0]]; + Vec<3> n = Cross (v1, v2); + + n.Normalize(); + if (n * Vec3d(mesh.Point (face[0]), + mesh.Point (tempels.Get(insphere.GetArray().Get(j))[k-1])) + > 0) + n *= -1; + + double hval = n * ( newp - mesh[face[0]]); + + if (hval > -1e-12) + { + cerr << "vec to outer" << endl; + (*testout) << "vec to outer, hval = " << hval << endl; + (*testout) << "v1 x v2 = " << Cross (v1, v2) << endl; + (*testout) << "facep: " + << mesh.Point (face[0]) << " " + << mesh.Point (face[1]) << " " + << mesh.Point (face[2]) << endl; + } + } + } + + meshnb.ResetFaceHT (10*insphere.GetArray().Size()+1); + + for (int j = 1; j <= insphere.GetArray().Size(); j++) + { + // int elind = + int celind = insphere.GetArray().Get(j); + + meshnb.Delete (celind); + list.DeleteElement (celind); + + for (int k = 0; k < 4; k++) + tempels.Elem(celind)[k] = -1; + + ((ADTree6&)tettree.Tree()).DeleteElement (celind); + freelist.Append (celind); + } + + int hasclose = 0; + for (int j = 1; j <= closesphere.GetArray().Size(); j++) + { + int ind = closesphere.GetArray().Get(j); + if (!insphere.IsIn(ind) && + fabs (Dist2 (centers.Get (ind), newp) - radi2.Get(ind)) < 1e-8 ) + hasclose = 1; + } + + for (int j = 1; j <= newels.Size(); j++) + { + int nelind; + + if (!freelist.Size()) + { + tempels.Append (newels.Get(j)); + nelind = tempels.Size(); + } + else + { + nelind = freelist.Last(); + freelist.DeleteLast(); + + tempels.Elem(nelind) = newels.Get(j); + } + + meshnb.Add (nelind); + list.AddElement (nelind); + + for (int k = 0; k < 4; k++) + pp[k] = &mesh.Point (newels.Get(j)[k]); + + if (CalcSphereCenter (&pp[0], pc) ) + { + PrintSysError ("Delaunay: New tet is flat"); + + (*testout) << "new tet is flat" << endl; + for (int k = 1; k <= 4; k++) + (*testout) << newels.Get(j).PNum(k) << " "; + (*testout) << endl; + for (int k = 1; k <= 4; k++) + (*testout) << *pp[k-1] << " "; + (*testout) << endl; + } + + r2 = Dist2 (*pp[0], pc); + if (hasclose) + for (int k = 1; k <= closesphere.GetArray().Size(); k++) + { + int csameind = closesphere.GetArray().Get(k); + if (!insphere.IsIn(csameind) && + fabs (r2 - radi2.Get(csameind)) < 1e-10 && + Dist (pc, centers.Get(csameind)) < 1e-10) + { + pc = centers.Get(csameind); + r2 = radi2.Get(csameind); + list.ConnectElement (nelind, csameind); + break; + } + } + + if (centers.Size() < nelind) + { + centers.Append (pc); + radi2.Append (r2); + } + else + { + centers.Elem(nelind) = pc; + radi2.Elem(nelind) = r2; + } + + closesphere.Add (nelind); + + tpmax = tpmin = *pp[0]; + for (int k = 1; k <= 3; k++) + { + tpmin.SetToMin (*pp[k]); + tpmax.SetToMax (*pp[k]); + } + tpmax = tpmax + 0.01 * (tpmax - tpmin); + tettree.Insert (tpmin, tpmax, nelind); + } + } + + + + + + + void Delaunay1 (Mesh & mesh, const MeshingParameters & mp, AdFront3 * adfront, + Array & tempels, + int oldnp, DelaunayTet & startel, Point3d & pmin, Point3d & pmax) + { + Array > centers; + Array radi2; + + Point3d tpmin, tpmax; + + + // new: local box + mesh.GetBox (pmax, pmin); // lower bound for pmax, upper for pmin + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & face = adfront->GetFace(i); + for (int j = 0; j < face.GetNP(); j++) + { + pmin.SetToMin (mesh.Point (face[j])); + pmax.SetToMax (mesh.Point (face[j])); + } + } + + for (int i = 0; i < mesh.LockedPoints().Size(); i++) + { + pmin.SetToMin (mesh.Point (mesh.LockedPoints()[i])); + pmax.SetToMax (mesh.Point (mesh.LockedPoints()[i])); + } + + + + Vec3d vdiag(pmin, pmax); + // double r1 = vdiag.Length(); + double r1 = sqrt (3.0) * max3(vdiag.X(), vdiag.Y(), vdiag.Z()); + vdiag = Vec3d (r1, r1, r1); + //double r2; + + Point3d pmin2 = pmin - 8 * vdiag; + Point3d pmax2 = pmax + 8 * vdiag; + + Point3d cp1(pmin2), cp2(pmax2), cp3(pmax2), cp4(pmax2); + cp2.X() = pmin2.X(); + cp3.Y() = pmin2.Y(); + cp4.Z() = pmin2.Z(); + + + + + int np = mesh.GetNP(); + + startel[0] = mesh.AddPoint (cp1); + startel[1] = mesh.AddPoint (cp2); + startel[2] = mesh.AddPoint (cp3); + startel[3] = mesh.AddPoint (cp4); + + // flag points to use for Delaunay: + BitArrayChar usep(np); + usep.Clear(); + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & face = adfront->GetFace(i); + for (int j = 0; j < face.GetNP(); j++) + usep.Set (face[j]); + } + + for (int i = oldnp + PointIndex::BASE; + i < np + PointIndex::BASE; i++) + usep.Set (i); + + for (int i = 0; i < mesh.LockedPoints().Size(); i++) + usep.Set (mesh.LockedPoints()[i]); + + + Array freelist; + + + int cntp = 0; + + MeshNB meshnb (tempels, mesh.GetNP() + 5); + SphereList list; + + pmin2 = pmin2 + 0.1 * (pmin2 - pmax2); + pmax2 = pmax2 + 0.1 * (pmax2 - pmin2); + + Box3dTree tettree(pmin2, pmax2); + + + tempels.Append (startel); + meshnb.Add (1); + list.AddElement (1); + Array connected, treesearch; + + + tpmin = tpmax = mesh.Point(startel[0]); + for (int k = 1; k < 4; k++) + { + tpmin.SetToMin (mesh.Point (startel[k])); + tpmax.SetToMax (mesh.Point (startel[k])); + } + tpmax = tpmax + 0.01 * (tpmax - tpmin); + tettree.Insert (tpmin, tpmax, 1); + + Point<3> pc; + + const Point<3> * pp[4]; + for (int k = 0; k < 4; k++) + pp[k] = &mesh.Point (startel[k]); + CalcSphereCenter (&pp[0], pc); + + centers.Append (pc); + radi2.Append (Dist2 (*pp[0], pc)); + + + IndexSet insphere(mesh.GetNP()); + IndexSet closesphere(mesh.GetNP()); + + // "random" reordering of points (speeds a factor 3 - 5 !!!) + Array mixed(np); + int prims[] = { 11, 13, 17, 19, 23, 29, 31, 37 }; + int prim; + + { + int i = 0; + while (np % prims[i] == 0) i++; + prim = prims[i]; + } + + for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End()-4; pi++) + mixed[pi] = PointIndex ( (prim * pi) % np + PointIndex::BASE ); + + for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End()-4; pi++) + { + if (pi % 1000 == 0) + { + if (pi % 10000 == 0) + PrintDot ('+'); + else + PrintDot ('.'); + } + + multithread.percent = 100.0 * pi / np; + if (multithread.terminate) + break; + + PointIndex newpi = mixed[pi]; + + if (!usep.Test(newpi)) + continue; + + cntp++; + + const MeshPoint & newp = mesh[newpi]; + + AddDelaunayPoint (newpi, newp, tempels, mesh, + tettree, meshnb, centers, radi2, + connected, treesearch, freelist, list, insphere, closesphere); + + } + + for (int i = tempels.Size(); i >= 1; i--) + if (tempels.Get(i)[0] <= 0) + tempels.DeleteElement (i); + + PrintDot ('\n'); + + PrintMessage (3, "Points: ", cntp); + PrintMessage (3, "Elements: ", tempels.Size()); + // (*mycout) << cntp << " / " << tempels.Size() << " points/elements" << endl; + + /* + cout << "tempels: "; + tempels.PrintMemInfo(cout); + cout << "Searchtree: "; + tettree.Tree().PrintMemInfo(cout); + cout << "MeshNB: "; + meshnb.PrintMemInfo(cout); + */ + } + + + + + + + void Meshing3 :: Delaunay (Mesh & mesh, int domainnr, const MeshingParameters & mp) + { + int np, ne; + + PrintMessage (1, "Delaunay meshing"); + PrintMessage (3, "number of points: ", mesh.GetNP()); + PushStatus ("Delaunay meshing"); + + + Array tempels; + Point3d pmin, pmax; + + DelaunayTet startel; + + int oldnp = mesh.GetNP(); + if (mp.blockfill) + { + BlockFillLocalH (mesh, mp); + PrintMessage (3, "number of points: ", mesh.GetNP()); + } + + np = mesh.GetNP(); + + Delaunay1 (mesh, mp, adfront, tempels, oldnp, startel, pmin, pmax); + + { + // improve delaunay - mesh by swapping !!!! + + Mesh tempmesh; + for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++) + tempmesh.AddPoint (mesh[pi]); + + for (int i = 1; i <= tempels.Size(); i++) + { + Element el(4); + for (int j = 0; j < 4; j++) + el[j] = tempels.Elem(i)[j]; + + el.SetIndex (1); + + const Point3d & lp1 = mesh.Point (el[0]); + const Point3d & lp2 = mesh.Point (el[1]); + const Point3d & lp3 = mesh.Point (el[2]); + const Point3d & lp4 = mesh.Point (el[3]); + Vec3d v1(lp1, lp2); + Vec3d v2(lp1, lp3); + Vec3d v3(lp1, lp4); + + Vec3d n = Cross (v1, v2); + double vol = n * v3; + if (vol > 0) swap (el[2], el[3]); + + tempmesh.AddVolumeElement (el); + } + + + MeshQuality3d (tempmesh); + + tempmesh.AddFaceDescriptor (FaceDescriptor (1, 1, 0, 0)); + tempmesh.AddFaceDescriptor (FaceDescriptor (2, 1, 0, 0)); + + + + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + { + Element2d sel = mesh.OpenElement(i); + sel.SetIndex(1); + tempmesh.AddSurfaceElement (sel); + swap (sel[1], sel[2]); + tempmesh.AddSurfaceElement (sel); + } + + + for (int i = 1; i <= 4; i++) + { + Element2d self(TRIG); + self.SetIndex (1); + startel.GetFace1 (i, self); + tempmesh.AddSurfaceElement (self); + } + + + // for (i = mesh.GetNP() - 3; i <= mesh.GetNP(); i++) + // tempmesh.AddLockedPoint (i); + for (PointIndex pi = tempmesh.Points().Begin(); + pi < tempmesh.Points().End(); pi++) + tempmesh.AddLockedPoint (pi); + + // tempmesh.PrintMemInfo(cout); + // tempmesh.Save ("tempmesh.vol"); + + for (int i = 1; i <= 2; i++) + { + tempmesh.FindOpenElements (); + + PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); + tempmesh.CalcSurfacesOfNode (); + + tempmesh.FreeOpenElementsEnvironment (1); + + MeshOptimize3d meshopt(mp); + // tempmesh.CalcSurfacesOfNode(); + meshopt.SwapImprove(tempmesh, OPT_CONFORM); + } + + MeshQuality3d (tempmesh); + + tempels.SetSize(0); + for (int i = 1; i <= tempmesh.GetNE(); i++) + tempels.Append (tempmesh.VolumeElement(i)); + } + + + + // remove degenerated + + BitArray badnode(mesh.GetNP()); + badnode.Clear(); + int ndeg = 0; + for (int i = 1; i <= tempels.Size(); i++) + { + Element el(4); + for (int j = 0; j < 4; j++) + el[j] = tempels.Elem(i)[j]; + // Element & el = tempels.Elem(i); + const Point3d & lp1 = mesh.Point (el[0]); + const Point3d & lp2 = mesh.Point (el[1]); + const Point3d & lp3 = mesh.Point (el[2]); + const Point3d & lp4 = mesh.Point (el[3]); + Vec3d v1(lp1, lp2); + Vec3d v2(lp1, lp3); + Vec3d v3(lp1, lp4); + Vec3d n = Cross (v1, v2); + double vol = n * v3; + + double h = v1.Length() + v2.Length() + v3.Length(); + if (fabs (vol) < 1e-8 * (h * h * h) && + (el[0] <= np && el[1] <= np && + el[2] <= np && el[3] <= np) ) // old: 1e-12 + { + badnode.Set(el[0]); + badnode.Set(el[1]); + badnode.Set(el[2]); + badnode.Set(el[3]); + ndeg++; + (*testout) << "vol = " << vol << " h = " << h << endl; + } + + if (vol > 0) + Swap (el[2], el[3]); + } + + ne = tempels.Size(); + for (int i = ne; i >= 1; i--) + { + const DelaunayTet & el = tempels.Get(i); + if (badnode.Test(el[0]) || + badnode.Test(el[1]) || + badnode.Test(el[2]) || + badnode.Test(el[3]) ) + tempels.DeleteElement(i); + } + + + PrintMessage (3, ndeg, " degenerated elements removed"); + + // find surface triangles which are no face of any tet + + INDEX_3_HASHTABLE openeltab(mesh.GetNOpenElements()+3); + Array openels; + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + { + const Element2d & tri = mesh.OpenElement(i); + INDEX_3 i3(tri[0], tri[1], tri[2]); + i3.Sort(); + openeltab.Set (i3, i); + } + + for (int i = 1; i <= tempels.Size(); i++) + { + for (int j = 0; j < 4; j++) + { + INDEX_3 i3 = tempels.Get(i).GetFace (j); + i3.Sort(); + if (openeltab.Used(i3)) + openeltab.Set (i3, 0); + } + } + + // and store them in openels + for (int i = 1; i <= openeltab.GetNBags(); i++) + for (int j = 1; j <= openeltab.GetBagSize(i); j++) + { + INDEX_3 i3; + int fnr; + openeltab.GetData (i, j, i3, fnr); + if (fnr) + openels.Append (fnr); + } + + + + + + // find open triangle with close edge (from halfening of surface squares) + + INDEX_2_HASHTABLE twotrias(mesh.GetNOpenElements()+5); + // for (i = 1; i <= mesh.GetNOpenElements(); i++) + for (int ii = 1; ii <= openels.Size(); ii++) + { + int i = openels.Get(ii); + const Element2d & el = mesh.OpenElement(i); + for (int j = 1; j <= 3; j++) + { + INDEX_2 hi2 (el.PNumMod (j), el.PNumMod(j+1)); + hi2.Sort(); + if (twotrias.Used(hi2)) + { + INDEX_2 hi3; + hi3 = twotrias.Get (hi2); + hi3.I2() = el.PNumMod (j+2); + twotrias.Set (hi2, hi3); + } + else + { + INDEX_2 hi3(el.PNumMod (j+2), 0); + twotrias.Set (hi2, hi3); + } + } + } + + INDEX_2_HASHTABLE tetedges(tempels.Size() + 5); + for (int i = 1; i <= tempels.Size(); i++) + { + const DelaunayTet & el = tempels.Get(i); + INDEX_2 i2; + for (int j = 1; j <= 6; j++) + { + switch (j) + { + case 1: i2.I1()=el[0]; i2.I2()=el[1]; break; + case 2: i2.I1()=el[0]; i2.I2()=el[2]; break; + case 3: i2.I1()=el[0]; i2.I2()=el[3]; break; + case 4: i2.I1()=el[1]; i2.I2()=el[2]; break; + case 5: i2.I1()=el[1]; i2.I2()=el[3]; break; + case 6: i2.I1()=el[2]; i2.I2()=el[3]; break; + default: i2.I1()=i2.I2()=0; break; + } + i2.Sort(); + tetedges.Set (i2, 1); + } + } + // cout << "tetedges:"; + // tetedges.PrintMemInfo (cout); + + + for (INDEX_2_HASHTABLE::Iterator it = twotrias.Begin(); + it != twotrias.End(); it++) + { + INDEX_2 hi2, hi3; + twotrias.GetData (it, hi2, hi3); + hi3.Sort(); + if (tetedges.Used (hi3)) + { + const Point3d & p1 = mesh.Point ( PointIndex (hi2.I1())); + const Point3d & p2 = mesh.Point ( PointIndex (hi2.I2())); + const Point3d & p3 = mesh.Point ( PointIndex (hi3.I1())); + const Point3d & p4 = mesh.Point ( PointIndex (hi3.I2())); + Vec3d v1(p1, p2); + Vec3d v2(p1, p3); + Vec3d v3(p1, p4); + Vec3d n = Cross (v1, v2); + double vol = n * v3; + + double h = v1.Length() + v2.Length() + v3.Length(); + if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12 + { + badnode.Set(hi3.I1()); + badnode.Set(hi3.I2()); + } + } + } + + /* + for (i = 1; i <= twotrias.GetNBags(); i++) + for (j = 1; j <= twotrias.GetBagSize (i); j++) + { + INDEX_2 hi2, hi3; + twotrias.GetData (i, j, hi2, hi3); + hi3.Sort(); + if (tetedges.Used (hi3)) + { + const Point3d & p1 = mesh.Point (hi2.I1()); + const Point3d & p2 = mesh.Point (hi2.I2()); + const Point3d & p3 = mesh.Point (hi3.I1()); + const Point3d & p4 = mesh.Point (hi3.I2()); + Vec3d v1(p1, p2); + Vec3d v2(p1, p3); + Vec3d v3(p1, p4); + Vec3d n = Cross (v1, v2); + double vol = n * v3; + + double h = v1.Length() + v2.Length() + v3.Length(); + if (fabs (vol) < 1e-4 * (h * h * h)) // old: 1e-12 + { + badnode.Set(hi3.I1()); + badnode.Set(hi3.I2()); + } + } + } + */ + + ne = tempels.Size(); + for (int i = ne; i >= 1; i--) + { + const DelaunayTet & el = tempels.Get(i); + if (badnode.Test(el[0]) || + badnode.Test(el[1]) || + badnode.Test(el[2]) || + badnode.Test(el[3]) ) + tempels.DeleteElement(i); + } + + + + + // find intersecting: + PrintMessage (3, "Remove intersecting"); + if (openels.Size()) + { + Box3dTree setree(pmin, pmax); + + /* + cout << "open elements in search tree: " << openels.Size() << endl; + cout << "pmin, pmax = " << pmin << " - " << pmax << endl; + */ + + for (int i = 1; i <= openels.Size(); i++) + { + int fnr; + fnr = openels.Get(i); + if (fnr) + { + const Element2d & tri = mesh.OpenElement(fnr); + + Point3d ltpmin (mesh.Point(tri[0])); + Point3d ltpmax (ltpmin); + + for (int k = 2; k <= 3; k++) + { + ltpmin.SetToMin (mesh.Point (tri.PNum(k))); + ltpmax.SetToMax (mesh.Point (tri.PNum(k))); + } + setree.Insert (ltpmin, ltpmax, fnr); + } + } + + Array neartrias; + for (int i = 1; i <= tempels.Size(); i++) + { + const Point<3> *pp[4]; + int tetpi[4]; + DelaunayTet & el = tempels.Elem(i); + + int intersect = 0; + + for (int j = 0; j < 4; j++) + { + pp[j] = &mesh.Point(el[j]); + tetpi[j] = el[j]; + } + + Point3d tetpmin(*pp[0]); + Point3d tetpmax(tetpmin); + for (int j = 1; j < 4; j++) + { + tetpmin.SetToMin (*pp[j]); + tetpmax.SetToMax (*pp[j]); + } + tetpmin = tetpmin + 0.01 * (tetpmin - tetpmax); + tetpmax = tetpmax + 0.01 * (tetpmax - tetpmin); + + setree.GetIntersecting (tetpmin, tetpmax, neartrias); + + + // for (j = 1; j <= mesh.GetNSE(); j++) + // { + for (int jj = 1; jj <= neartrias.Size(); jj++) + { + int j = neartrias.Get(jj); + + const Element2d & tri = mesh.OpenElement(j); + const Point<3> *tripp[3]; + int tripi[3]; + + for (int k = 1; k <= 3; k++) + { + tripp[k-1] = &mesh.Point (tri.PNum(k)); + tripi[k-1] = tri.PNum(k); + } + + if (IntersectTetTriangle (&pp[0], &tripp[0], tetpi, tripi)) + { + /* + int il1, il2; + (*testout) << "intersect !" << endl; + (*testout) << "triind: "; + for (il1 = 0; il1 < 3; il1++) + (*testout) << " " << tripi[il1]; + (*testout) << endl; + (*testout) << "tetind: "; + for (il2 = 0; il2 < 4; il2++) + (*testout) << " " << tetpi[il2]; + (*testout) << endl; + + (*testout) << "trip: "; + for (il1 = 0; il1 < 3; il1++) + (*testout) << " " << *tripp[il1]; + (*testout) << endl; + (*testout) << "tetp: "; + for (il2 = 0; il2 < 4; il2++) + (*testout) << " " << *pp[il2]; + (*testout) << endl; + */ + + + intersect = 1; + break; + } + } + + + if (intersect) + { + tempels.DeleteElement(i); + i--; + } + } + } + + + + + PrintMessage (3, "Remove outer"); + + // find connected tets (with no face between, and no hole due + // to removed intersecting tets. + // INDEX_3_HASHTABLE innerfaces(np); + + + INDEX_3_HASHTABLE boundaryfaces(mesh.GetNOpenElements()/3+1); + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + { + const Element2d & tri = mesh.OpenElement(i); + INDEX_3 i3 (tri[0], tri[1], tri[2]); + i3.Sort(); + boundaryfaces.PrepareSet (i3); + } + boundaryfaces.AllocateElements(); + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + { + const Element2d & tri = mesh.OpenElement(i); + INDEX_3 i3 (tri[0], tri[1], tri[2]); + i3.Sort(); + boundaryfaces.Set (i3, 1); + } + + for (int i = 0; i < tempels.Size(); i++) + for (int j = 0; j < 4; j++) + tempels[i].NB(j) = 0; + + TABLE elsonpoint(mesh.GetNP()); + for (int i = 0; i < tempels.Size(); i++) + { + const DelaunayTet & el = tempels[i]; + INDEX_4 i4(el[0], el[1], el[2], el[3]); + i4.Sort(); + elsonpoint.IncSizePrepare (i4.I1()); + elsonpoint.IncSizePrepare (i4.I2()); + } + + elsonpoint.AllocateElementsOneBlock(); + + for (int i = 0; i < tempels.Size(); i++) + { + const DelaunayTet & el = tempels[i]; + INDEX_4 i4(el[0], el[1], el[2], el[3]); + i4.Sort(); + elsonpoint.Add (i4.I1(), i+1); + elsonpoint.Add (i4.I2(), i+1); + } + + // cout << "elsonpoint mem: "; + // elsonpoint.PrintMemInfo(cout); + + INDEX_3_CLOSED_HASHTABLE faceht(100); + + Element2d hel(TRIG); + for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++) + { + faceht.SetSize (4 * elsonpoint[pi].Size()); + for (int ii = 0; ii < elsonpoint[pi].Size(); ii++) + { + int i = elsonpoint[pi][ii]; + const DelaunayTet & el = tempels.Get(i); + + for (int j = 1; j <= 4; j++) + { + el.GetFace1 (j, hel); + hel.Invert(); + hel.NormalizeNumbering(); + + if (hel[0] == pi) + { + INDEX_3 i3(hel[0], hel[1], hel[2]); + + if (!boundaryfaces.Used (i3)) + { + if (faceht.Used (i3)) + { + INDEX_2 i2 = faceht.Get(i3); + + tempels.Elem(i).NB1(j) = i2.I1(); + tempels.Elem(i2.I1()).NB1(i2.I2()) = i; + } + else + { + hel.Invert(); + hel.NormalizeNumbering(); + INDEX_3 i3i(hel[0], hel[1], hel[2]); + INDEX_2 i2(i, j); + faceht.Set (i3i, i2); + } + } + } + } + } + } + + /* + for (i = 1; i <= tempels.Size(); i++) + { + const DelaunayTet & el = tempels.Get(i); + for (j = 1; j <= 4; j++) + { + INDEX_3 i3; + Element2d face; + el.GetFace1 (j, face); + for (int kk = 1; kk <= 3; kk++) + i3.I(kk) = face.PNum(kk); + + i3.Sort(); + if (!boundaryfaces.Used (i3)) + { + if (innerfaces.Used(i3)) + { + INDEX_2 i2; + i2 = innerfaces.Get(i3); + i2.I2() = i; + innerfaces.Set (i3, i2); + } + else + { + INDEX_2 i2; + i2.I1() = i; + i2.I2() = 0; + innerfaces.Set (i3, i2); + } + } + } + } + */ + + /* + (*testout) << "nb elements:" << endl; + for (i = 1; i <= tempels.Size(); i++) + { + (*testout) << i << " "; + for (j = 1; j <= 4; j++) + (*testout) << tempels.Get(i).NB1(j) << " "; + (*testout) << endl; + } + + (*testout) << "pairs:" << endl; + for (i = 1; i <= innerfaces.GetNBags(); i++) + for (j = 1; j <= innerfaces.GetBagSize(i); j++) + { + INDEX_3 i3; + INDEX_2 i2; + innerfaces.GetData (i, j, i3, i2); + (*testout) << i2 << endl; + } + */ + + + + + + + + /* + cout << "innerfaces: "; + innerfaces.PrintMemInfo (cout); + */ + + // cout << "boundaryfaces: "; + // boundaryfaces.PrintMemInfo (cout); + + + PrintMessage (5, "tables filled"); + + + ne = tempels.Size(); + BitArray inner(ne), outer(ne); + inner.Clear(); + outer.Clear(); + Array elstack; + + /* + int starti = 0; + for (i = 1; i <= ne; i++) + { + const Element & el = tempels.Get(i); + for (j = 1; j <= 4; j++) + for (k = 1; k <= 4; k++) + if (el.PNum(j) == startel.PNum(k)) + { + outer.Set(i); + starti = i; + } + } + */ + + while (1) + { + int inside; + bool done = 1; + + int i; + for (i = 1; i <= ne; i++) + if (!inner.Test(i) && !outer.Test(i)) + { + done = 0; + break; + } + + if (done) break; + + const DelaunayTet & el = tempels.Get(i); + const Point3d & p1 = mesh.Point (el[0]); + const Point3d & p2 = mesh.Point (el[1]); + const Point3d & p3 = mesh.Point (el[2]); + const Point3d & p4 = mesh.Point (el[3]); + + Point3d ci = Center (p1, p2, p3, p4); + + inside = adfront->Inside (ci); + + /* + cout << "startel: " << i << endl; + cout << "inside = " << inside << endl; + cout << "ins2 = " << adfront->Inside (Center (ci, p1)) << endl; + cout << "ins3 = " << adfront->Inside (Center (ci, p2)) << endl; + */ + + elstack.SetSize(0); + elstack.Append (i); + + while (elstack.Size()) + { + int ei = elstack.Last(); + elstack.DeleteLast(); + + if (!inner.Test(ei) && !outer.Test(ei)) + { + if (inside) + inner.Set(ei); + else + outer.Set(ei); + + + for (int j = 1; j <= 4; j++) + { + INDEX_3 i3 = tempels.Get(ei).GetFace1(j); + /* + Element2d face; + tempels.Get(ei).GetFace(j, face); + for (int kk = 1; kk <= 3; kk++) + i3.I(kk) = face.PNum(kk); + */ + i3.Sort(); + + + if (tempels.Get(ei).NB1(j)) + elstack.Append (tempels.Get(ei).NB1(j)); + + /* + if (innerfaces.Used(i3)) + { + INDEX_2 i2 = innerfaces.Get(i3); + int other = i2.I1() + i2.I2() - ei; + + if (other != tempels.Get(ei).NB1(j)) + cerr << "different1 !!" << endl; + + if (other) + { + elstack.Append (other); + } + } + else + if (tempels.Get(ei).NB1(j)) + cerr << "different2 !!" << endl; + */ + + } + } + } + } + + + + // check outer elements + if (debugparam.slowchecks) + { + for (int i = 1; i <= ne; i++) + { + const DelaunayTet & el = tempels.Get(i); + const Point3d & p1 = mesh.Point (el[0]); + const Point3d & p2 = mesh.Point (el[1]); + const Point3d & p3 = mesh.Point (el[2]); + const Point3d & p4 = mesh.Point (el[3]); + + Point3d ci = Center (p1, p2, p3, p4); + + // if (adfront->Inside (ci) != adfront->Inside (Center (ci, p1))) + // cout << "ERROR: outer test unclear !!!" << endl; + + if (inner.Test(i) != adfront->Inside (ci)) + { + /* + cout << "ERROR: outer test wrong !!!" + << "inner = " << int(inner.Test(i)) + << "outer = " << int(outer.Test(i)) + << endl; + + cout << "Vol = " << Determinant(Vec3d(p1, p2), + Vec3d(p1, p3), + Vec3d(p1, p4)) << endl; + + */ + for (int j = 1; j <= 4; j++) + { + Point3d hp; + switch (j) + { + case 1: hp = Center (ci, p1); break; + case 2: hp = Center (ci, p2); break; + case 3: hp = Center (ci, p3); break; + case 4: hp = Center (ci, p4); break; + } + // cout << "inside(" << hp << ") = " << adfront->Inside(hp) << endl; + } + + } + + if (adfront->Inside(ci)) + outer.Clear(i); + else + outer.Set(i); + } + } + + + /* + + // find bug in innerfaces + + tempmesh.DeleteVolumeElements(); + + for (i = 1; i <= innerfaces.GetNBags(); i++) + for (j = 1; j <= innerfaces.GetBagSize(i); j++) + { + INDEX_3 i3; + INDEX_2 i2; + innerfaces.GetData (i, j, i3, i2); + if (i2.I2()) + { + if (outer.Test(i2.I1()) != outer.Test(i2.I2())) + { + tempmesh.AddVolumeElement (tempels.Get(i2.I1())); + tempmesh.AddVolumeElement (tempels.Get(i2.I2())); + cerr << "outer flag different for connected els" << endl; + } + } + } + + + cout << "Check intersectiong once more" << endl; + + for (i = 1; i <= openels.Size(); i++) + { + tempmesh.SurfaceElement(2*openels.Get(i)).SetIndex(2); + tempmesh.SurfaceElement(2*openels.Get(i)-1).SetIndex(2); + } + + // for (i = 1; i <= tempmesh.GetNE(); i++) + // for (j = 1; j <= tempmesh.GetNSE(); j++) + i = 6; j = 403; + if (i <= tempmesh.GetNE() && j <= tempmesh.GetNSE()) + if (tempmesh.SurfaceElement(j).GetIndex()==2) + { + const Element & el = tempmesh.VolumeElement(i); + const Element2d & sel = tempmesh.SurfaceElement(j); + + const Point3d *tripp[3]; + const Point3d *pp[4]; + int tetpi[4], tripi[3]; + + for (k = 1; k <= 4; k++) + { + pp[k-1] = &tempmesh.Point(el.PNum(k)); + tetpi[k-1] = el.PNum(k); + } + + for (k = 1; k <= 3; k++) + { + tripp[k-1] = &tempmesh.Point (sel.PNum(k)); + tripi[k-1] = sel.PNum(k); + } + + (*testout) << "Check Triangle " << j << ":"; + for (k = 1; k <= 3; k++) + (*testout) << " " << sel.PNum(k); + for (k = 1; k <= 3; k++) + (*testout) << " " << tempmesh.Point(sel.PNum(k)); + (*testout) << endl; + + (*testout) << "Check Tet " << i << ":"; + for (k = 1; k <= 4; k++) + (*testout) << " " << el.PNum(k); + for (k = 1; k <= 4; k++) + (*testout) << " " << tempmesh.Point(el.PNum(k)); + (*testout) << endl; + + if (IntersectTetTriangle (&pp[0], &tripp[0], tetpi, tripi)) + { + cout << "Intesection detected !!" << endl; + } + } + + tempmesh.Save ("temp.vol"); + + // end bug search + */ + + + for (int i = ne; i >= 1; i--) + { + if (outer.Test(i)) + tempels.DeleteElement(i); + } + + + // mesh.points.SetSize(mesh.points.Size()-4); + + for (int i = 0; i < tempels.Size(); i++) + { + Element el(4); + for (int j = 0; j < 4; j++) + el[j] = tempels[i][j]; + mesh.AddVolumeElement (el); + } + + PrintMessage (5, "outer removed"); + + mesh.FindOpenElements(domainnr); + + mesh.Compress(); + + PopStatus (); + } +} diff --git a/libsrc/meshing/delaunay2d.cpp b/libsrc/meshing/delaunay2d.cpp new file mode 100644 index 00000000..82f5b529 --- /dev/null +++ b/libsrc/meshing/delaunay2d.cpp @@ -0,0 +1,174 @@ +#include +#include "meshing.hpp" + +// not yet working .... + +namespace netgen +{ + + void Meshing2 :: BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp) + { + double filldist = mp.filldist; + + cout << "blockfill local h" << endl; + cout << "rel filldist = " << filldist << endl; + PrintMessage (3, "blockfill local h"); + + Array > npoints; + + // adfront -> CreateTrees(); + + Box<3> bbox ( Box<3>::EMPTY_BOX ); + double maxh = 0; + + for (int i = 0; i < adfront->GetNFL(); i++) + { + const FrontLine & line = adfront->GetLine (i); + + const Point<3> & p1 = adfront->GetPoint(line.L().I1()); + const Point<3> & p2 = adfront->GetPoint(line.L().I2()); + + double hi = Dist (p1, p2); + if (hi > maxh) maxh = hi; + + bbox.Add (p1); + bbox.Add (p2); + } + + + cout << "bbox = " << bbox << endl; + + + // Point<3> mpc = bbox.Center(); + bbox.Increase (bbox.Diam()/2); + Box<3> meshbox = bbox; + + LocalH loch2 (bbox, 1); + + if (mp.maxh < maxh) maxh = mp.maxh; + + bool changed; + do + { + mesh.LocalHFunction().ClearFlags(); + + for (int i = 0; i < adfront->GetNFL(); i++) + { + const FrontLine & line = adfront->GetLine(i); + + Box<3> bbox (adfront->GetPoint (line.L().I1())); + bbox.Add (adfront->GetPoint (line.L().I2())); + + + double filld = filldist * bbox.Diam(); + bbox.Increase (filld); + + mesh.LocalHFunction().CutBoundary (bbox); + } + + + mesh.LocalHFunction().FindInnerBoxes (adfront, NULL); + + npoints.SetSize(0); + mesh.LocalHFunction().GetInnerPoints (npoints); + + changed = false; + for (int i = 0; i < npoints.Size(); i++) + { + if (mesh.LocalHFunction().GetH(npoints[i]) > 1.5 * maxh) + { + mesh.LocalHFunction().SetH (npoints[i], maxh); + changed = true; + } + } + } + while (changed); + + if (debugparam.slowchecks) + (*testout) << "Blockfill with points: " << endl; + *testout << "loch = " << mesh.LocalHFunction() << endl; + + *testout << "npoints = " << endl << npoints << endl; + + for (int i = 1; i <= npoints.Size(); i++) + { + if (meshbox.IsIn (npoints.Get(i))) + { + PointIndex gpnum = mesh.AddPoint (npoints.Get(i)); + adfront->AddPoint (npoints.Get(i), gpnum); + + if (debugparam.slowchecks) + { + (*testout) << npoints.Get(i) << endl; + + Point<2> p2d (npoints.Get(i)(0), npoints.Get(i)(1)); + if (!adfront->Inside(p2d)) + { + cout << "add outside point" << endl; + (*testout) << "outside" << endl; + } + } + + } + } + + + + // find outer points + + loch2.ClearFlags(); + + for (int i = 0; i < adfront->GetNFL(); i++) + { + const FrontLine & line = adfront->GetLine(i); + + Box<3> bbox (adfront->GetPoint (line.L().I1())); + bbox.Add (adfront->GetPoint (line.L().I2())); + + loch2.SetH (bbox.Center(), bbox.Diam()); + } + + + for (int i = 0; i < adfront->GetNFL(); i++) + { + const FrontLine & line = adfront->GetLine(i); + + Box<3> bbox (adfront->GetPoint (line.L().I1())); + bbox.Add (adfront->GetPoint (line.L().I2())); + + bbox.Increase (filldist * bbox.Diam()); + loch2.CutBoundary (bbox); + } + + loch2.FindInnerBoxes (adfront, NULL); + + npoints.SetSize(0); + loch2.GetOuterPoints (npoints); + + for (int i = 1; i <= npoints.Size(); i++) + { + if (meshbox.IsIn (npoints.Get(i))) + { + PointIndex gpnum = mesh.AddPoint (npoints.Get(i)); + adfront->AddPoint (npoints.Get(i), gpnum); + } + } + + } + + void Meshing2 :: Delaunay (Mesh & mesh, int domainnr, const MeshingParameters & mp) + { + cout << "2D Delaunay meshing (in progress)" << endl; + + // int oldnp = mesh.GetNP(); + + cout << "np, old = " << mesh.GetNP() << endl; + + BlockFillLocalH (mesh, mp); + + + cout << "np, now = " << mesh.GetNP() << endl; + + } + +} diff --git a/libsrc/meshing/findip.hpp b/libsrc/meshing/findip.hpp new file mode 100644 index 00000000..f5d8e424 --- /dev/null +++ b/libsrc/meshing/findip.hpp @@ -0,0 +1,192 @@ +// find inner point + + + +inline void Minimize (const Array & a, + const Array & c, + int * act, + Vec<3> & x, double & f, + int * sol) +{ + int act1[4]; + Mat<3> m, inv; + Vec<3> rs, xmax, center; + + f = 1e99; + + for (int j = 0; j < 5; j++) + { + for (int hk = 0, k = 0; hk < 4; hk++) + { + if (hk == j) k++; + act1[hk] = act[k]; + k++; + } + + for (int k = 0; k < 3; k++) + { + m(k, 0) = a[act1[0]].X() - a[act1[k+1]].X(); + m(k, 1) = a[act1[0]].Y() - a[act1[k+1]].Y(); + m(k, 2) = a[act1[0]].Z() - a[act1[k+1]].Z(); + rs(k) = c[act1[k+1]] - c[act1[0]]; + } + + /* + (*testout) << "act1 = " + << act1[0] << " " + << act1[1] << " " + << act1[2] << " " + << act1[3] << endl; + (*testout) << "Det = " << Det(m) << endl; + */ + + if (fabs (Det (m)) > 1e-10) + { + CalcInverse (m, inv); + xmax = inv * rs; + + double fmax = -1e10; + for (int k = 0; k < 5; k++) + { + double hd = + xmax(0) * a[act[k]].X() + xmax(1) * a[act[k]].Y() + xmax(2) * a[act[k]].Z() + c[act[k]]; + if (hd > fmax) fmax = hd; + } + + if (fmax < f) + { + f = fmax; + x = xmax; + for (int k = 0; k < 4; k++) + sol[k] = act1[k]; + } + } + } +} + + + + +template +inline int FindInnerPoint (POINTArray & points, + FACEArray & faces, + Point3d & p) +{ + static int timer = NgProfiler::CreateTimer ("FindInnerPoint"); + NgProfiler::RegionTimer reg (timer); + + Array a; + Array c; + Mat<3> m, inv; + Vec<3> rs, x = 0.0, center; + double f; + + int nf = faces.Size(); + + // minimize_x max_i a_i x + c_i + + a.SetSize (nf+4); + c.SetSize (nf+4); + + for (int i = 0; i < nf; i++) + { + Point3d p1 = points.Get(faces[i][0]); + a[i] = Cross (points.Get(faces[i][1]) - p1, + points.Get(faces[i][2]) - p1); + a[i] /= a[i].Length(); + c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z()); + } + + /* + center = 0; + for (int i = 0; i < points.Size(); i++) + center += Vec<3> (points[i]); + center /= points.Size(); + */ + + center = 0; + for (int i = 0; i < faces.Size(); i++) + for (int j = 0; j < 3; j++) + center += Vec<3> (points.Get(faces[i][j])); + center /= (3*faces.Size()); + + + // (*testout) << "center = " << center << endl; + + double hmax = 0; + for (int i = 0; i < nf; i++) + { + // const Element2d & el = faces[i]; + // (*testout) << "el[" << i << "] = " << el << endl; + for (int j = 1; j <= 3; j++) + { + double hi = Dist (points.Get(faces[i].PNumMod(j)), + points.Get(faces[i].PNumMod(j+1))); + if (hi > hmax) hmax = hi; + } + } + + // (*testout) << "hmax = " << hmax << endl; + + a[nf] = Vec<3> (1, 0, 0); + c[nf] = -center(0) - hmax; + a[nf+1] = Vec<3> (0, 1, 0); + c[nf+1] = -center(1) - hmax; + a[nf+2] = Vec<3> (0, 0, 1); + c[nf+2] = -center(2) - hmax; + a[nf+3] = Vec<3> (-1, -1, -1); + c[nf+3] = center(0)+center(1)+center(2)-3*hmax; + + /* + (*testout) << "findip, a now = " << endl << a << endl; + (*testout) << "findip, c now = " << endl << c << endl; + */ + + int act[5] = { 0, nf, nf+1, nf+2, nf+3 }; + int sol[4]; + + while (1) + { + /* + (*testout) << "try "; + for (int j = 0; j < 5; j++) + (*testout) << act[j] << " "; + */ + + Minimize (a, c, act, x, f, sol); + + /* + (*testout) << endl << "sol = "; + for (int j = 0; j < 4; j++) + (*testout) << sol[j] << " "; + + (*testout) << " fmin = " << f << endl; + */ + for (int j = 0; j < 4; j++) act[j] = sol[j]; + + bool found = 0; + double maxval = f; + for (int j = 0; j < nf; j++) + { + double val = x(0) * a[j].X() + x(1) * a[j].Y() + x(2) * a[j].Z() + c[j]; + if (val > maxval + hmax * 1e-6) + { + found = 1; + maxval = val; + act[4] = j; + } + } + + // (*testout) << "maxval = " << maxval << endl; + if (!found) break; + } + + // cout << "converged, f = " << f << endl; + + p = Point3d (x(0), x(1), x(2)); + // (*testout) << "findip, f = " << f << ", hmax = " << hmax << endl; + return (f < -1e-5 * hmax); +} + + + diff --git a/libsrc/meshing/findip2.hpp b/libsrc/meshing/findip2.hpp new file mode 100644 index 00000000..95385534 --- /dev/null +++ b/libsrc/meshing/findip2.hpp @@ -0,0 +1,95 @@ +// find inner point + +template +inline int FindInnerPoint2 (POINTArray & points, + FACEArray & faces, + Point3d & p) +{ + static int timer = NgProfiler::CreateTimer ("FindInnerPoint2"); + NgProfiler::RegionTimer reg (timer); + + Array a; + Array c; + Mat<3> m, inv; + Vec<3> rs, x, pmin; + + int nf = faces.Size(); + + a.SetSize (nf); + c.SetSize (nf); + + for (int i = 0; i < nf; i++) + { + Point3d p1 = points.Get(faces[i][0]); + a[i] = Cross (points.Get(faces[i][1]) - p1, + points.Get(faces[i][2]) - p1); + a[i] /= a[i].Length(); + c[i] = - (a[i].X() * p1.X() + a[i].Y() * p1.Y() + a[i].Z() * p1.Z()); + } + + + x = 0; + + + double hmax = 0; + for (int i = 0; i < nf; i++) + { + const Element2d & el = faces[i]; + for (int j = 1; j <= 3; j++) + { + double hi = Dist (points.Get(el.PNumMod(j)), + points.Get(el.PNumMod(j+1))); + if (hi > hmax) hmax = hi; + } + } + + double fmin = 0; + + for (int i1 = 1; i1 <= nf; i1++) + for (int i2 = i1+1; i2 <= nf; i2++) + for (int i3 = i2+1; i3 <= nf; i3++) + for (int i4 = i3+1; i4 <= nf; i4++) + { + m(0, 0) = a.Get(i1).X() - a.Get(i2).X(); + m(0, 1) = a.Get(i1).Y() - a.Get(i2).Y(); + m(0, 2) = a.Get(i1).Z() - a.Get(i2).Z(); + rs(0) = c.Get(i2) - c.Get(i1); + + m(1, 0) = a.Get(i1).X() - a.Get(i3).X(); + m(1, 1) = a.Get(i1).Y() - a.Get(i3).Y(); + m(1, 2) = a.Get(i1).Z() - a.Get(i3).Z(); + rs(1) = c.Get(i3) - c.Get(i1); + + m(2, 0) = a.Get(i1).X() - a.Get(i4).X(); + m(2, 1) = a.Get(i1).Y() - a.Get(i4).Y(); + m(2, 2) = a.Get(i1).Z() - a.Get(i4).Z(); + rs(2) = c.Get(i4) - c.Get(i1); + + + if (fabs (Det (m)) > 1e-10) + { + CalcInverse (m, inv); + x = inv * rs; + + double f = -1e10; + for (int i = 0; i < nf; i++) + { + double hd = + x(0) * a[i].X() + x(1) * a[i].Y() + x(2) * a[i].Z() + c[i]; + if (hd > f) f = hd; + if (hd > fmin) break; + } + + if (f < fmin) + { + fmin = f; + pmin = x; + } + } + } + + p = Point3d (pmin(0), pmin(1), pmin(2)); + (*testout) << "fmin = " << fmin << endl; + return (fmin < -1e-3 * hmax); +} + diff --git a/libsrc/meshing/geomsearch.cpp b/libsrc/meshing/geomsearch.cpp new file mode 100644 index 00000000..5a2192ea --- /dev/null +++ b/libsrc/meshing/geomsearch.cpp @@ -0,0 +1,263 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + GeomSearch3d :: GeomSearch3d() + { + size.i1 = 0; size.i2 = 0; size.i3 = 0; + }; + + GeomSearch3d :: ~GeomSearch3d() + { + //delete old Hashtable: + if (size.i1 != 0) + { + for (int i = 0; i < size.i1*size.i2*size.i3; i++) + delete hashtable[i]; + } + } + + void GeomSearch3d :: Init (Array *pointsi, Array *facesi) + { + points = pointsi; + faces = facesi; + size.i1 = 0; size.i2 = 0; size.i3 = 0; + reset = 1; + hashcount = 1; + } + + void GeomSearch3d :: ElemMaxExt(Point3d& minp, Point3d& maxp, const MiniElement2d& elem) + { + maxp.X()=(*points)[elem.PNum(1)].P()(0); + maxp.Y()=(*points)[elem.PNum(1)].P()(1); + maxp.Z()=(*points)[elem.PNum(1)].P()(2); + minp.X()=(*points)[elem.PNum(1)].P()(0); + minp.Y()=(*points)[elem.PNum(1)].P()(1); + minp.Z()=(*points)[elem.PNum(1)].P()(2); + + for (int i=2; i <= 3; i++) + { + maxp.X()=max2((*points)[elem.PNum(i)].P()(0),maxp.X()); + maxp.Y()=max2((*points)[elem.PNum(i)].P()(1),maxp.Y()); + maxp.Z()=max2((*points)[elem.PNum(i)].P()(2),maxp.Z()); + minp.X()=min2((*points)[elem.PNum(i)].P()(0),minp.X()); + minp.Y()=min2((*points)[elem.PNum(i)].P()(1),minp.Y()); + minp.Z()=min2((*points)[elem.PNum(i)].P()(2),minp.Z()); + } + } + + void GeomSearch3d :: MinCoords(const Point3d& p1, Point3d& p2) + { + p2.X()=min2(p1.X(),p2.X()); + p2.Y()=min2(p1.Y(),p2.Y()); + p2.Z()=min2(p1.Z(),p2.Z()); + } + + void GeomSearch3d :: MaxCoords(const Point3d& p1, Point3d& p2) + { + p2.X()=max2(p1.X(),p2.X()); + p2.Y()=max2(p1.Y(),p2.Y()); + p2.Z()=max2(p1.Z(),p2.Z()); + } + + void GeomSearch3d :: Create() + { + INDEX i,j,k; + if (reset) + { + const double hashelemsizefactor = 4; + reset = 0; + /* + minext=Point3d(MAXDOUBLE, MAXDOUBLE, MAXDOUBLE); + maxext=Point3d(MINDOUBLE, MINDOUBLE, MINDOUBLE); + */ + ElemMaxExt(minext, maxext, faces->Get(1).Face()); + Point3d maxp, minp; + Vec3d midext(0,0,0); + + //get max Extension of Frontfaces + for (i = 1; i <= faces->Size(); i++) + { + ElemMaxExt(minp, maxp, faces->Get(i).Face()); + MinCoords(minp, minext); + MaxCoords(maxp, maxext); + midext+=maxp-minp; + } + + + maxextreal = maxext; + maxext = maxext + 1e-4 * (maxext - minext); + + midext*=1./faces->Size(); + Vec3d boxext = maxext - minext; + + //delete old Hashtable: + if (size.i1 != 0) + { + for (i = 1; i <= size.i1*size.i2*size.i3; i++) + { + delete hashtable.Get(i); + } + } + + size.i1 = int (boxext.X()/midext.X()/hashelemsizefactor+1); + size.i2 = int (boxext.Y()/midext.Y()/hashelemsizefactor+1); + size.i3 = int (boxext.Z()/midext.Z()/hashelemsizefactor+1); + // PrintMessage (5, "hashsizes = ", size.i1, ", ", size.i2, ", ", size.i3); + + elemsize.X()=boxext.X()/size.i1; + elemsize.Y()=boxext.Y()/size.i2; + elemsize.Z()=boxext.Z()/size.i3; + + //create Hasharrays: + hashtable.SetSize(size.i1*size.i2*size.i3); + for (i = 1; i <= size.i1; i++) + { + for (j = 1; j <= size.i2; j++) + { + for (k = 1; k <= size.i3; k++) + { + INDEX ind=i+(j-1)*size.i1+(k-1)*size.i2*size.i1; + hashtable.Elem(ind) = new Array (); + } + } + } + } + else + { + //Clear all Hash-Arrays + for (i = 1; i <= size.i1; i++) + { + for (j = 1; j <= size.i2; j++) + { + for (k = 1; k <= size.i3; k++) + { + INDEX ind=i+(j-1)*size.i1+(k-1)*size.i2*size.i1; + hashtable.Elem(ind)->SetSize(0); + } + } + } + } + + //Faces in Hashtable einfuegen: + for (i = 1; i <= faces->Size(); i++) + { + AddElem(faces->Get(i).Face(),i); + } + + } + + void GeomSearch3d :: AddElem(const MiniElement2d& elem, INDEX elemnum) + { + Point3d minp, maxp; + ElemMaxExt(minp, maxp, elem); + int sx = int ((minp.X()-minext.X())/elemsize.X()+1.); + int ex = int ((maxp.X()-minext.X())/elemsize.X()+1.); + int sy = int ((minp.Y()-minext.Y())/elemsize.Y()+1.); + int ey = int ((maxp.Y()-minext.Y())/elemsize.Y()+1.); + int sz = int ((minp.Z()-minext.Z())/elemsize.Z()+1.); + int ez = int ((maxp.Z()-minext.Z())/elemsize.Z()+1.); + + for (int ix = sx; ix <= ex; ix++) + for (int iy = sy; iy <= ey; iy++) + for (int iz = sz; iz <= ez; iz++) + { + INDEX ind=ix+(iy-1)*size.i1+(iz-1)*size.i2*size.i1; + if (ind < 1 || ind > size.i1 * size.i2 * size.i3) + { + cerr << "Illegal hash-position"; + cerr << "Position: " << ix << "," << iy << "," << iz << endl; + throw NgException ("Illegal position in Geomsearch"); + } + hashtable.Elem(ind)->Append(elemnum); + } + } + + void GeomSearch3d :: GetLocals(Array & locfaces, Array & findex, + INDEX fstind, const Point3d& p0, double xh) + { + hashcount++; + + Point3d minp, maxp, midp; + + minp=p0-Vec3d(xh,xh,xh); //lay cube over sphere + maxp=p0+Vec3d(xh,xh,xh); + + MaxCoords(minext,minp); //cube may not be out of hash-region + MinCoords(maxextreal,maxp); + + + int cluster = faces->Get(fstind).Cluster(); + + int sx = int((minp.X()-minext.X())/elemsize.X()+1.); + int ex = int((maxp.X()-minext.X())/elemsize.X()+1.); + int sy = int((minp.Y()-minext.Y())/elemsize.Y()+1.); + int ey = int((maxp.Y()-minext.Y())/elemsize.Y()+1.); + int sz = int((minp.Z()-minext.Z())/elemsize.Z()+1.); + int ez = int((maxp.Z()-minext.Z())/elemsize.Z()+1.); + int ix,iy,iz,i,k; + + int cnt1 = 0; // test, how efficient hashtable is + int cnt2 = 0; + int cnt3 = 0; + + for (ix = sx; ix <= ex; ix++) + { + for (iy = sy; iy <= ey; iy++) + { + for (iz = sz; iz <= ez; iz++) + { + INDEX ind=ix+(iy-1)*size.i1+(iz-1)*size.i2*size.i1; + + //go through all elements in one hash area + const Array & area = *hashtable.Elem(ind); + for (k = 1; k <= area.Size(); k++) + { + cnt2++; + i = area.Get(k); + if (faces->Get(i).Cluster() == cluster && + faces->Get(i).Valid() && + faces->Get(i).HashValue() != hashcount && + i != fstind) + { + cnt1++; + const MiniElement2d & face = faces->Get(i).Face(); + + const Point3d & p1 = (*points)[face.PNum(1)].P(); + const Point3d & p2 = (*points)[face.PNum(2)].P(); + const Point3d & p3 = (*points)[face.PNum(3)].P(); + + midp = Center (p1, p2, p3); + + // if (Dist2 (midp, p0) <= xh*xh) + if((Dist2 (p1, p0) <= xh*xh) || + (Dist2 (p2, p0) <= xh*xh) || + (Dist2 (p3, p0) <= xh*xh) || + (Dist2 (midp, p0) <= xh*xh) ) // by Jochen Wild + { + cnt3++; + locfaces.Append(faces->Get(i).Face()); + findex.Append(i); + faces->Elem(i).SetHashValue(hashcount); + } + } + } + } + } + } + /* + if (faces->Size() != 0 && hashcount % 200 == 0) + { + (*mycout) << "n.o.f= " << faces->Size(); + (*mycout) << ", n.o.lf= " << locfaces.Size(); + (*mycout) << ", hashf= " << (double)cnt2/(double)faces->Size(); + (*mycout) << " (" << (double)cnt1/(double)faces->Size(); + (*mycout) << ", " << (double)cnt3/(double)faces->Size() << ")" << endl; + } + */ + + } + +} diff --git a/libsrc/meshing/geomsearch.hpp b/libsrc/meshing/geomsearch.hpp new file mode 100644 index 00000000..d483c823 --- /dev/null +++ b/libsrc/meshing/geomsearch.hpp @@ -0,0 +1,117 @@ +#ifndef FILE_GEOMSEARCH +#define FILE_GEOMSEARCH + +/**************************************************************************/ +/* File: geomsearch.hh */ +/* Author: Johannes Gerstmayr */ +/* Date: 19. Nov. 97 */ +/**************************************************************************/ + +class FrontPoint3; +class FrontFace; +class MiniElement2d; + + /// class for quick access of 3D-elements; class cannot delete elements, but only append +class GeomSearch3d +{ + +public: + /// + GeomSearch3d(); + /// + virtual ~GeomSearch3d(); + + /// + void Init (Array *pointsi, Array *facesi); + + ///get elements max extension + void ElemMaxExt(Point3d& minp, Point3d& maxp, const MiniElement2d& elem); + + ///get minimum coordinates of two points ->p2 + void MinCoords(const Point3d& p1, Point3d& p2); + + ///get minimum coordinates of two points ->p2 + void MaxCoords(const Point3d& p1, Point3d& p2); + + ///create a hashtable from an existing array of triangles + ///sizei = number of pieces in one direction + void Create(); + + ///add new element to Hashtable + void AddElem(const MiniElement2d& elem, INDEX elemnum); + + ///GetLocal faces in sphere with radius xh and middlepoint p + void GetLocals(Array & locfaces, Array & findex, + INDEX fstind, const Point3d& p0, double xh); + +private: + + Array *faces; // Pointers to Arrays in Adfront + Array *points; + + Array *> hashtable; + + Point3d minext; //extension of Hashdomain + Point3d maxext; + Point3d maxextreal; + Vec3d elemsize; //size of one Hash-Element + + threeint size; // size of Hashtable in each direction + int reset; + int hashcount; +}; + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libsrc/meshing/global.cpp b/libsrc/meshing/global.cpp new file mode 100644 index 00000000..477c84e8 --- /dev/null +++ b/libsrc/meshing/global.cpp @@ -0,0 +1,61 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + // stringstream emptystr; + // ostream * testout = &emptystr; + // testout -> clear(ios::failbit); + + // ostream * testout = &cout; + ostream * testout = new ostream(0); + + // NetgenOutStream * testout = new NetgenOutStream; + + ostream * mycout = &cout; + ostream * myerr = &cerr; + + + // Flags parameters; + + + int silentflag = 0; + int testmode = 0; + + volatile multithreadt multithread; + + string ngdir = "."; + + Array tets_in_qualclass; + + int h_argc = 0; + char ** h_argv = NULL; + + multithreadt :: multithreadt() + { + pause =0; + testmode = 0; + redraw = 0; + drawing = 0; + terminate = 0; + running = 0; + percent = 0; + task = ""; + } + + DebugParameters debugparam; + bool verbose = 0; + + int timestamp = 0; + int GetTimeStamp() + { + return timestamp; + } + + int NextTimeStamp() + { + timestamp++; + return timestamp; + } +} diff --git a/libsrc/meshing/global.hpp b/libsrc/meshing/global.hpp new file mode 100644 index 00000000..5538de65 --- /dev/null +++ b/libsrc/meshing/global.hpp @@ -0,0 +1,57 @@ +#ifndef FILE_GLOBAL +#define FILE_GLOBAL + + +/**************************************************************************/ +/* File: global.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Okt. 95 */ +/**************************************************************************/ + +/* + global functions and variables +*/ + +namespace netgen +{ + + /// + DLL_HEADER extern double GetTime (); + extern void ResetTime (); + + /// + extern int testmode; + + /// calling parameters + // extern Flags parameters; + + // extern DLL_HEADER MeshingParameters mparam; + + extern Array tets_in_qualclass; + + class multithreadt + { + public: + int pause; + int testmode; + int redraw; + int drawing; + int terminate; + int running; + double percent; + const char * task; + bool demorunning; + multithreadt(); + }; + + extern volatile multithreadt multithread; + + DLL_HEADER extern string ngdir; + extern DebugParameters debugparam; + extern bool verbose; + + extern int h_argc; + extern char ** h_argv; +} + +#endif diff --git a/libsrc/meshing/hpref_hex.hpp b/libsrc/meshing/hpref_hex.hpp new file mode 100644 index 00000000..11e3f86e --- /dev/null +++ b/libsrc/meshing/hpref_hex.hpp @@ -0,0 +1,236 @@ +// SZ + +// HP_HEX ... no refinement +int refhex_splitedges[][3] = + { + { 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE refhex_newelstypes[] = + { + HP_HEX, + HP_NONE, + }; +int refhex_newels[][8] = + { + { 1, 2, 3, 4, 5, 6, 7, 8 } + }; +HPRef_Struct refhex = + { + HP_HEX, + refhex_splitedges, + 0, 0, + refhex_newelstypes, + refhex_newels + }; + +// HP_HEX_1F ... face (1 - 4 - 3 -2) singular +int refhex_1f_0e_0v_splitedges[][3] = + { + { 1, 5, 9 }, + { 2, 6, 10 }, + { 3, 7, 11 }, + { 4, 8, 12 }, + { 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE refhex_1f_0e_0v_newelstypes[] = + { + HP_HEX, + HP_HEX_1F_0E_0V, + HP_NONE, + }; +int refhex_1f_0e_0v_newels[][8] = + { + { 9, 10, 11, 12, 5, 6, 7, 8 }, + { 1, 2, 3, 4, 9, 10, 11, 12} + }; +HPRef_Struct refhex_1f_0e_0v = + { + HP_HEX, + refhex_1f_0e_0v_splitedges, + 0, 0, + refhex_1f_0e_0v_newelstypes, + refhex_1f_0e_0v_newels + }; + + + +// HP_HEX_1FA_1FB ... face (1 - 4 - 3 -2) and face (1-2-6-5) singular +int refhex_1fa_1fb_0e_0v_splitedges[][3] = + { + { 1, 5, 9 }, + { 2, 6, 10 }, + { 3, 7, 11 }, + { 4, 8, 12 }, + { 1, 4, 13 }, + { 2, 3, 14 }, + { 6, 7, 15 }, + { 5, 8, 16 }, + { 0, 0, 0 } + }; + +int refhex_1fa_1fb_0e_0v_splitfaces[][4] = + { + { 2, 3, 6, 17 }, + { 1, 4, 5, 18 }, + { 0, 0, 0, 0 }, + }; +HPREF_ELEMENT_TYPE refhex_1fa_1fb_0e_0v_newelstypes[] = + { + HP_HEX, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; +int refhex_1fa_1fb_0e_0v_newels[][8] = + { + {18, 17, 11, 12, 16, 15, 7, 8}, + {13, 14, 3, 4, 18, 17, 11, 12}, + { 5, 6, 10, 9, 16, 15, 17, 18}, + { 1, 2, 14, 13, 9, 10, 17, 18} + }; +HPRef_Struct refhex_1fa_1fb_0e_0v = + { + HP_HEX, + refhex_1fa_1fb_0e_0v_splitedges, + refhex_1fa_1fb_0e_0v_splitfaces, 0, + refhex_1fa_1fb_0e_0v_newelstypes, + refhex_1fa_1fb_0e_0v_newels + }; + + + +// Refine Dummies + // HP_HEX_0E_1V + int refhex_0e_1v_splitedges[][3] = + { + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refhex_0e_1v_newelstypes[] = + { + HP_TET_0E_1V, + HP_TET, + HP_TET, + HP_TET, + HP_TET, + HP_TET, + HP_NONE, + }; + int refhex_0e_1v_newels[][8] = + { + { 1, 5, 2, 4 }, + { 7, 3, 6, 8 }, + { 2, 8, 5, 6 }, + { 2, 8, 6, 3 }, + { 2, 8, 3, 4 }, + { 2, 8, 4, 5 }, + }; + HPRef_Struct refhex_0e_1v = + { + HP_HEX, + refhex_0e_1v_splitedges, + 0, 0, + refhex_0e_1v_newelstypes, + refhex_0e_1v_newels + }; + + + +// Refine Dummies + // HP_HEX_1E_1V + int refhex_1e_1v_splitedges[][3] = + { + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refhex_1e_1v_newelstypes[] = + { + HP_TET_1E_1VA, + HP_TET, + HP_TET_0E_1V, + HP_TET_0E_1V, + HP_TET_0E_1V, + HP_TET_0E_1V, + HP_NONE, + }; + int refhex_1e_1v_newels[][8] = + { + // { 1, 5, 2, 4 }, + { 1, 2, 4, 5 }, + { 7, 3, 6, 8 }, + { 2, 8, 5, 6 }, + { 2, 8, 6, 3 }, + { 2, 8, 3, 4 }, + { 2, 8, 4, 5 }, + }; + HPRef_Struct refhex_1e_1v = + { + HP_HEX, + refhex_1e_1v_splitedges, + 0, 0, + refhex_1e_1v_newelstypes, + refhex_1e_1v_newels + }; + + +// Refine Dummies + // HP_HEX_3E_0V + int refhex_3e_0v_splitedges[][3] = + { + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refhex_3e_0v_newelstypes[] = + { + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_TET_0E_1V, + HP_TET, + HP_NONE, + }; + int refhex_3e_0v_newels[][8] = + { + { 1, 2, 3, 6 }, + { 1, 4, 8, 3 }, + { 1, 5, 6, 8 }, + { 1, 6, 3, 8 }, + { 3, 8, 6, 7 }, + }; + HPRef_Struct refhex_3e_0v = + { + HP_HEX, + refhex_3e_0v_splitedges, + 0, 0, + refhex_3e_0v_newelstypes, + refhex_3e_0v_newels + }; + + + +// Refine Dummies + // HP_HEX_1E_0V + int refhex_1e_0v_splitedges[][3] = + { + { 0, 0, 0 } + }; + + HPREF_ELEMENT_TYPE refhex_1e_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, // HP_PRISM_SINGEDGE_H1, + HP_PRISM, + HP_NONE, + }; + int refhex_1e_0v_newels[][8] = + { + { 1, 4, 5, 2, 3, 6 }, + { 5, 4, 8, 6, 3, 7 }, + }; + HPRef_Struct refhex_1e_0v = + { + HP_HEX, + refhex_1e_0v_splitedges, + 0, 0, + refhex_1e_0v_newelstypes, + refhex_1e_0v_newels + }; + + diff --git a/libsrc/meshing/hpref_prism.hpp b/libsrc/meshing/hpref_prism.hpp new file mode 100644 index 00000000..3cceb44a --- /dev/null +++ b/libsrc/meshing/hpref_prism.hpp @@ -0,0 +1,3405 @@ + + // HP_PRISM ... no refinement + int refprism_splitedges[][3] = + { + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_newelstypes[] = + { + HP_PRISM, + HP_NONE, + }; + int refprism_newels[][8] = + { + { 1, 2, 3, 4, 5, 6 } + }; + HPRef_Struct refprism = + { + HP_PRISM, + refprism_splitedges, + 0, 0, + refprism_newelstypes, + refprism_newels + }; + + + + // HP_PRISM_SINGEDGE ... vertical edge 1-4 is singular + int refprism_singedge_splitedges[][3] = + { + { 1, 2, 7 }, + { 1, 3, 8 }, + { 4, 5, 9 }, + { 4, 6, 10 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_singedge_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_NONE, + }; + int refprism_singedge_newels[][8] = + { + { 1, 7, 8, 4, 9, 10 }, + { 3, 8, 7, 2, 6, 10, 9, 5 } + }; + HPRef_Struct refprism_singedge = + { + HP_PRISM, + refprism_singedge_splitedges, + 0, 0, + refprism_singedge_newelstypes, + refprism_singedge_newels + }; + + + + + + + // HP_PRISM_SINGEDGE_V12 vertical edges 1-4 and 2-5 are singular + int refprism_singedge_v12_splitedges[][3] = + { + { 1, 2, 7 }, + { 1, 3, 8 }, + { 2, 1, 9 }, + { 2, 3, 10 }, + { 4, 5, 11 }, + { 4, 6, 12 }, + { 5, 4, 13 }, + { 5, 6, 14}, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_singedge_v12_newelstypes[] = + { + HP_HEX, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_NONE, + }; + int refprism_singedge_v12_newels[][8] = + { + { 7, 9, 10, 8, 11, 13, 14, 12 }, + { 1, 7, 8, 4, 11, 12 }, + { 2, 10, 9, 5, 14, 13 }, + { 3, 8, 10, 6, 12, 14 }, + }; + HPRef_Struct refprism_singedge_v12 = + { + HP_PRISM, + refprism_singedge_v12_splitedges, + 0, 0, + refprism_singedge_v12_newelstypes, + refprism_singedge_v12_newels + }; + + + + + + + // HP_PRISM_SINGEDGE_H12 + int refprism_singedge_h12_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 3, 1, 10 }, + + { 4, 6, 12 }, + { 5, 4, 13 }, + { 5, 6, 14 }, + { 6, 4, 15 }, + + { 0, 0, 0 } + }; + + int refprism_singedge_h12_splitfaces[][4] = + { + { 2, 1, 3, 11 }, + { 5, 4, 6, 16 }, + { 0, 0, 0, 0 }, + }; + + HPREF_ELEMENT_TYPE refprism_singedge_h12_newelstypes[] = + { + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_NONE, + }; + int refprism_singedge_h12_newels[][8] = + { + { 1, 8, 11, 7, 4, 13, 16, 12 }, + { 9, 3, 10, 11, 14, 6, 15, 16 }, + { 7, 11, 10, 12, 16, 15 }, + { 2, 9, 11, 5, 14, 16 }, + { 8, 2, 11, 13, 5, 16 } + }; + HPRef_Struct refprism_singedge_h12 = + { + HP_PRISM, + refprism_singedge_h12_splitedges, + refprism_singedge_h12_splitfaces, + 0, + refprism_singedge_h12_newelstypes, + refprism_singedge_h12_newels + }; + + + + + + + // HP_PRISM_SINGEDGE_H1 + int refprism_singedge_h1_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 4, 6, 9 }, + { 5, 6, 10 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_singedge_h1_newelstypes[] = + { + HP_HEX, + HP_PRISM, + HP_NONE, + }; + int refprism_singedge_h1_newels[][8] = + { + { 1, 2, 8, 7, 4, 5, 10, 9 }, + { 3, 7, 8, 6, 9, 10 } + }; + HPRef_Struct refprism_singedge_h1 = + { + HP_PRISM, + refprism_singedge_h1_splitedges, + 0, 0, + refprism_singedge_h1_newelstypes, + refprism_singedge_h1_newels + }; + + + +// HP_PRISM_1FA_0E_0V + int refprism_1fa_0e_0v_splitedges[][3] = + { + { 1, 4, 16 }, + { 2, 5, 17 }, + { 3, 6, 18 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fa_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_NONE, + }; + int refprism_1fa_0e_0v_newels[][8] = + { + { 16, 17, 18, 4, 5, 6 }, + { 1, 2, 3, 16, 17, 18 } + }; + HPRef_Struct refprism_1fa_0e_0v = + { + HP_PRISM, + refprism_1fa_0e_0v_splitedges, + 0, 0, + refprism_1fa_0e_0v_newelstypes, + refprism_1fa_0e_0v_newels + }; + +// HP_PRISM_1FA_1E_0V + int refprism_1fa_1e_0v_splitedges[][3] = + { + { 1, 4, 16 }, + { 2, 5, 17 }, + { 3, 6, 18 }, + { 1, 2, 7}, + { 1, 3, 12}, + { 4, 6, 45}, + { 4, 5, 40}, + { 0, 0, 0 } + }; + int refprism_1fa_1e_0v_splitfaces[][4] = + { + {1,2,4,19}, + {1,3,4,24}, + {0,0,0,0} + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1e_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_1fa_1e_0v_newels[][8] = + { + { 16, 19, 24, 4, 40, 45 }, + { 24, 19, 17, 18, 45 , 40, 5, 6 }, + { 1, 7 , 12 , 16, 19, 24 }, + { 7, 2, 3, 12, 19, 17, 18, 24 } + }; + HPRef_Struct refprism_1fa_1e_0v = + { + HP_PRISM, + refprism_1fa_1e_0v_splitedges, + refprism_1fa_1e_0v_splitfaces, + 0, + refprism_1fa_1e_0v_newelstypes, + refprism_1fa_1e_0v_newels + }; + +// HP_PRISM_2FA_1E_0V + int refprism_2fa_1e_0v_splitedges[][3] = + { + { 1, 4, 16 }, + { 2, 5, 17 }, + { 3, 6, 18 }, + { 1, 2, 7}, + { 1, 3, 12}, + { 4, 6, 45}, + { 4, 5, 40}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 0, 0, 0 } + }; + int refprism_2fa_1e_0v_splitfaces[][4] = + { + {1,2,4,19}, + {1,3,4,24}, + {4,1,5,31}, + {4,1,6,36}, + {0,0,0,0} + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1e_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_2fa_1e_0v_newels[][8] = + { + { 16, 19, 24, 28, 31, 36 }, + { 24, 19, 17, 18, 36, 31, 29, 30 }, + { 1, 7 , 12 , 16, 19, 24 }, + { 12, 7, 2, 3, 24, 19, 17, 18 }, + { 4, 45, 40, 28, 36, 31 }, + { 40, 45, 6, 5, 31, 36, 30, 29,} + }; + HPRef_Struct refprism_2fa_1e_0v = + { + HP_PRISM, + refprism_2fa_1e_0v_splitedges, + refprism_2fa_1e_0v_splitfaces, + 0, + refprism_2fa_1e_0v_newelstypes, + refprism_2fa_1e_0v_newels + }; + +// HP_PRISM_1FB_0E_0V ... quad face 1-2-4-5 + int refprism_1fb_0e_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 4, 6, 9 }, + { 5, 6, 10 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_0e_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_NONE, + }; + int refprism_1fb_0e_0v_newels[][8] = + { + { 1, 4, 5, 2, 7, 9, 10, 8 }, + { 7, 8, 3, 9, 10, 6 } + }; + HPRef_Struct refprism_1fb_0e_0v = + { + HP_PRISM, + refprism_1fb_0e_0v_splitedges, + + 0, 0, + refprism_1fb_0e_0v_newelstypes, + refprism_1fb_0e_0v_newels + }; + + +// HP_PRISM_1FB_1EA_0V ... quad face 1-2-4-5 + int refprism_1fb_1ea_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 4, 6, 9 }, + { 5, 6, 10 }, + { 1, 2, 11 }, + { 4, 5, 12 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_1ea_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM, + HP_NONE, + }; + int refprism_1fb_1ea_0v_newels[][8] = + { + { 11, 12, 5, 2, 7, 9, 10, 8 }, + { 1, 11, 7, 4, 12, 9 }, + { 7, 8, 3, 9, 10, 6 } + }; + HPRef_Struct refprism_1fb_1ea_0v = + { + HP_PRISM, + refprism_1fb_1ea_0v_splitedges, + 0, 0, + refprism_1fb_1ea_0v_newelstypes, + refprism_1fb_1ea_0v_newels + }; + +// HP_PRISM_1FB_1EC_0V ... quad face 1-2-4-5 with singular edge 3-6 + int refprism_1fb_1ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_1fb_1ec_0v_newels[][8] = + { + { 3, 11, 10, 6, 44, 43}, + { 12, 9, 10, 11, 45, 42, 43, 44}, + { 4, 5, 2, 1, 45, 42, 9, 12 } + }; + HPRef_Struct refprism_1fb_1ec_0v = + { + HP_PRISM, + refprism_1fb_1ec_0v_splitedges, + 0, 0, + refprism_1fb_1ec_0v_newelstypes, + refprism_1fb_1ec_0v_newels + }; + +// HP_PRISM_1FA_1FB_1EC_0V ... bot-trig face, quad face 1-2-4-5 with singular edge 3-6 + int refprism_1fa_1fb_1ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 0, 0, 0 } + }; + + int refprism_1fa_1fb_1ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_1fa_1fb_1ec_0v_newels[][8] = + { + { 18, 23, 22, 6, 44, 43}, + { 24, 21, 22, 23, 45, 42, 43, 44}, + { 4, 5, 17, 16, 45, 42, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 1, 2, 9, 12, 16, 17, 21, 24} + }; + HPRef_Struct refprism_1fa_1fb_1ec_0v = + { + HP_PRISM, + refprism_1fa_1fb_1ec_0v_splitedges, + refprism_1fa_1fb_1ec_0v_splitfaces, 0, + refprism_1fa_1fb_1ec_0v_newelstypes, + refprism_1fa_1fb_1ec_0v_newels + }; + + +// HP_PRISM_1FA_1FB_2EB_0V + int refprism_1fa_1fb_2eb_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 4, 5, 40}, + { 4, 6, 45}, + { 1, 2, 7}, + { 0, 0, 0 } + }; + + int refprism_1fa_1fb_2eb_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {1,2,4,19}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_1fa_1fb_2eb_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fa_1fb_2eb_0v_newels[][8] = + { + { 18, 23, 22, 6, 44, 43}, + { 24, 21, 22, 23, 45, 42, 43, 44}, + { 40, 5, 17, 19, 45, 42, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 7, 2, 9, 12, 19, 17, 21, 24}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_1fb_2eb_0v = + { + HP_PRISM, + refprism_1fa_1fb_2eb_0v_splitedges, + refprism_1fa_1fb_2eb_0v_splitfaces, 0, + refprism_1fa_1fb_2eb_0v_newelstypes, + refprism_1fa_1fb_2eb_0v_newels + }; + + // HP_PRISM_1FA_1FB_2EC_0V + int refprism_1fa_1fb_2ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,4,41}, + {2,1,8}, + { 0, 0, 0 } + }; + + int refprism_1fa_1fb_2ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {2,1,5,20}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_1fa_1fb_2ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fa_1fb_2ec_0v_newels[][8] = + { + { 18, 23, 22, 6, 44, 43}, + { 24, 21, 22, 23, 45, 42, 43, 44}, + { 4, 41, 20, 16, 45, 42, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 1, 8, 9, 12, 16, 20, 21, 24}, + {8,2,9,20,17,21}, + {5,41,42,17,20,21} + }; + HPRef_Struct refprism_1fa_1fb_2ec_0v = + { + HP_PRISM, + refprism_1fa_1fb_2ec_0v_splitedges, + refprism_1fa_1fb_2ec_0v_splitfaces, + 0, + refprism_1fa_1fb_2ec_0v_newelstypes, + refprism_1fa_1fb_2ec_0v_newels + }; + + + + + + + +// HP_PRISM_2FA_1FB_1EC_0V ... trig faces, quad face 1-2-4-5 with singular edge 3-6 + int refprism_2fa_1fb_1ec_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 0, 0, 0 } + }; + + int refprism_2fa_1fb_1ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {5,2,6,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_2fa_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_2fa_1fb_1ec_0v_newels[][8] = + { + { 18, 23, 22, 30, 35, 34}, + { 24, 21, 22, 23, 36, 33, 34, 35}, + { 28, 29, 17, 16, 36, 33, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 1, 2, 9, 12, 16, 17, 21, 24}, + { 6, 43, 44, 30, 34, 35}, + { 44, 43, 42, 45, 35, 34, 33, 36}, + { 5, 4, 45, 42, 29, 28, 36, 33 }, + }; + HPRef_Struct refprism_2fa_1fb_1ec_0v = + { + HP_PRISM, + refprism_2fa_1fb_1ec_0v_splitedges, + refprism_2fa_1fb_1ec_0v_splitfaces, + 0, + refprism_2fa_1fb_1ec_0v_newelstypes, + refprism_2fa_1fb_1ec_0v_newels + }; + +// HP_PRISM_2FA_1FB_2EB_0V + int refprism_2fa_1fb_2eb_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {3,2,10}, + {3,1,11}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + {4,5,40}, + {1,2,7}, + { 0, 0, 0 } + }; + + int refprism_2fa_1fb_2eb_0v_splitfaces[][4] = + { + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,1,5,31}, + {1,2,4,19}, + {0,0,0,0} + }; + HPREF_ELEMENT_TYPE refprism_2fa_1fb_2eb_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_NONE, + }; + int refprism_2fa_1fb_2eb_0v_newels[][8] = + { + { 18, 23, 22, 30, 35, 34}, + { 24, 21, 22, 23, 36, 33, 34, 35}, + { 31, 29, 17, 19, 36, 33, 21, 24}, + { 3, 11, 10, 18, 23, 22}, + { 12, 9, 10, 11, 24, 21, 22, 23}, + { 7, 2, 9, 12, 19, 17, 21, 24}, + { 6, 43, 44, 30, 34, 35}, + { 44, 43, 42, 45, 35, 34, 33, 36}, + { 5, 40, 45, 42, 29, 31, 36, 33 }, + { 1, 7, 12, 16, 19, 24 }, + { 16, 19, 24, 28, 31, 36 }, + { 40, 4, 45, 31, 28, 36 }, + }; + HPRef_Struct refprism_2fa_1fb_2eb_0v = + { + HP_PRISM, + refprism_2fa_1fb_2eb_0v_splitedges, + refprism_2fa_1fb_2eb_0v_splitfaces, 0, + refprism_2fa_1fb_2eb_0v_newelstypes, + refprism_2fa_1fb_2eb_0v_newels + }; + +// HP_PRISM_1FB_2EA_0V ... quad face 1-2-4-5 with singular edges 1-4, 2-5 + int refprism_1fb_2ea_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 2, 1, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 5, 4, 14 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_2ea_0v_newelstypes[] = + { + HP_PRISM, + HP_PRISM_1FB_1EA_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fb_2ea_0v_newels[][8] = + { + { 7, 8, 3, 11, 12, 6 }, + { 1, 9, 7, 4, 13, 11 }, + { 13, 14, 10, 9, 11, 12, 8, 7 }, + { 5, 14, 12, 2, 10, 8 }, + }; + HPRef_Struct refprism_1fb_2ea_0v = + { + HP_PRISM, + refprism_1fb_2ea_0v_splitedges, + 0, 0, + refprism_1fb_2ea_0v_newelstypes, + refprism_1fb_2ea_0v_newels + }; + +// HP_PRISM_1FB_2EB_0V ... quad face 1-2-4-5 with singular edges 1-4, 3-6 + int refprism_1fb_2eb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE refprism_1fb_2eb_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FB_1EA_0V, + HP_HEX_1F_0E_0V, + HP_NONE, + }; + int refprism_1fb_2eb_0v_newels[][8] = + { + { 3, 11, 10, 6, 44, 43 }, + { 12, 9, 10, 11, 45, 42, 43, 44}, + { 1, 7, 12, 4, 40, 45}, + { 40, 5, 2, 7, 45, 42, 9, 12} + }; + HPRef_Struct refprism_1fb_2eb_0v = + { + HP_PRISM, + refprism_1fb_2eb_0v_splitedges, + 0, 0, + refprism_1fb_2eb_0v_newelstypes, + refprism_1fb_2eb_0v_newels + }; + +// HP_PRISM_1FB_3E_0V ... quad face 1-2-4-5 with singular edges 1-4, 3-6 + int refprism_1fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_3e_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_HEX, + HP_PRISM_1FB_1EA_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_1fb_3e_0v_newels[][8] = + { + { 3, 11, 10, 6, 44, 43 }, + { 12, 9, 10, 11, 45, 42, 43, 44}, + { 1, 7, 12, 4, 40, 45 }, + { 40, 41, 8, 7, 45, 42, 9, 12}, + { 5, 41, 42, 2, 8, 9}, + }; + HPRef_Struct refprism_1fb_3e_0v = + { + HP_PRISM, + refprism_1fb_3e_0v_splitedges, + 0, 0, + refprism_1fb_3e_0v_newelstypes, + refprism_1fb_3e_0v_newels + }; + + + +// HP_PRISM_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 + int refprism_2fb_0e_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 3, 2, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 6, 5, 14 }, + { 0, 0, 0 } + }; + int refprism_2fb_0e_0v_splitfaces[][4] = + { + { 1, 2, 3, 15 }, + { 4, 5, 6, 16 }, + { 0, 0, 0, 0 }, + }; + HPREF_ELEMENT_TYPE refprism_2fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_2fb_0e_0v_newels[][8] = + { + { 15, 8, 10, 16, 12, 14 }, + { 13, 5, 2, 9, 16, 12, 8, 15}, + { 11, 7, 3, 6, 16, 15, 10, 14 }, + { 1, 9, 15, 4, 13, 16 }, + { 4, 11, 16, 1,7, 15 } + }; + HPRef_Struct refprism_2fb_0e_0v = + { + HP_PRISM, + refprism_2fb_0e_0v_splitedges, + refprism_2fb_0e_0v_splitfaces, + 0, + refprism_2fb_0e_0v_newelstypes, + refprism_2fb_0e_0v_newels + }; + +// HP_PRISM_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 and sing edge 3-6 + int refprism_2fb_1ec_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 3, 2, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 6, 5, 14 }, + { 3, 1, 17}, + { 6, 4, 18}, + { 0, 0, 0 } + }; + int refprism_2fb_1ec_0v_splitfaces[][4] = + { + { 1, 2, 3, 15 }, + { 4, 5, 6, 16 }, + { 0, 0, 0, 0 }, + }; + HPREF_ELEMENT_TYPE refprism_2fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_2fb_1ec_0v_newels[][8] = + { + { 15, 8, 10, 16, 12, 14 }, + { 13, 5, 2, 9, 16, 12, 8, 15}, + { 11, 7, 17, 18, 16, 15, 10, 14 }, + { 1, 9, 15, 4, 13, 16 }, + { 4, 11, 16, 1,7, 15 }, + { 3, 17, 10, 6, 18, 14 } + }; + HPRef_Struct refprism_2fb_1ec_0v = + { + HP_PRISM, + refprism_2fb_1ec_0v_splitedges, + refprism_2fb_1ec_0v_splitfaces, + 0, + refprism_2fb_1ec_0v_newelstypes, + refprism_2fb_1ec_0v_newels + }; + + + +// HP_PRISM_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 and 3 sing edges + int refprism_2fb_3e_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 1, 2, 9 }, + { 3, 2, 10 }, + { 4, 6, 11 }, + { 5, 6, 12 }, + { 4, 5, 13 }, + { 6, 5, 14 }, + { 3, 1, 17}, + { 6, 4, 18}, + { 2, 1, 19}, + { 5, 4, 20}, + { 0, 0, 0 } + }; + int refprism_2fb_3e_0v_splitfaces[][4] = + { + { 1, 2, 3, 15 }, + { 4, 5, 6, 16 }, + { 0, 0, 0, 0 }, + }; + HPREF_ELEMENT_TYPE refprism_2fb_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE, + }; + int refprism_2fb_3e_0v_newels[][8] = + { + { 15, 8, 10, 16, 12, 14 }, + { 13, 20, 19, 9, 16, 12, 8, 15}, + { 11, 7, 17, 18, 16, 15, 10, 14 }, + { 1, 9, 15, 4, 13, 16 }, + { 4, 11, 16, 1,7, 15 }, + { 3, 17, 10, 6, 18, 14 }, + { 5, 20, 12, 2, 19, 8 } + }; + HPRef_Struct refprism_2fb_3e_0v = + { + HP_PRISM, + refprism_2fb_3e_0v_splitedges, + refprism_2fb_3e_0v_splitfaces, 0, + refprism_2fb_3e_0v_newelstypes, + refprism_2fb_3e_0v_newels + }; + + + +// HP_PRISM_1FA_1FB_0E_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_0e_0v_splitedges[][3] = + { + {1,4,16}, + {2,5,17}, + {3,6,18}, + {2,3,9}, + {1,3,12}, + {5,6,42}, + {4,6,45}, + {0,0,0} + }; + int refprism_1fa_1fb_0e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + { 0, 0, 0, 0 } + }; + +HPREF_ELEMENT_TYPE refprism_1fa_1fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_1fa_1fb_0e_0v_newels[][8] = + { + { 24, 21, 18, 45, 42, 6 }, + { 4, 5, 17, 16, 45, 42, 21, 24 }, + { 12, 9, 3, 24, 21, 18 }, + { 1, 2, 9, 12, 16, 17, 21, 24 } + }; + HPRef_Struct refprism_1fa_1fb_0e_0v = + { + HP_PRISM, + refprism_1fa_1fb_0e_0v_splitedges, + + refprism_1fa_1fb_0e_0v_splitfaces, 0, + refprism_1fa_1fb_0e_0v_newelstypes, + refprism_1fa_1fb_0e_0v_newels + }; + +/* +// HP_PRISM_1FA_1FB_1EC_0V ... quad face 1-2-4-5 and trig face 1-2-3 +int refprism_1fa_1fb_1ec_0v_splitedges[][3] = + { + {1,4,16}, + {2,5,17}, + {3,6,18}, + {2,3,9}, + {1,3,12}, + {5,6,42}, + {4,6,45}, + {6,5,43}, + {6,4,44}, + {3,2,10}, + {3,1,11}, + {0,0,0} + }; + int refprism_1fa_1fb_1ec_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + { 0, 0, 0, 0 } + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_SINGEDGE, + HP_PRISM_1FA_1E_0V, + HP_PRISM_ + HP_NONE, + }; + int refprism_1fa_1fb_0e_0v_newels[][8] = + { + { 24, 21, 18, 45, 42, 6 }, + { 4, 5, 17, 16, 45, 42, 21, 24 }, + { 12, 9, 3, 24, 21, 18 }, + { 1, 2, 9, 12, 16, 17, 21, 24 } + }; + HPRef_Struct refprism_1fa_1fb_0e_0v = + { + HP_PRISM, + refprism_1fa_1fb_1ec_0v_splitedges, + + refprism_1fa_1fb_1ec_0v_splitfaces, 0, + refprism_1fa_1fb_1ec_0v_newelstypes, + refprism_1fa_1fb_1ec_0v_newels + }; + + +*/ + + + + +// HP_PRISM_2FA_1FB_0E_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_2fa_1fb_0e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {0,0,0} + + }; + int refprism_2fa_1fb_0e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {5,6,2,33}, + {4,1,6,36}, + {0,0,0,0} + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_0e_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_NONE, + }; + int refprism_2fa_1fb_0e_0v_newels[][8] = + { + {28,29,17,16,36,33,21,24}, + {24,21,18, 36, 33, 30}, + {12,9,3,24,21,18}, + {1,2,9,12,16,17,21,24}, + {6,42,45,30,33,36}, + {4,5,29,28,45,42,33,36} + }; + HPRef_Struct refprism_2fa_1fb_0e_0v = + { + HP_PRISM, + refprism_2fa_1fb_0e_0v_splitedges, + + refprism_2fa_1fb_0e_0v_splitfaces, 0, + refprism_2fa_1fb_0e_0v_newelstypes, + refprism_2fa_1fb_0e_0v_newels + }; + + +// HP_PRISM_1FA_1FB_1EA_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_1ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + }; + int refprism_1fa_1fb_1ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1ea_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_1fa_1fb_1ea_0v_newels[][8] = + { + {40,5,17,19,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {7,2,9,12,19,17,21,24}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + + }; + HPRef_Struct refprism_1fa_1fb_1ea_0v = + { + HP_PRISM, + refprism_1fa_1fb_1ea_0v_splitedges, + refprism_1fa_1fb_1ea_0v_splitfaces, 0, + refprism_1fa_1fb_1ea_0v_newelstypes, + refprism_1fa_1fb_1ea_0v_newels + }; + +// HP_PRISM_2FA_1FB_1EA_0V + int refprism_2fa_1fb_1ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + }; + int refprism_2fa_1fb_1ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {4,1,6,36}, + {4,1,5,31}, + {5,6,2,33}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_1ea_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_NONE + }; + int refprism_2fa_1fb_1ea_0v_newels[][8] = + { + { 18, 24, 21, 30, 36, 33}, + { 31, 29, 17, 19, 36, 33, 21, 24}, + { 16,19, 24, 28, 31, 36 }, + { 3, 12, 9, 18, 24, 21 }, + { 7, 2, 9, 12, 19, 17, 21, 24}, + { 1, 7, 12, 16, 19, 24 }, + { 6, 42, 45, 30, 33, 36 }, + { 40, 5, 29, 31, 45, 42, 33, 36 }, + { 40, 4, 45, 31, 28, 36} + }; + HPRef_Struct refprism_2fa_1fb_1ea_0v = + { + HP_PRISM, + refprism_2fa_1fb_1ea_0v_splitedges, + refprism_2fa_1fb_1ea_0v_splitfaces, 0, + refprism_2fa_1fb_1ea_0v_newelstypes, + refprism_2fa_1fb_1ea_0v_newels + }; + + +// HP_PRISM_2FA_1FB_2EA_0V + int refprism_2fa_1fb_2ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {4,5,40}, + {1,2,7}, + { 5, 4, 41}, + { 2, 1, 8}, + {0,0,0}, + }; + int refprism_2fa_1fb_2ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {4,1,6,36}, + {4,1,5,31}, + {5,6,2,33}, + {5,4,2,32}, + {2,1,5,20}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_2ea_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_2fa_1fb_2ea_0v_newels[][8] = + { + { 18, 24, 21, 30, 36, 33}, + { 31, 32, 20, 19, 36, 33, 21, 24}, + { 16,19, 24, 28, 31, 36 }, + { 3, 12, 9, 18, 24, 21 }, + {7,8,9,12,19,20,21,24}, + { 1, 7, 12, 16, 19, 24 }, + { 6, 42, 45, 30, 33, 36 }, + { 40, 41, 32, 31, 45, 42, 33, 36}, + { 40, 4, 45, 31, 28, 36}, + { 8, 2, 9, 20, 17, 21 }, + { 29, 32, 33, 17, 20, 21 }, + { 5, 41, 42, 29, 32, 33 }, + }; + HPRef_Struct refprism_2fa_1fb_2ea_0v = + { + HP_PRISM, + refprism_2fa_1fb_2ea_0v_splitedges, + refprism_2fa_1fb_2ea_0v_splitfaces, 0, + refprism_2fa_1fb_2ea_0v_newelstypes, + refprism_2fa_1fb_2ea_0v_newels + }; + +// HP_PRISM_2FA_1FB_3E_0V + int refprism_2fa_1fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + {0,0,0}, + }; + int refprism_2fa_1fb_3e_0v_splitfaces[][4] = + { + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_1fb_3e_0v_newelstypes[] = + { + HP_HEX, + HP_PRISM_SINGEDGE, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_HEX_1FA_1FB_0E_0V, + + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_HEX_1FA_1FB_0E_0V, + + HP_NONE + }; + int refprism_2fa_1fb_3e_0v_newels[][8] = + { + {24, 21, 22, 23, 36, 33, 34, 35}, + {18, 23, 22, 30, 35, 34}, + { 31, 32, 20, 19, 36, 33, 21, 24}, + { 16,19, 24, 28, 31, 36 }, + { 29, 32, 33, 17, 20, 21}, + + + { 12, 9,10,11, 24, 21, 22, 23 }, + { 3, 11, 10, 18,23,22}, + { 1, 7, 12 , 16, 19, 24}, + { 8,2,9, 20, 17,21}, + { 7,8,9,12,19, 20, 21, 24}, + + { 44, 43, 42, 45, 35, 34, 33, 36}, + { 6, 43, 44, 30, 34, 35}, + { 40, 4, 45, 31,28, 36}, + { 5, 41,42, 29, 32, 33}, + { 40, 41, 32, 31, 45, 42, 33, 36}, + }; + HPRef_Struct refprism_2fa_1fb_3e_0v = + { + HP_PRISM, + refprism_2fa_1fb_3e_0v_splitedges, + + refprism_2fa_1fb_3e_0v_splitfaces, 0, + refprism_2fa_1fb_3e_0v_newelstypes, + refprism_2fa_1fb_3e_0v_newels + }; + + + + +// HP_PRISM_1FA_1FB_1EB_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_1eb_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {0,0,0}, + }; + int refprism_1fa_1fb_1eb_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_1eb_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V , + HP_NONE + }; + int refprism_1fa_1fb_1eb_0v_newels[][8] = + { + {4,41,20,16,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {1,8,9,12,16,20,21,24}, + {5,41,42,17,20,21}, + {8,2,9,20,17,21} + }; + HPRef_Struct refprism_1fa_1fb_1eb_0v = + { + HP_PRISM, + refprism_1fa_1fb_1eb_0v_splitedges, + + refprism_1fa_1fb_1eb_0v_splitfaces, 0, + refprism_1fa_1fb_1eb_0v_newelstypes, + refprism_1fa_1fb_1eb_0v_newels + }; + + +// HP_PRISM_1FA_1FB_2EA_0V ... quad face 1-2-4-5 and trig face 1-2-3 + int refprism_1fa_1fb_2ea_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + + }; + int refprism_1fa_1fb_2ea_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {1,2,4,19}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_2ea_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V , + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_1fa_1fb_2ea_0v_newels[][8] = + { + {40,41,20,19,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {7,8,9,12,19,20,21,24}, + {5,41,42,17,20,21}, + {8,2,9,20,17,21}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_1fb_2ea_0v = + { + HP_PRISM, + refprism_1fa_1fb_2ea_0v_splitedges, + + refprism_1fa_1fb_2ea_0v_splitfaces, 0, + refprism_1fa_1fb_2ea_0v_newelstypes, + refprism_1fa_1fb_2ea_0v_newels + }; + + +// HP_PRISM_1FA_1FB_3E_0V + int refprism_1fa_1fb_3e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {4,5,40}, + {1,2,7}, + { 3, 2, 10}, + { 3, 1, 11}, + { 6, 5, 43}, + { 6, 4, 44}, + {0,0,0}, + + }; + int refprism_1fa_1fb_3e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {1,2,4,19}, + {3,2,6,22}, + {3,1,6,23}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_1fb_3e_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_HEX, + HP_PRISM_SINGEDGE, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V , + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_NONE + }; + int refprism_1fa_1fb_3e_0v_newels[][8] = + { + {40,41,20,19,45,42,21,24}, + {24, 21, 22, 23, 45, 42, 43, 44}, + {18, 23, 22, 6, 44, 43}, + {12, 9, 10, 11, 24, 21, 22, 23}, + {3, 11, 10, 18, 23, 22}, + {7,8,9,12,19,20,21,24}, + {5,41,42,17,20,21}, + {8,2,9,20,17,21}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_1fb_3e_0v = + { + HP_PRISM, + refprism_1fa_1fb_3e_0v_splitedges, + + refprism_1fa_1fb_3e_0v_splitfaces, 0, + refprism_1fa_1fb_3e_0v_newelstypes, + refprism_1fa_1fb_3e_0v_newels + }; + + + + + + + + +// HP_PRISM_2FA_0E_0V singular trig faces + int refprism_2fa_0e_0v_splitedges[][3] = + { + {1,4,16}, + {2,5,17}, + {3,6,18}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_NONE + }; + int refprism_2fa_0e_0v_newels[][8] = + { + {16,17,18,28,29,30}, + {1,2,3,16,17,18}, + {4,6,5,28,30,29}, + }; + +HPRef_Struct refprism_2fa_0e_0v = + + { + HP_PRISM, + refprism_2fa_0e_0v_splitedges, + 0, 0, + refprism_2fa_0e_0v_newelstypes, + refprism_2fa_0e_0v_newels + }; + + + + + +// HP_PRISM_1FA_2FB ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_0e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_0e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_0e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_NONE, + }; + int refprism_1fa_2fb_0e_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 5, 17, 19, 46, 42, 21, 25 }, + { 24, 18, 6, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 3, 12, 13, 10, 18, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 } + + }; + HPRef_Struct refprism_1fa_2fb_0e_0v = + { + HP_PRISM, + refprism_1fa_2fb_0e_0v_splitedges, + refprism_1fa_2fb_0e_0v_splitfaces, + refprism_1fa_2fb_0e_0v_splitelement, + refprism_1fa_2fb_0e_0v_newelstypes, + refprism_1fa_2fb_0e_0v_newels + }; + +// HP_PRISM_1FA_2FB_1EC ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_1ec_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_1ec_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_1ec_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_NONE, + }; + int refprism_1fa_2fb_1ec_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 5, 17, 19, 46, 42, 21, 25 }, + { 24, 23, 44, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 18, 23, 22, 6, 44, 43}, + + + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22}, + + }; + HPRef_Struct refprism_1fa_2fb_1ec_0v = + { + HP_PRISM, + refprism_1fa_2fb_1ec_0v_splitedges, + refprism_1fa_2fb_1ec_0v_splitfaces, + refprism_1fa_2fb_1ec_0v_splitelement, + refprism_1fa_2fb_1ec_0v_newelstypes, + refprism_1fa_2fb_1ec_0v_newels + }; + + +// HP_PRISM_1FA_2FB_3E ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_3e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE, + }; + int refprism_1fa_2fb_3e_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 41, 20, 19, 46, 42, 21, 25 }, + { 24, 23, 44, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 18, 23, 22, 6, 44, 43}, + { 5, 41, 42, 17, 20, 21}, + + + { 13, 9, 10, 25, 21, 22 }, + { 7, 8, 9, 13, 19, 20, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22}, + { 8, 2, 9, 20, 17, 21}, + + }; + HPRef_Struct refprism_1fa_2fb_3e_0v = + { + HP_PRISM, + refprism_1fa_2fb_3e_0v_splitedges, + refprism_1fa_2fb_3e_0v_splitfaces, + refprism_1fa_2fb_3e_0v_splitelement, + refprism_1fa_2fb_3e_0v_newelstypes, + refprism_1fa_2fb_3e_0v_newels + }; + + + + + + + + + +// HP_PRISM_1FA_2FB_1eb ... quad face 1-2-4-5 and quad face 1-4-6-3 +int refprism_1fa_2fb_1eb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_1fa_2fb_1eb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {1,3,4,24}, + {4,5,6,46}, + { 0, 0, 0, 0 } + }; +int refprism_1fa_2fb_1eb_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {0,0,0,0,0} + }; + + +HPREF_ELEMENT_TYPE refprism_1fa_2fb_1eb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE, + }; + + int refprism_1fa_2fb_1eb_0v_newels[][8] = + { + { 25, 21, 22, 46, 42, 43 }, + { 40, 41, 20, 19, 46, 42, 21, 25 }, + { 24, 18, 6, 45, 25, 22, 43, 46}, + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 5, 41, 42, 17, 20, 21 }, + + + { 13, 9, 10, 25, 21, 22 }, + { 7, 8, 9, 13, 19, 20, 21, 25 }, + { 3, 12, 13, 10, 18, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 8, 2, 9, 20, 17, 21}, + + }; + HPRef_Struct refprism_1fa_2fb_1eb_0v = + { + HP_PRISM, + refprism_1fa_2fb_1eb_0v_splitedges, + refprism_1fa_2fb_1eb_0v_splitfaces, + refprism_1fa_2fb_1eb_0v_splitelement, + refprism_1fa_2fb_1eb_0v_newelstypes, + refprism_1fa_2fb_1eb_0v_newels + }; + + + + + + +// HP_PRISM_2FA_2FB +int refprism_2fa_2fb_0e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 4, 6, 45}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 0, 0, 0 } + }; +int refprism_2fa_2fb_0e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {1,3,4,24}, + {4,5,6,46}, + {4,1,5,31}, + {5,6,2,33}, + {6,5,3,34}, + {4,1,6,36}, + { 0, 0, 0, 0 } + }; +int refprism_2fa_2fb_0e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {4,1,6,5,37}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_2fb_0e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_NONE, + }; + int refprism_2fa_2fb_0e_0v_newels[][8] = + { + { 25, 21, 22, 37, 33, 34}, + { 31, 29, 17, 19, 37, 33, 21, 25}, + { 36, 24, 18, 30, 37, 25, 22, 34}, + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25}, + + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 3, 12, 13, 10, 18, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + + { 46, 43, 42 ,37, 34, 33}, + { 40, 5, 29, 31, 46, 42, 33, 37 }, + { 6, 45, 36, 30, 43, 46, 37, 34 }, + { 40, 4, 46, 31, 28, 37 }, + { 4, 45, 46, 28, 36, 37}, + + }; + HPRef_Struct refprism_2fa_2fb_0e_0v = + { + HP_PRISM, + refprism_2fa_2fb_0e_0v_splitedges, + refprism_2fa_2fb_0e_0v_splitfaces, + refprism_2fa_2fb_0e_0v_splitelement, + refprism_2fa_2fb_0e_0v_newelstypes, + refprism_2fa_2fb_0e_0v_newels + }; + + +// HP_PRISM_2FA_2FB_1EC +int refprism_2fa_2fb_1ec_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_2fa_2fb_1ec_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {4,1,5,31}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + { 0, 0, 0, 0 } + }; +int refprism_2fa_2fb_1ec_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {4,1,6,5,37}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_2fb_1ec_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE, + }; + int refprism_2fa_2fb_1ec_0v_newels[][8] = + { + { 25, 21, 22, 37, 33, 34}, + { 31, 29, 17, 19, 37, 33, 21, 25}, + { 36, 24, 23, 35, 37, 25, 22, 34}, + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25}, + { 18, 23, 22, 30, 35, 34}, + + { 13, 9, 10, 25, 21, 22 }, + { 7, 2, 9, 13, 19, 17, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22 }, + + { 46, 43, 42 ,37, 34, 33}, + { 40, 5, 29, 31, 46, 42, 33, 37 }, + { 44, 45, 36, 35, 43, 46, 37, 34 }, + { 40, 4, 46, 31, 28, 37 }, + { 4, 45, 46, 28, 36, 37}, + { 44, 6, 43, 35, 30, 34}, + + }; + HPRef_Struct refprism_2fa_2fb_1ec_0v = + { + HP_PRISM, + refprism_2fa_2fb_1ec_0v_splitedges, + refprism_2fa_2fb_1ec_0v_splitfaces, + refprism_2fa_2fb_1ec_0v_splitelement, + refprism_2fa_2fb_1ec_0v_newelstypes, + refprism_2fa_2fb_1ec_0v_newels + }; + + + +// HP_PRISM_2FA_2FB_3E +int refprism_2fa_2fb_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0 } + }; +int refprism_2fa_2fb_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + { 0, 0, 0, 0 } + }; +int refprism_2fa_2fb_3e_0v_splitelement[][5] = + { + {1,2,3,4,25}, + {4,1,6,5,37}, + {0,0,0,0,0} + }; + +HPREF_ELEMENT_TYPE refprism_2fa_2fb_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + + HP_NONE, + }; + int refprism_2fa_2fb_3e_0v_newels[][8] = + { + { 25, 21, 22, 37, 33, 34}, + { 31, 32, 20, 19, 37, 33, 21, 25}, + { 36, 24, 23, 35, 37, 25, 22, 34}, + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25}, + { 18, 23, 22, 30, 35, 34}, + { 29, 32, 33, 17, 20, 21}, + + { 13, 9, 10, 25, 21, 22 }, + { 7, 8, 9, 13, 19, 20, 21, 25 }, + { 11, 12, 13, 10, 23, 24, 25, 22 }, + { 1, 7, 13, 16, 19, 25 }, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 10, 18, 23, 22 }, + { 8, 2, 9, 20, 17, 21 }, + + { 46, 43, 42 ,37, 34, 33}, + { 40, 41, 32, 31, 46, 42, 33, 37 }, + { 44, 45, 36, 35, 43, 46, 37, 34 }, + { 40, 4, 46, 31, 28, 37 }, + { 4, 45, 46, 28, 36, 37}, + { 44, 6, 43, 35, 30, 34}, + { 5, 41, 42, 29, 32, 33}, + + }; + HPRef_Struct refprism_2fa_2fb_3e_0v = + { + HP_PRISM, + refprism_2fa_2fb_3e_0v_splitedges, + refprism_2fa_2fb_3e_0v_splitfaces, + refprism_2fa_2fb_3e_0v_splitelement, + refprism_2fa_2fb_3e_0v_newelstypes, + refprism_2fa_2fb_3e_0v_newels + }; + + + + +// HP_PRISM_1FA_2E_0V + int refprism_1fa_2e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {5,4,41}, + {2,1,8}, + {4,5,40}, + {1,2,7}, + {0,0,0}, + + }; + int refprism_1fa_2e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {2,1,5,20}, + {1,2,4,19}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_2e_0v_newelstypes[] = + { + HP_HEX, + HP_PRISM, + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_SINGEDGE, + HP_PRISM_1FA_1E_0V, + HP_PRISM_SINGEDGE, + HP_PRISM_1FA_1E_0V, + HP_NONE + }; + int refprism_1fa_2e_0v_newels[][8] = + { + {40,41,20,19,45,42,21,24}, + {24,21,18,45,42,6}, + {12,9,3,24,21,18}, + {9, 12, 7, 8, 21, 24, 19, 20}, + { 17, 21, 20, 5, 42, 41}, + {2, 9, 8, 17, 21, 20}, + {16,19,24,4,40,45}, + {1,7,12,16,19,24} + }; + HPRef_Struct refprism_1fa_2e_0v = + { + HP_PRISM, + refprism_1fa_2e_0v_splitedges, + + refprism_1fa_2e_0v_splitfaces, 0, + refprism_1fa_2e_0v_newelstypes, + refprism_1fa_2e_0v_newels + }; + +// HP_PRISM_2FA_2E_0V + int refprism_2fa_2e_0v_splitedges[][3] = + { + {2,3,9}, + {1,3,12}, + {1,4,16}, + {2,5,17}, + {3,6,18}, + {5,6,42}, + {4,6,45}, + {4,1,28}, + {5,2,29}, + {6,3,30}, + {4,5,40}, + {1,2,7}, + { 5, 4, 41}, + { 2, 1, 8}, + {0,0,0}, + }; + int refprism_2fa_2e_0v_splitfaces[][4] = + { + {2,3,5,21}, + {1,3,4,24}, + {1,2,4,19}, + {4,1,6,36}, + {4,1,5,31}, + {5,6,2,33}, + {5,4,2,32}, + {2,1,5,20}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_2e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_NONE, + + }; + int refprism_2fa_2e_0v_newels[][8] = + { + { 24, 21, 18, 36, 33, 30}, + { 19, 20, 21, 24, 31, 32, 33, 36}, + { 16, 19, 24, 28, 31, 36}, + { 17, 21, 20, 29, 33, 32}, + + { 12, 9, 3, 24, 21, 18}, + { 7, 8, 9, 12, 19, 20, 21, 24}, + { 1, 7, 12, 16, 19, 24}, + { 2, 9, 8, 17, 21, 20}, + + { 45, 6, 42, 36, 30, 33}, + { 40, 45, 42, 41, 31, 36, 33, 32}, + { 4, 45, 40, 28, 36, 31 }, + { 5, 41, 42, 29, 32, 33 }, + }; + HPRef_Struct refprism_2fa_2e_0v = + { + HP_PRISM, + refprism_2fa_2e_0v_splitedges, + refprism_2fa_2e_0v_splitfaces, 0, + refprism_2fa_2e_0v_newelstypes, + refprism_2fa_2e_0v_newels + }; + + + +// HP_PRISM_3E_0V + int refprism_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; + int refprism_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_NONE + }; + int refprism_3e_0v_newels[][8] = + { + { 13, 14, 15, 46, 47, 48}, + { 7, 8, 14, 13, 40, 41, 47, 46}, + { 15, 14, 9, 10, 48, 47, 42, 43}, + { 12, 13, 15, 11, 45, 46, 48, 44}, + { 14, 8, 9, 47, 41, 42 }, + { 11, 15, 10, 44, 48, 43 }, + { 7, 13, 12, 40, 46, 45}, + { 1, 7, 12, 4, 40, 45}, + { 2, 9, 8, 5, 42, 41 }, + { 3, 11, 10, 6, 44, 43 } + }; + HPRef_Struct refprism_3e_0v = + { + HP_PRISM, + refprism_3e_0v_splitedges, + refprism_3e_0v_splitfaces, 0, + refprism_3e_0v_newelstypes, + refprism_3e_0v_newels + }; + + +// HP_PRISM_3E_0V +int refprism_1fa_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + + { 0, 0, 0}, + }; +int refprism_1fa_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_1fa_3e_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_NONE + }; +int refprism_1fa_3e_0v_newels[][8] = + { + { 25, 26, 27, 46, 47, 48}, + { 19, 20, 26, 25, 40, 41, 47, 46}, + { 27, 26, 21, 22, 48, 47, 42, 43}, + { 23, 24, 25, 27, 44, 45, 46, 48}, + { 19, 25, 24, 40, 46, 45}, + { 26, 20, 21, 47, 41, 42}, + { 23, 27, 22, 44, 48, 43}, + { 16, 19, 24, 4, 40, 45}, + { 17, 21, 20, 5, 42, 41}, + { 18, 23, 22, 6, 44, 43}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 15, 14, 9, 10, 27, 26, 21, 22}, + { 12, 13, 15, 11, 24, 25, 27, 23}, + { 14, 8, 9, 26, 20, 21}, + { 11, 15, 10, 23, 27, 22}, + { 7, 13 , 12, 19, 25, 24}, + { 2, 9, 8, 17, 21, 20}, + { 3, 11, 10, 18, 23, 22}, + { 1, 7, 12, 16, 19, 24}, + }; + HPRef_Struct refprism_1fa_3e_0v = + { + HP_PRISM, + refprism_1fa_3e_0v_splitedges, + refprism_1fa_3e_0v_splitfaces, + refprism_1fa_3e_0v_splitelements, + refprism_1fa_3e_0v_newelstypes, + refprism_1fa_3e_0v_newels + }; + + + +// HP_PRISM_2FA_3E_0V +int refprism_2fa_3e_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_2fa_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_2fa_3e_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {4,1,6,5,37}, + {5,2,4,6,38}, + {6,4,5,3,39}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_NONE + }; + + int refprism_2fa_3e_0v_newels[][8] = + { + { 25, 26, 27, 37, 38, 39}, + { 19, 20, 26, 25, 31, 32, 38, 37}, + { 27, 26, 21, 22, 39, 38, 33, 34}, + { 23, 24, 25, 27, 35, 36, 37, 39}, + { 19, 25, 24, 31, 37, 36}, + { 26, 20, 21, 38, 32, 33}, + { 23, 27, 22, 35, 39, 34}, + { 16, 19, 24, 28, 31, 36}, + { 17, 21, 20, 29, 33, 32}, + { 18, 23, 22, 30, 35, 34}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 15, 14, 9, 10, 27, 26, 21, 22}, + { 12, 13, 15, 11, 24, 25, 27, 23}, + { 14, 8, 9, 26, 20, 21}, + { 11, 15, 10, 23, 27, 22}, + { 7, 13 , 12, 19, 25, 24}, + { 2, 9, 8, 17, 21, 20}, + { 3, 11, 10, 18, 23, 22}, + { 1, 7, 12, 16, 19, 24}, + + { 48, 47, 46, 39, 38, 37 }, + { 48, 43, 42, 47, 39, 34, 33, 38}, + { 45, 44, 48, 46, 36, 35, 39, 37}, + { 46, 47, 41, 40, 37, 38, 32, 31}, + { 47, 42, 41, 38, 33, 32}, + { 45, 46, 40, 36, 37, 31}, + { 44, 43, 48, 35, 34, 39}, + { 6, 43, 44, 30, 34, 35}, + { 5, 41, 42, 29, 32, 33}, + { 4, 45, 40, 28, 36, 31}, + }; + +HPRef_Struct refprism_2fa_3e_0v = + { + HP_PRISM, + refprism_2fa_3e_0v_splitedges, + refprism_2fa_3e_0v_splitfaces, + refprism_2fa_3e_0v_splitelements, + refprism_2fa_3e_0v_newelstypes, + refprism_2fa_3e_0v_newels + }; + + + +// HP_PRISM_3FB_0V + int refprism_3fb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; + int refprism_3fb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_3fb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_NONE + }; + int refprism_3fb_0v_newels[][8] = + { + { 13, 14, 15, 46, 47, 48}, + { 8, 7, 40, 41, 14,13, 46, 47 }, + { 10, 9, 42, 43, 15, 14, 47, 48 }, + { 44, 45, 12, 11, 48, 46, 13, 15}, + { 1, 7, 13, 4, 40, 46 }, + { 4, 45, 46, 1, 12, 13}, + { 2, 9, 14, 5, 42, 47 }, + { 5, 41, 47, 2, 8, 14 }, + { 3, 11, 15, 6, 44, 48}, + { 6, 43, 48, 3, 10, 15}, + + }; + HPRef_Struct refprism_3fb_0v = + { + HP_PRISM, + refprism_3fb_0v_splitedges, + refprism_3fb_0v_splitfaces, 0, + refprism_3fb_0v_newelstypes, + refprism_3fb_0v_newels + }; + + +// HP_PRISM_3FB_0V +int refprism_1fa_3fb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_1fa_3fb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_1fa_3fb_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_1fa_3fb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE + }; + int refprism_1fa_3fb_0v_newels[][8] = + { + { 25, 26, 27, 46, 47, 48}, + { 19, 40, 41, 20, 25, 46, 47, 26}, + { 22, 21, 42, 43, 27, 26, 47, 48}, + { 24, 23, 44, 45, 25, 27, 48, 46}, + + { 16, 19, 25, 4, 40, 46 }, + { 4, 45, 46, 16, 24, 25 }, + { 17, 21, 26, 5, 42, 47 }, + { 5, 41, 47, 17, 20, 26}, + { 18, 23, 27, 6, 44, 48}, + { 6, 43, 48, 18, 22, 27}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 9, 10, 15, 14, 21, 22, 27, 26}, + { 11, 12, 13, 15, 23, 24, 25, 27}, + + { 2, 9, 14, 17, 21, 26}, + { 8, 2, 14, 20, 17, 26}, + { 1, 7, 13, 16, 19, 25}, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 15, 18, 23, 27 }, + { 10, 3, 15, 22, 18, 27}, + + }; + HPRef_Struct refprism_1fa_3fb_0v = + { + HP_PRISM, + refprism_1fa_3fb_0v_splitedges, + refprism_1fa_3fb_0v_splitfaces, + refprism_1fa_3fb_0v_splitelements, + refprism_1fa_3fb_0v_newelstypes, + refprism_1fa_3fb_0v_newels + }; + + + +// HP_PRISM_2FA_3E_0V +int refprism_2fa_3fb_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_2fa_3fb_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_2fa_3fb_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {4,1,6,5,37}, + {5,2,4,6,38}, + {6,4,5,3,39}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_3fb_0v_newelstypes[] = + { + + HP_PRISM, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_HEX_1FA_1FB_0E_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + HP_PRISM_1FA_1FB_1EA_0V, + HP_PRISM_1FA_1FB_1EB_0V, + + HP_NONE + }; + int refprism_2fa_3fb_0v_newels[][8] = + { + { 25, 26, 27, 37, 38, 39}, + { 19, 31, 32, 20, 25, 37, 38, 26}, + { 33, 34, 22, 21, 38, 39, 27, 26}, + { 35, 36, 24, 23, 39, 37, 25, 27}, + + { 16, 19, 25, 28, 31, 37}, + { 28, 36, 37, 16, 24, 25 }, + { 17, 21, 26, 29, 33, 38 }, + { 29, 32, 38, 17, 20, 26}, + { 18, 23, 27, 30, 35, 39}, + { 30, 34, 39, 18, 22, 27}, + + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 9, 10, 15, 14, 21, 22, 27, 26}, + { 11, 12, 13, 15, 23, 24, 25, 27}, + + { 2, 9, 14, 17, 21, 26}, + { 8, 2, 14, 20, 17, 26}, + { 1, 7, 13, 16, 19, 25}, + { 12, 1, 13, 24, 16, 25 }, + { 3, 11, 15, 18, 23, 27 }, + { 10, 3, 15, 22, 18, 27}, + + + { 48, 47, 46, 39, 38, 37 }, + { 44, 45, 36, 35, 48, 46, 37, 39}, + { 40, 41, 32, 31, 46, 47, 38, 37}, + { 42, 43, 34, 33, 47, 48, 39, 38}, + + { 6, 43, 48, 30, 34, 39}, + { 44, 6, 48, 35, 30, 39}, + { 4, 45, 46, 28, 36, 37}, + { 40, 4, 46, 31, 28, 37}, + { 5, 41, 47, 29, 32, 38}, + { 42, 5, 47, 33, 29, 38}, + }; + +HPRef_Struct refprism_2fa_3fb_0v = + { + HP_PRISM, + refprism_2fa_3fb_0v_splitedges, + refprism_2fa_3fb_0v_splitfaces, + refprism_2fa_3fb_0v_splitelements, + refprism_2fa_3fb_0v_newelstypes, + refprism_2fa_3fb_0v_newels + }; + + +/* + + +// HP_PRISM_3E_4EH +int refprism_3e_4eh_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + + }; +int refprism_3e_4eh_splitfaces[][4] = + { + {3,1,2,15}, + {6,4,5,48}, + {0,0,0,0}, + }; + +HPREF_ELEMENT_TYPE refprism_2fa_3fb_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX_2EH_0V, + HP_HEX_2EH_0V, + HP_TET_2E, + HP_TET_2E, + HP_PRISM_1E_2EH_0V, + HP_PRISM_1E_2EH_0V, + HP_NONE + }; + int refprism_2fa_3fb_0v_newels[][8] = + { + {15, 7, 8, 48, 40, 41 }, + + }; + +HPRef_Struct refprism_2fa_3fb_0v = + { + HP_PRISM, + refprism_2fa_3fb_0v_splitedges, + refprism_2fa_3fb_0v_splitfaces, + refprism_2fa_3fb_0v_splitelements, + refprism_2fa_3fb_0v_newelstypes, + refprism_2fa_3fb_0v_newels + }; +*/ + +/* +// HP_PRISM_2FA_3E_0V +int refprism_3e_4_0v_splitedges[][3] = + { + { 1, 2, 7}, + { 2, 1, 8}, + { 2, 3, 9}, + { 3, 2, 10}, + { 3, 1, 11}, + { 1, 3, 12}, + { 1, 4, 16}, + { 2, 5, 17}, + { 3, 6, 18}, + { 4, 1, 28}, + { 5, 2, 29}, + { 6, 3, 30}, + { 4, 5, 40}, + { 5, 4, 41}, + { 5, 6, 42}, + { 6, 5, 43}, + { 6, 4, 44}, + { 4, 6, 45}, + { 0, 0, 0}, + }; +int refprism_2fa_3e_0v_splitfaces[][4] = + { + {1,2,3,13}, + {2,3,1,14}, + {3,1,2,15}, + {1,2,4,19}, + {2,1,5,20}, + {2,3,5,21}, + {3,2,6,22}, + {3,1,6,23}, + {1,3,4,24}, + {4,1,5,31}, + {5,4,2,32}, + {5,6,2,33}, + {6,5,3,34}, + {6,4,3,35}, + {4,1,6,36}, + {4,5,6,46}, + {5,4,6,47}, + {6,4,5,48}, + {0,0,0,0}, + }; + +int refprism_2fa_3e_0v_splitelements[][5] = + { + {1,2,3,4,25}, + {2,1,3,5,26}, + {3,1,2,6,27}, + {4,1,6,5,37}, + {5,2,4,6,38}, + {6,4,5,3,39}, + {0,0,0,0,0}, + }; + + HPREF_ELEMENT_TYPE refprism_2fa_3e_0v_newelstypes[] = + { + HP_PRISM, + HP_HEX, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_PRISM_1FA_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + HP_PRISM_1FA_1E_0V, + + HP_NONE + }; + + int refprism_2fa_3e_0v_newels[][8] = + { + { 25, 26, 27, 37, 38, 39}, + { 19, 20, 26, 25, 31, 32, 38, 37}, + { 27, 26, 21, 22, 39, 38, 33, 34}, + { 23, 24, 25, 27, 35, 36, 37, 39}, + { 19, 25, 24, 31, 37, 36}, + { 26, 20, 21, 38, 32, 33}, + { 23, 27, 22, 35, 39, 34}, + { 16, 19, 24, 28, 31, 36}, + { 17, 21, 20, 29, 33, 32}, + { 18, 23, 22, 30, 35, 34}, + + { 13, 14, 15, 25, 26, 27}, + { 7, 8, 14, 13, 19, 20, 26, 25}, + { 15, 14, 9, 10, 27, 26, 21, 22}, + { 12, 13, 15, 11, 24, 25, 27, 23}, + { 14, 8, 9, 26, 20, 21}, + { 11, 15, 10, 23, 27, 22}, + { 7, 13 , 12, 19, 25, 24}, + { 2, 9, 8, 17, 21, 20}, + { 3, 11, 10, 18, 23, 22}, + { 1, 7, 12, 16, 19, 24}, + + { 48, 47, 46, 39, 38, 37 }, + { 48, 43, 42, 47, 39, 34, 33, 38}, + { 45, 44, 48, 46, 36, 35, 39, 37}, + { 46, 47, 41, 40, 37, 38, 32, 31}, + { 47, 42, 41, 38, 33, 32}, + { 45, 46, 40, 36, 37, 31}, + { 44, 43, 48, 35, 34, 39}, + { 6, 43, 44, 30, 34, 35}, + { 5, 41, 42, 29, 32, 33}, + { 4, 45, 40, 28, 36, 31}, + }; + +HPRef_Struct refprism_2fa_3e_0v = + { + HP_PRISM, + refprism_2fa_3e_0v_splitedges, + refprism_2fa_3e_0v_splitfaces, + refprism_2fa_3e_0v_splitelements, + refprism_2fa_3e_0v_newelstypes, + refprism_2fa_3e_0v_newels + }; + +*/ +/* + +// HP_PRISM_1FB_1EB_0V ... quad face 1-2-4-5 + int refprism_1fb_1eb_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 3, 8 }, + { 4, 6, 9 }, + { 5, 6, 10 }, + { 2, 1, 11 }, + { 5, 4, 12 }, + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refprism_1fb_1eb_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EB_0V, + HP_PRISM, + HP_NONE, + }; + int refprism_1fb_1eb_0v_newels[][8] = + { + { 1, 4, 12, 11, 7, 9, 10, 8 }, + { 11, 2, 8, 12, 5, 10 }, + { 7, 8, 3, 9, 10, 6 } + }; + HPRef_Struct refprism_1fb_1eb_0v = + { + HP_PRISM, + refprism_1fb_1eb_0v_splitedges, + 0, 0, + refprism_1fb_1eb_0v_newelstypes, + refprism_1fb_1eb_0v_newels + }; + + + + + + + + + + + // HP_PRISM_2F_0E_0V + int refprism_2f_0e_0v_splitedges[][3] = + { + { 1, 3, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 3, 1, 10 }, + + { 4, 6, 12 }, + { 5, 4, 13 }, + { 5, 6, 14 }, + { 6, 4, 15 }, + + { 0, 0, 0 } + }; + + int refprism_2f_0e_0v_splitfaces[][4] = + { + { 2, 1, 3, 11 }, + { 5, 4, 6, 16 }, + { 0, 0, 0, 0 }, + }; + + HPREF_ELEMENT_TYPE refprism_2f_0e_0v_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_HEX_1F_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM, + HP_NONE, + }; + int refprism_2f_0e_0v_newels[][8] = + { + //{ 1, 8, 11, 7, 4, 13, 16, 12 }, + // { 9, 3, 10, 11, 14, 6, 15, 16 }, + { 1, 4, 13, 8, 7, 12, 16, 11 }, + { 9, 14, 6, 3, 11, 16, 15, 10 }, + { 2, 9, 11, 5, 14, 16 }, + // { 8, 2, 11, 13, 5, 16 }, + { 5, 13, 16, 2, 8, 11 }, + { 7, 11, 10, 12, 16, 15 } + }; + HPRef_Struct refprism_2f_0e_0v = + { + HP_PRISM, + refprism_2f_0e_0v_splitedges, + refprism_2f_0e_0v_splitfaces, + 0, + refprism_2f_0e_0v_newelstypes, + refprism_2f_0e_0v_newels + }; + +*/ diff --git a/libsrc/meshing/hpref_pyramid.hpp b/libsrc/meshing/hpref_pyramid.hpp new file mode 100644 index 00000000..521daf50 --- /dev/null +++ b/libsrc/meshing/hpref_pyramid.hpp @@ -0,0 +1,118 @@ + + // HP_PYRAMID + int refpyramid_splitedges[][3] = + { + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refpyramid_newelstypes[] = + { + HP_PYRAMID, + HP_NONE, + }; + int refpyramid_newels[][8] = + { + { 1, 2, 3, 4, 5 } + }; + HPRef_Struct refpyramid = + { + HP_PYRAMID, + refpyramid_splitedges, + 0, 0, + refpyramid_newelstypes, + refpyramid_newels + }; + + +// singular point 1 + // HP_PYRAMID_0E_1V + int refpyramid_0e_1v_splitedges[][3] = + { + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refpyramid_0e_1v_newelstypes[] = + { + HP_TET_0E_1V, + HP_TET, + HP_NONE, + }; + int refpyramid_0e_1v_newels[][8] = + { + { 1, 2, 4, 5 }, + { 2, 3, 4, 5 }, + }; + HPRef_Struct refpyramid_0e_1v = + { + HP_PYRAMID, + refpyramid_0e_1v_splitedges, + 0, 0, + refpyramid_0e_1v_newelstypes, + refpyramid_0e_1v_newels + }; + + +// singular edges 1-2 1-4 singular point 1 + // HP_PYRAMID_EDGES + int refpyramid_edges_splitedges[][3] = + { + { 0, 0, 0 } + }; + HPREF_ELEMENT_TYPE refpyramid_edges_newelstypes[] = + { + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_NONE, + }; + int refpyramid_edges_newels[][8] = + { + { 1, 2, 3, 5 }, + { 1, 4, 5, 3 }, + }; + HPRef_Struct refpyramid_edges = + { + HP_PYRAMID, + refpyramid_edges_splitedges, + 0, 0, + refpyramid_edges_newelstypes, + refpyramid_edges_newels + }; + + + +// singular face 1-2-5 singular point 5 + // HP_PYRAMID_1FB_0E_1VA + int refpyramid_1fb_0e_1va_splitedges[][3] = + { + { 1, 4, 6 }, + { 2, 3, 7 }, + { 5, 1, 8 }, + { 5, 2, 9 }, + { 5, 3, 10 }, + { 5, 4, 11 }, + { 0, 0, 0 }, + }; + + HPREF_ELEMENT_TYPE refpyramid_1fb_0e_1va_newelstypes[] = + { + HP_HEX_1F_0E_0V, + HP_PYRAMID_1FB_0E_1VA, + HP_PRISM, + HP_NONE, + }; + int refpyramid_1fb_0e_1va_newels[][8] = + { + { 1, 8, 9, 2, 6, 11, 10, 7 }, + { 8, 9, 10, 11, 5 }, + { 3, 7, 10, 4, 6, 11 } + }; + HPRef_Struct refpyramid_1fb_0e_1va = + { + HP_PYRAMID, + refpyramid_1fb_0e_1va_splitedges, + 0, 0, + refpyramid_1fb_0e_1va_newelstypes, + refpyramid_1fb_0e_1va_newels + }; + + + + diff --git a/libsrc/meshing/hpref_quad.hpp b/libsrc/meshing/hpref_quad.hpp new file mode 100644 index 00000000..2a23156d --- /dev/null +++ b/libsrc/meshing/hpref_quad.hpp @@ -0,0 +1,2082 @@ +// HP_QUAD +int refquad_splitedges[][3] = +{ + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_newelstypes[] = +{ + HP_QUAD, + HP_NONE, +}; +int refquad_newels[][8] = +{ + { 1, 2, 3, 4 }, +}; +HPRef_Struct refquad = +{ + HP_QUAD, + refquad_splitedges, + 0, 0, + refquad_newelstypes, + refquad_newels +}; + + + + + + + +// HP_QUAD_SINGCORNER +int refquad_singcorner_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_singcorner_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_QUAD, + HP_TRIG, + HP_NONE, +}; +int refquad_singcorner_newels[][8] = +{ + { 1, 5, 6 }, + { 2, 4, 6, 5 }, + { 2, 3, 4 }, +}; +HPRef_Struct refquad_singcorner = +{ + HP_QUAD, + refquad_singcorner_splitedges, + 0, 0, + refquad_singcorner_newelstypes, + refquad_singcorner_newels +}; + + + + + +// HP_DUMMY_QUAD_SINGCORNER +int refdummyquad_singcorner_splitedges[][3] = +{ + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refdummyquad_singcorner_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_TRIG, + HP_NONE, +}; +int refdummyquad_singcorner_newels[][8] = +{ + { 1, 2, 4 }, + { 4, 2, 3 }, +}; +HPRef_Struct refdummyquad_singcorner = +{ + HP_QUAD, + refdummyquad_singcorner_splitedges, + 0, 0, + refdummyquad_singcorner_newelstypes, + refdummyquad_singcorner_newels +}; + + + + + + + +// HP_QUAD_SINGEDGE +int refquad_singedge_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_singedge_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_singedge_newels[][8] = +{ + { 1, 2, 6, 5 }, + { 5, 6, 3, 4 }, +}; +HPRef_Struct refquad_singedge = +{ + HP_QUAD, + refquad_singedge_splitedges, + 0, 0, + refquad_singedge_newelstypes, + refquad_singedge_newels +}; + + + + + + +// HP_QUAD_0E_2VA +int refquad_0e_2va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_0e_2va_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD, + HP_QUAD, + HP_NONE, +}; +int refquad_0e_2va_newels[][8] = +{ + { 1, 5, 6 }, + { 2, 8, 7 }, + { 5, 7, 8, 6 }, + { 6, 8, 3, 4 }, +}; +HPRef_Struct refquad_0e_2va = +{ + HP_QUAD, + refquad_0e_2va_splitedges, + 0, 0, + refquad_0e_2va_newelstypes, + refquad_0e_2va_newels +}; + + + +// HP_QUAD_0E_2VB +int refquad_0e_2vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 3, 4, 7 }, + { 3, 2, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_0e_2vb_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD, + HP_QUAD, + HP_NONE, +}; +int refquad_0e_2vb_newels[][8] = +{ + { 1, 5, 6 }, + { 3, 7, 8 }, + { 5, 2, 4, 6 }, + { 2, 8, 7, 4 }, +}; +HPRef_Struct refquad_0e_2vb = +{ + HP_QUAD, + refquad_0e_2vb_splitedges, + 0, 0, + refquad_0e_2vb_newelstypes, + refquad_0e_2vb_newels +}; + + + + +// HP_QUAD_0E_3V +int refquad_0e_3v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 3, 2, 9 }, + { 3, 4, 10 }, + { 0, 0, 0 } +}; + +int refquad_0e_3v_splitfaces[][4] = +{ + { 2, 3, 1, 14 }, + { 0, 0, 0, 0 }, +}; + +HPREF_ELEMENT_TYPE refquad_0e_3v_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_DUMMY_QUAD_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD, + HP_QUAD, + HP_QUAD, + HP_NONE, +}; +int refquad_0e_3v_newels[][8] = +{ + { 1, 5, 6 }, + { 2, 8, 14, 7 }, + { 3, 10, 9 }, + { 5, 7, 14, 6 }, + { 8, 9, 10, 14 }, + { 6, 14, 10, 4 }, +}; +HPRef_Struct refquad_0e_3v = +{ + HP_QUAD, + refquad_0e_3v_splitedges, + refquad_0e_3v_splitfaces, + 0, + refquad_0e_3v_newelstypes, + refquad_0e_3v_newels +}; + + + + +// HP_QUAD_0E_4V +int refquad_0e_4v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 3, 2, 9 }, + { 3, 4, 10 }, + { 4, 1, 11 }, + { 4, 3, 12 }, + { 0, 0, 0 } +}; + +int refquad_0e_4v_splitfaces[][4] = +{ + { 1, 2, 4, 13 }, + { 2, 3, 1, 14 }, + { 3, 4, 2, 15 }, + { 4, 1, 3, 16 }, + { 0, 0, 0, 0 }, +}; + +HPREF_ELEMENT_TYPE refquad_0e_4v_newelstypes[] = +{ + HP_DUMMY_QUAD_SINGCORNER, + HP_DUMMY_QUAD_SINGCORNER, + HP_DUMMY_QUAD_SINGCORNER, + HP_DUMMY_QUAD_SINGCORNER, + + HP_QUAD, + HP_QUAD, + HP_QUAD, + HP_QUAD, + + HP_QUAD, + HP_NONE, +}; +int refquad_0e_4v_newels[][8] = +{ + { 1, 5, 13, 6 }, + { 2, 8, 14, 7 }, + { 3, 10, 15, 9 }, + { 4, 11, 16, 12 }, + { 5, 7, 14, 13 }, + { 8, 9, 15, 14 }, + { 10, 12, 16, 15 }, + { 11, 6, 13, 16 }, + { 13, 14, 15, 16 } +}; +HPRef_Struct refquad_0e_4v = +{ + HP_QUAD, + refquad_0e_4v_splitedges, + refquad_0e_4v_splitfaces, + 0, + refquad_0e_4v_newelstypes, + refquad_0e_4v_newels +}; + + + + + + + + +// HP_QUAD_1E_1VA +int refquad_1e_1va_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_1va_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGEDGECORNER1, + HP_NONE, +}; +int refquad_1e_1va_newels[][8] = +{ + { 7, 2, 6, 5 }, + { 5, 6, 3, 4 }, + { 1, 7, 5 }, +}; +HPRef_Struct refquad_1e_1va = +{ + HP_QUAD, + refquad_1e_1va_splitedges, + 0, 0, + refquad_1e_1va_newelstypes, + refquad_1e_1va_newels +}; + + + + +// HP_QUAD_1E_1VB +int refquad_1e_1vb_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 2, 1, 7 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_1vb_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int refquad_1e_1vb_newels[][8] = +{ + { 1, 7, 6, 5 }, + { 5, 6, 3, 4 }, + { 7, 2, 6 }, +}; +HPRef_Struct refquad_1e_1vb = +{ + HP_QUAD, + refquad_1e_1vb_splitedges, + 0, 0, + refquad_1e_1vb_newelstypes, + refquad_1e_1vb_newels +}; + + + +// HP_QUAD_1E_1VC +int refquad_1e_1vc_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 3, 4, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_1vc_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_1e_1vc_newels[][8] = +{ + { 1, 2, 6, 5 }, + { 5, 6, 4 }, + { 4, 6, 7, 8 }, + { 3, 8, 7 } +}; +HPRef_Struct refquad_1e_1vc = +{ + HP_QUAD, + refquad_1e_1vc_splitedges, + 0, 0, + refquad_1e_1vc_newelstypes, + refquad_1e_1vc_newels +}; + + + +// HP_QUAD_1E_1VD +int refquad_1e_1vd_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 4, 1, 7 }, + { 4, 3, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_1vd_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_1e_1vd_newels[][8] = +{ + { 1, 2, 6, 5 }, + { 5, 6, 3 }, + { 5, 3, 8, 7 }, + { 4, 7, 8 } +}; +HPRef_Struct refquad_1e_1vd = +{ + HP_QUAD, + refquad_1e_1vd_splitedges, + 0, 0, + refquad_1e_1vd_newelstypes, + refquad_1e_1vd_newels +}; + + + + + + + +// HP_QUAD_1E_2VA +int refquad_1e_2va_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 2, 1, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_2va_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int refquad_1e_2va_newels[][8] = +{ + { 7, 8, 6, 5 }, + { 5, 6, 3, 4 }, + { 1, 7, 5 }, + { 8, 2, 6 } +}; +HPRef_Struct refquad_1e_2va = +{ + HP_QUAD, + refquad_1e_2va_splitedges, + 0, 0, + refquad_1e_2va_newelstypes, + refquad_1e_2va_newels +}; + + + + +// HP_QUAD_1E_2VB +int refquad_1e_2vb_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 3, 2, 8 }, + { 3, 4, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_2vb_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_1e_2vb_newels[][8] = +{ + { 7, 2, 6, 5 }, + { 1, 7, 5 }, + { 5, 6, 4 }, + { 4, 6, 8, 9 }, + { 3, 9, 8 } +}; +HPRef_Struct refquad_1e_2vb = +{ + HP_QUAD, + refquad_1e_2vb_splitedges, + 0, 0, + refquad_1e_2vb_newelstypes, + refquad_1e_2vb_newels +}; + + + + +// HP_QUAD_1E_2VC +int refquad_1e_2vc_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 4, 1, 8 }, + { 4, 3, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_2vc_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_1e_2vc_newels[][8] = +{ + { 7, 2, 6, 5 }, + { 1, 7, 5 }, + { 5, 6, 3 }, + { 5, 3, 9, 8 }, + { 4, 8, 9 } +}; +HPRef_Struct refquad_1e_2vc = +{ + HP_QUAD, + refquad_1e_2vc_splitedges, + 0, 0, + refquad_1e_2vc_newelstypes, + refquad_1e_2vc_newels +}; + + + + +// HP_QUAD_1E_2VD +int refquad_1e_2vd_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 2, 1, 7 }, + { 3, 2, 8 }, + { 3, 4, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_2vd_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_1e_2vd_newels[][8] = +{ + { 1, 7, 6, 5 }, + { 7, 2, 6 }, + { 5, 6, 4 }, + { 4, 6, 8, 9 }, + { 3, 9, 8 } +}; +HPRef_Struct refquad_1e_2vd = +{ + HP_QUAD, + refquad_1e_2vd_splitedges, + 0, 0, + refquad_1e_2vd_newelstypes, + refquad_1e_2vd_newels +}; + + + + + +// HP_QUAD_1E_2VE +int refquad_1e_2ve_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 2, 1, 7 }, + { 4, 1, 8 }, + { 4, 3, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_2ve_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_1e_2ve_newels[][8] = +{ + { 1, 7, 6, 5 }, + { 7, 2, 6 }, + { 5, 6, 3 }, + { 5, 3, 9, 8 }, + { 4, 8, 9 } +}; +HPRef_Struct refquad_1e_2ve = +{ + HP_QUAD, + refquad_1e_2ve_splitedges, + 0, 0, + refquad_1e_2ve_newelstypes, + refquad_1e_2ve_newels +}; + + + + + + +// HP_QUAD_1E_2VF +int refquad_1e_2vf_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 4, 1, 7 }, + { 4, 3, 8 }, + { 3, 2, 9 }, + { 3, 4, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_2vf_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_1e_2vf_newels[][8] = +{ + { 1, 2, 6, 5 }, + { 5, 6, 9, 7 }, + { 7, 9, 10, 8 }, + { 4, 7, 8 }, + { 3, 10, 9 }, +}; +HPRef_Struct refquad_1e_2vf = +{ + HP_QUAD, + refquad_1e_2vf_splitedges, + 0, 0, + refquad_1e_2vf_newelstypes, + refquad_1e_2vf_newels +}; + + + + + +// HP_QUAD_1E_3VA +int refquad_1e_3va_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 2, 1, 8 }, + { 3, 2, 9 }, + { 3, 4, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_3va_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGCORNER, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG, + HP_NONE, +}; +int refquad_1e_3va_newels[][8] = +{ + { 1, 7, 5 }, + { 8, 2, 6 }, + { 3, 10, 9 }, + { 7, 8, 6, 5 }, + { 4, 6, 9, 10 }, + { 5, 6, 4 } +}; +HPRef_Struct refquad_1e_3va = +{ + HP_QUAD, + refquad_1e_3va_splitedges, + 0, 0, + refquad_1e_3va_newelstypes, + refquad_1e_3va_newels +}; + + + + + +// HP_QUAD_1E_3VB +int refquad_1e_3vb_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 2, 1, 8 }, + { 4, 1, 9 }, + { 4, 3, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_3vb_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGCORNER, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG, + HP_NONE, +}; +int refquad_1e_3vb_newels[][8] = +{ + { 1, 7, 5 }, + { 8, 2, 6 }, + { 4, 9, 10 }, + { 7, 8, 6, 5 }, + { 5, 3, 10, 9 }, + { 5, 6, 3 } +}; +HPRef_Struct refquad_1e_3vb = +{ + HP_QUAD, + refquad_1e_3vb_splitedges, + 0, 0, + refquad_1e_3vb_newelstypes, + refquad_1e_3vb_newels +}; + + + + + +// HP_QUAD_1E_3VC +int refquad_1e_3vc_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 3, 2, 8 }, + { 3, 4, 9 }, + { 4, 3, 10 }, + { 4, 1, 11 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_3vc_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_QUAD, + HP_NONE, +}; +int refquad_1e_3vc_newels[][8] = +{ + { 1, 7, 5 }, + { 3, 9, 8 }, + { 4, 11, 10 }, + { 7, 2, 6, 5 }, + { 5, 6, 8, 11 }, + { 11, 8, 9, 10 } +}; +HPRef_Struct refquad_1e_3vc = +{ + HP_QUAD, + refquad_1e_3vc_splitedges, + 0, 0, + refquad_1e_3vc_newelstypes, + refquad_1e_3vc_newels +}; + + + + +// HP_QUAD_1E_3VD +int refquad_1e_3vd_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 2, 1, 7 }, + { 3, 2, 8 }, + { 3, 4, 9 }, + { 4, 3, 10 }, + { 4, 1, 11 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_3vd_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_QUAD, + HP_NONE, +}; +int refquad_1e_3vd_newels[][8] = +{ + { 7, 2, 6 }, + { 3, 9, 8 }, + { 4, 11, 10 }, + { 1, 7, 6, 5 }, + { 5, 6, 8, 11 }, + { 11, 8, 9, 10 } +}; +HPRef_Struct refquad_1e_3vd = +{ + HP_QUAD, + refquad_1e_3vd_splitedges, + 0, 0, + refquad_1e_3vd_newelstypes, + refquad_1e_3vd_newels +}; + + + + + + +// HP_QUAD_1E_4V +int refquad_1e_4v_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 2, 1, 8 }, + { 4, 1, 9 }, + { 3, 2, 10 }, + { 4, 3, 11 }, + { 3, 4, 12 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_1e_4v_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_QUAD, + HP_NONE, +}; +int refquad_1e_4v_newels[][8] = +{ + { 1, 7, 5 }, + { 8, 2, 6 }, + { 3, 12, 10 }, + { 4, 9, 11 }, + { 7, 8, 6, 5 }, + { 5, 6, 10, 9 }, + { 9, 10, 12, 11 } +}; +HPRef_Struct refquad_1e_4v = +{ + HP_QUAD, + refquad_1e_4v_splitedges, + 0, 0, + refquad_1e_4v_newelstypes, + refquad_1e_4v_newels +}; + +//////////////////////////////////////////////////////////////////////////////// + +// HP_QUAD_2E +int refquad_2e_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 4, 3, 8 }, + { 0, 0, 0 } +}; +int refquad_2e_splitfaces[][4] = +{ + { 1, 2, 4, 9 }, + { 0, 0, 0, 0 }, +}; + + +/* + HPREF_ELEMENT_TYPE refquad_2e_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2e_newels[][8] = +{ + { 1, 5, 9 }, + { 6, 1, 9 }, + { 5, 2, 7, 9 }, + { 4, 6, 9, 8 }, + { 9, 7, 3, 8 }, +}; +*/ + +// SZ refine to 4 quads +HPREF_ELEMENT_TYPE refquad_2e_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2e_newels[][8] = +{ + { 1, 5, 9, 6 }, + { 5, 2, 7, 9 }, + { 4, 6, 9, 8 }, + { 9, 7, 3, 8 }, +}; + +HPRef_Struct refquad_2e = +{ + HP_QUAD, + refquad_2e_splitedges, + refquad_2e_splitfaces, + 0, + refquad_2e_newelstypes, + refquad_2e_newels +}; + + +// HP_QUAD_2E_1VA +int refquad_2e_1va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 4, 3, 8 }, + { 2, 1, 10 }, + { 0, 0, 0 } +}; +int refquad_2e_1va_splitfaces[][4] = +{ + { 1, 2, 4, 9 }, + { 0, 0, 0, 0 }, +}; + +/* +HPREF_ELEMENT_TYPE refquad_2e_1va_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int refquad_2e_1va_newels[][8] = +{ + { 1, 5, 9 }, + { 6, 1, 9 }, + { 5, 10, 7, 9 }, + { 4, 6, 9, 8 }, + { 9, 7, 3, 8 }, + { 10, 2, 7 }, +}; +*/ +// SZ Quad_2e refinement +HPREF_ELEMENT_TYPE refquad_2e_1va_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int refquad_2e_1va_newels[][8] = +{ + { 1, 5, 9, 6 }, + { 5, 10, 7, 9 }, + { 4, 6, 9, 8 }, + { 9, 7, 3, 8 }, + { 10, 2, 7 }, +}; + +HPRef_Struct refquad_2e_1va = +{ + HP_QUAD, + refquad_2e_1va_splitedges, + refquad_2e_1va_splitfaces, + 0, + refquad_2e_1va_newelstypes, + refquad_2e_1va_newels +}; + + + +// HP_QUAD_2E_1VB +int refquad_2e_1vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 4, 3, 8 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 0, 0, 0 } +}; +int refquad_2e_1vb_splitfaces[][4] = +{ + { 1, 2, 4, 9 }, + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2e_1vb_newelstypes[] = +{ + // HP_TRIG_SINGEDGECORNER1, + // HP_TRIG_SINGEDGECORNER2, + // SZ QUAD_2E + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int refquad_2e_1vb_newels[][8] = +{ + //{ 1, 5, 9 }, + //{ 6, 1, 9 }, + { 1, 5, 9, 6 }, + { 5, 2, 7, 9 }, + { 4, 6, 9, 8 }, + { 7, 8, 9 }, + { 8, 7, 10, 11 }, + { 3, 11, 10 } +}; +HPRef_Struct refquad_2e_1vb = +{ + HP_QUAD, + refquad_2e_1vb_splitedges, + refquad_2e_1vb_splitfaces, + 0, + refquad_2e_1vb_newelstypes, + refquad_2e_1vb_newels +} +; + +// HP_QUAD_2E_1VC +int refquad_2e_1vc_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 4, 1, 8 }, + { 4, 3, 9 }, + { 0, 0, 0 } +}; +int refquad_2e_1vc_splitfaces[][4] = +{ + { 1, 2, 4, 10 }, + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2e_1vc_newelstypes[] = +{ + // HP_TRIG_SINGEDGECORNER1, + // HP_TRIG_SINGEDGECORNER2, + HP_QUAD_2E, + HP_TRIG_SINGEDGECORNER1, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2e_1vc_newels[][8] = +{ + //{ 1, 5, 10 }, + //{ 6, 1, 10 }, + { 1, 5, 10, 6}, + { 4, 8, 9 }, + { 5, 2, 7, 10 }, + { 8, 6, 10, 9 }, + { 10, 7, 3, 9 }, +}; +HPRef_Struct refquad_2e_1vc = +{ + HP_QUAD, + refquad_2e_1vc_splitedges, + refquad_2e_1vc_splitfaces, + 0, + refquad_2e_1vc_newelstypes, + refquad_2e_1vc_newels +}; + +// HP_QUAD_2E_2VA +int refquad_2e_2va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 4, 3, 8 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 2, 1, 12 }, + { 0, 0, 0 } +}; +int refquad_2e_2va_splitfaces[][4] = +{ + { 1, 2, 4, 9 }, + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2e_2va_newelstypes[] = +{ + //HP_TRIG_SINGEDGECORNER1, + //HP_TRIG_SINGEDGECORNER2, + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int refquad_2e_2va_newels[][8] = +{ + // { 1, 5, 9 }, + // { 6, 1, 9 }, + { 1, 5, 9, 6 }, + { 5, 12, 7, 9 }, + { 4, 6, 9, 8 }, + { 7, 8, 9 }, + { 8, 7, 10, 11 }, + { 3, 11, 10 }, + { 12, 2, 7 } +}; +HPRef_Struct refquad_2e_2va = +{ + HP_QUAD, + refquad_2e_2va_splitedges, + refquad_2e_2va_splitfaces, + 0, + refquad_2e_2va_newelstypes, + refquad_2e_2va_newels +}; + + + + + + +// HP_QUAD_2E_2VB +int refquad_2e_2vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 4, 1, 9 }, + { 4, 3, 10 }, + { 0, 0, 0 } +}; +int refquad_2e_2vb_splitfaces[][4] = +{ + { 1, 2, 4, 11 }, + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2e_2vb_newelstypes[] = +{ + // HP_TRIG_SINGEDGECORNER1, + // HP_TRIG_SINGEDGECORNER2, + HP_QUAD_2E, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2e_2vb_newels[][8] = +{ + //{ 1, 5, 11 }, + //{ 6, 1, 11 }, + { 1, 5, 11, 6 }, + { 4, 9, 10 }, + { 7, 2, 8 }, + { 5, 7, 8, 11 }, + { 9, 6, 11, 10 }, + { 3, 10, 11, 8 }, +}; +HPRef_Struct refquad_2e_2vb = +{ + HP_QUAD, + refquad_2e_2vb_splitedges, + refquad_2e_2vb_splitfaces, + 0, + refquad_2e_2vb_newelstypes, + refquad_2e_2vb_newels +}; + +// HP_QUAD_2E_2VC +int refquad_2e_2vc_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 4, 3, 8 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 4, 1, 12 }, + { 0, 0, 0 } +}; +int refquad_2e_2vc_splitfaces[][4] = +{ + { 1, 2, 4, 9 }, + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2e_2vc_newelstypes[] = +{ + // HP_TRIG_SINGEDGECORNER1, + // HP_TRIG_SINGEDGECORNER2, + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGEDGECORNER1, //SZ (vorher: SINGEDGECORNER2) + HP_NONE, +}; +int refquad_2e_2vc_newels[][8] = +{ + { 1, 5, 9 }, + { 6, 1, 9 }, + { 5, 2, 7, 9 }, + { 12, 6, 9, 8 }, + { 7, 8, 9 }, + { 8, 7, 10, 11 }, + { 3, 11, 10 }, + { 4, 12, 8 } +}; +HPRef_Struct refquad_2e_2vc = +{ + HP_QUAD, + refquad_2e_2vc_splitedges, + refquad_2e_2vc_splitfaces, + 0, + refquad_2e_2vc_newelstypes, + refquad_2e_2vc_newels +}; + +// HP_QUAD_2E_3V +int refquad_2e_3v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 4, 3, 8 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 2, 1, 12 }, + { 4, 1, 13 }, + { 0, 0, 0 } +}; +int refquad_2e_3v_splitfaces[][4] = +{ + { 1, 2, 4, 9 }, + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2e_3v_newelstypes[] = +{ + // HP_TRIG_SINGEDGECORNER1, + // HP_TRIG_SINGEDGECORNER2, + HP_QUAD_2E, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_NONE, +}; +int refquad_2e_3v_newels[][8] = +{ + //{ 1, 5, 9 }, + //{ 6, 1, 9 }, + { 1, 5, 9, 6 }, + { 5, 12, 7, 9 }, + { 13, 6, 9, 8 }, + { 7, 8, 9 }, + { 8, 7, 10, 11 }, + { 3, 11, 10 }, + { 12, 2, 7 }, + { 4, 13, 8 } +}; +HPRef_Struct refquad_2e_3v = +{ + HP_QUAD, + refquad_2e_3v_splitedges, + refquad_2e_3v_splitfaces, + 0, + refquad_2e_3v_newelstypes, + refquad_2e_3v_newels +}; + +// HP_QUAD_2EB_0V +int refquad_2eb_0v_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 0, 0, 0 } +}; +int refquad_2eb_0v_splitfaces[][4] = +{ + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2eb_0v_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_0v_newels[][8] = +{ + { 1, 2, 6, 5 }, + { 3, 4, 8, 7 }, + { 5, 6, 7, 8 } +}; +HPRef_Struct refquad_2eb_0v = +{ + HP_QUAD, + refquad_2eb_0v_splitedges, + refquad_2eb_0v_splitfaces, + 0, + refquad_2eb_0v_newelstypes, + refquad_2eb_0v_newels +}; + + +// HP_QUAD_2EB_1VA +int refquad_2eb_1va_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 1, 2, 9 }, + { 0, 0, 0 } +}; +int refquad_2eb_1va_splitfaces[][4] = +{ + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2eb_1va_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_1va_newels[][8] = +{ + { 9, 2, 6, 5 }, + { 3, 4, 8, 7 }, + { 1, 9, 5 }, + { 5, 6, 7, 8 } +}; +HPRef_Struct refquad_2eb_1va = +{ + HP_QUAD, + refquad_2eb_1va_splitedges, + refquad_2eb_1va_splitfaces, + 0, + refquad_2eb_1va_newelstypes, + refquad_2eb_1va_newels +}; + +// HP_QUAD_2EB_1VB +int refquad_2eb_1vb_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 2, 1, 9 }, + { 0, 0, 0 } +}; +int refquad_2eb_1vb_splitfaces[][4] = +{ + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2eb_1vb_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_1vb_newels[][8] = +{ + { 1, 9, 6, 5 }, + { 3, 4, 8, 7 }, + { 9, 2, 6 }, + { 5, 6, 7, 8 } +}; +HPRef_Struct refquad_2eb_1vb = +{ + HP_QUAD, + refquad_2eb_1vb_splitedges, + refquad_2eb_1vb_splitfaces, + 0, + refquad_2eb_1vb_newelstypes, + refquad_2eb_1vb_newels +}; + +// HP_QUAD_2EB_2VA +int refquad_2eb_2va_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 1, 2, 9 }, + { 2, 1, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_2eb_2va_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_2va_newels[][8] = +{ + { 9, 10, 6, 5 }, + { 3, 4, 8, 7 }, + { 1, 9, 5 }, + { 10, 2, 6 }, + { 5, 6, 7, 8 } +}; +HPRef_Struct refquad_2eb_2va = +{ + HP_QUAD, + refquad_2eb_2va_splitedges, + 0, 0, + refquad_2eb_2va_newelstypes, + refquad_2eb_2va_newels +}; + + + +// HP_QUAD_2EB_2VB +int refquad_2eb_2vb_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 1, 2, 9 }, + { 3, 4, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_2eb_2vb_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER1, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_2vb_newels[][8] = +{ + { 9, 2, 6, 5 }, + { 10, 4, 8, 7 }, + { 1, 9, 5 }, + { 3, 10, 7 }, + { 5, 6, 7, 8 } +}; +HPRef_Struct refquad_2eb_2vb = +{ + HP_QUAD, + refquad_2eb_2vb_splitedges, + 0, 0, + refquad_2eb_2vb_newelstypes, + refquad_2eb_2vb_newels +}; + + + +// HP_QUAD_2EB_2VC +int refquad_2eb_2vc_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 1, 2, 9 }, + { 4, 3, 10 }, + { 0, 0, 0 } +}; +int refquad_2eb_2vc_splitfaces[][4] = +{ + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2eb_2vc_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_2vc_newels[][8] = +{ + { 9, 2, 6, 5 }, + { 3, 10, 8, 7 }, + { 1, 9, 5 }, + { 10, 4, 8 }, + { 5, 6, 7, 8 } +}; +HPRef_Struct refquad_2eb_2vc = +{ + HP_QUAD, + refquad_2eb_2vc_splitedges, + refquad_2eb_2vc_splitfaces, + 0, + refquad_2eb_2vc_newelstypes, + refquad_2eb_2vc_newels +}; + + +// HP_QUAD_2EB_2VD +int refquad_2eb_2vd_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 2, 1, 9 }, + { 4, 3, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_2eb_2vd_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_2vd_newels[][8] = +{ + { 1, 9, 6, 5 }, + { 3, 10, 8, 7 }, + { 9, 2, 6 }, + { 10, 4, 8 }, + { 5, 6, 7, 8 } +}; +HPRef_Struct refquad_2eb_2vd = +{ + HP_QUAD, + refquad_2eb_2vd_splitedges, + 0, 0, + refquad_2eb_2vd_newelstypes, + refquad_2eb_2vd_newels +}; + + +// HP_QUAD_2EB_3VA +int refquad_2eb_3va_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 2, 1, 8 }, + { 3, 2, 9 }, + { 4, 1, 10 }, + { 3, 4, 11 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_2eb_3va_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_3va_newels[][8] = +{ + { 1, 7, 5 }, + { 8, 2, 6 }, + { 3, 11, 9}, + { 7, 8, 6, 5 }, + { 11, 4, 10, 9 }, + { 5, 6, 9, 10 } +}; +HPRef_Struct refquad_2eb_3va = +{ + HP_QUAD, + refquad_2eb_3va_splitedges, + 0, 0, + refquad_2eb_3va_newelstypes, + refquad_2eb_3va_newels +}; + + +// HP_QUAD_2EB_3VB +int refquad_2eb_3vb_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 1, 2, 7 }, + { 2, 1, 8 }, + { 3, 2, 9 }, + { 4, 1, 10 }, + { 4, 3, 11 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE refquad_2eb_3vb_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_NONE, +}; +int refquad_2eb_3vb_newels[][8] = +{ + { 1, 7, 5 }, + { 8, 2, 6 }, + { 11, 4, 10 }, + { 7, 8, 6, 5 }, + { 3, 11, 10, 9 }, + { 5, 6, 9, 10 } +}; +HPRef_Struct refquad_2eb_3vb = +{ + HP_QUAD, + refquad_2eb_3vb_splitedges, + 0, 0, + refquad_2eb_3vb_newelstypes, + refquad_2eb_3vb_newels +}; + + +// HP_QUAD_2EB_4V +int refquad_2eb_4v_splitedges[][3] = +{ + { 1, 4, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 4, 1, 8 }, + { 1, 2, 9 }, + { 2, 1, 10 }, + { 3, 4, 11 }, + { 4, 3, 12 }, + { 0, 0, 0 } +}; +int refquad_2eb_4v_splitfaces[][4] = +{ + { 0, 0, 0, 0 }, +}; +HPREF_ELEMENT_TYPE refquad_2eb_4v_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int refquad_2eb_4v_newels[][8] = +{ + { 9, 10, 6, 5 }, + { 11, 12, 8, 7 }, + { 5, 6, 7, 8 }, + { 1, 9, 5 }, + { 10, 2, 6 }, + { 3, 11, 7 }, + { 12, 4, 8 }, +}; +HPRef_Struct refquad_2eb_4v = +{ + HP_QUAD, + refquad_2eb_4v_splitedges, + refquad_2eb_4v_splitfaces, + 0, + refquad_2eb_4v_newelstypes, + refquad_2eb_4v_newels +}; + + + +// HP_QUAD_3E +int refquad_3e_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 3, 4, 10 }, + { 4, 3, 12 }, + { 0, 0, 0 } +}; + +int refquad_3e_splitfaces[][4] = +{ + { 1, 2, 4, 13 }, + { 2, 3, 1, 14 }, + { 0, 0, 0, 0 }, +}; + +HPREF_ELEMENT_TYPE refquad_3e_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_2E, +// HP_TRIG_SINGEDGECORNER1, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER1, + + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + + HP_QUAD, + HP_NONE, +}; +int refquad_3e_newels[][8] = +{ +// { 1, 5, 13 }, +// { 6, 1, 13 }, +// { 7, 2, 14 }, +// { 2, 8, 14 }, + { 1, 5, 13, 6 }, + { 2, 8, 14, 7 }, + { 5, 7, 14, 13 }, + { 8, 3, 10, 14 }, + { 4, 6, 13, 12 }, + { 13, 14, 10, 12 } +}; +HPRef_Struct refquad_3e = +{ + HP_QUAD, + refquad_3e_splitedges, + refquad_3e_splitfaces, + 0, + refquad_3e_newelstypes, + refquad_3e_newels +}; + + + + + + + +// HP_QUAD_3E_3VA +int refquad_3e_3va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 3, 4, 10 }, + { 3, 2, 11 }, + { 4, 3, 12 }, + { 0, 0, 0 } +}; + +int refquad_3e_3va_splitfaces[][4] = +{ + { 1, 2, 4, 13 }, + { 2, 3, 1, 14 }, + { 0, 0, 0, 0 }, +}; + +HPREF_ELEMENT_TYPE refquad_3e_3va_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_2E, + +// HP_TRIG_SINGEDGECORNER1, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + + HP_QUAD, + HP_NONE, +}; +int refquad_3e_3va_newels[][8] = +{ +// { 1, 5, 13 }, +// { 6, 1, 13 }, +// { 7, 2, 14 }, +// { 2, 8, 14 }, + { 1, 5, 13, 6 }, + { 2, 8, 14, 7 }, + { 11, 3, 10 }, + { 5, 7, 14, 13 }, + { 8, 11, 10, 14 }, + { 4, 6, 13, 12 }, + { 13, 14, 10, 12 } +}; +HPRef_Struct refquad_3e_3va = +{ + HP_QUAD, + refquad_3e_3va_splitedges, + refquad_3e_3va_splitfaces, + 0, + refquad_3e_3va_newelstypes, + refquad_3e_3va_newels +}; + +// HP_QUAD_3E_3VB +int refquad_3e_3vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 3, 4, 10 }, + { 4, 1, 11 }, + { 4, 3, 12 }, + { 0, 0, 0 } +}; + +int refquad_3e_3vb_splitfaces[][4] = +{ + { 1, 2, 4, 13 }, + { 2, 3, 1, 14 }, + { 0, 0, 0, 0 }, +}; + +HPREF_ELEMENT_TYPE refquad_3e_3vb_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_2E, + +// HP_TRIG_SINGEDGECORNER1, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER1, + + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + + HP_QUAD, + HP_NONE, +}; +int refquad_3e_3vb_newels[][8] = +{ +// { 1, 5, 13 }, +// { 6, 1, 13 }, +// { 7, 2, 14 }, +// { 2, 8, 14 }, + { 1, 5, 13, 6 }, + { 2, 8, 14, 7 }, + { 4, 11, 12 }, + { 5, 7, 14, 13 }, + { 8, 3, 10, 14 }, + { 11, 6, 13, 12 }, + { 13, 14, 10, 12 } +}; +HPRef_Struct refquad_3e_3vb = +{ + HP_QUAD, + refquad_3e_3vb_splitedges, + refquad_3e_3vb_splitfaces, + 0, + refquad_3e_3vb_newelstypes, + refquad_3e_3vb_newels +}; + + + + + + + + + +// HP_QUAD_3E_4V +int refquad_3e_4v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 3, 4, 10 }, + { 3, 2, 11 }, + { 4, 3, 12 }, + { 4, 1, 15 }, + { 0, 0, 0 } +}; + +int refquad_3e_4v_splitfaces[][4] = +{ + { 1, 2, 4, 13 }, + { 2, 3, 1, 14 }, + { 0, 0, 0, 0 }, +}; + +HPREF_ELEMENT_TYPE refquad_3e_4v_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_2E, + +// HP_TRIG_SINGEDGECORNER1, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER2, +// HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + + HP_QUAD, + HP_NONE, +}; +int refquad_3e_4v_newels[][8] = +{ +// { 1, 5, 13 }, +// { 6, 1, 13 }, +// { 7, 2, 14 }, +// { 2, 8, 14 }, + { 1, 5, 13, 6 }, + { 2, 8, 14, 7 }, + { 11, 3, 10 }, + { 4, 15, 12 }, + { 5, 7, 14, 13 }, + { 8, 11, 10, 14 }, + { 15, 6, 13, 12 }, + { 13, 14, 10, 12 } +}; +HPRef_Struct refquad_3e_4v = +{ + HP_QUAD, + refquad_3e_4v_splitedges, + refquad_3e_4v_splitfaces, + 0, + refquad_3e_4v_newelstypes, + refquad_3e_4v_newels +}; + + + + + + + + + +// HP_QUAD_4E +int refquad_4e_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 3, 2, 9 }, + { 3, 4, 10 }, + { 4, 1, 11 }, + { 4, 3, 12 }, + { 0, 0, 0 } +}; + +int refquad_4e_splitfaces[][4] = +{ + { 1, 2, 4, 13 }, + { 2, 3, 1, 14 }, + { 3, 4, 2, 15 }, + { 4, 1, 3, 16 }, + { 0, 0, 0, 0 }, +}; + +HPREF_ELEMENT_TYPE refquad_4e_newelstypes[] = +{ + HP_QUAD_2E, + HP_QUAD_2E, + HP_QUAD_2E, + HP_QUAD_2E, + + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + + HP_QUAD, + HP_NONE, +}; +int refquad_4e_newels[][8] = +{ + { 1, 5, 13, 6 }, + { 2, 8, 14, 7 }, + { 3, 10, 15, 9 }, + { 4, 11, 16, 12 }, + { 5, 7, 14, 13 }, + { 8, 9, 15, 14 }, + { 10, 12, 16, 15 }, + { 11, 6, 13, 16 }, + { 13, 14, 15, 16 } +}; +HPRef_Struct refquad_4e = +{ + HP_QUAD, + refquad_4e_splitedges, + refquad_4e_splitfaces, + 0, + refquad_4e_newelstypes, + refquad_4e_newels +}; diff --git a/libsrc/meshing/hpref_segm.hpp b/libsrc/meshing/hpref_segm.hpp new file mode 100644 index 00000000..25445823 --- /dev/null +++ b/libsrc/meshing/hpref_segm.hpp @@ -0,0 +1,122 @@ + // HP_SEGM + int refsegm_splitedges[][3] = + { + { 0, 0, 0 } + }; + + HPREF_ELEMENT_TYPE refsegm_newelstypes[] = + { + HP_SEGM, + HP_NONE, + }; + int refsegm_newels[][8] = + { + { 1, 2 }, + }; + HPRef_Struct refsegm = + { + HP_SEGM, + refsegm_splitedges, + 0, 0, + refsegm_newelstypes, + refsegm_newels + }; + + // HP_SEGM_SINGCORNERL = 2, + int refsegm_scl_splitedges[][3] = + { + { 1, 2, 3 }, + { 0, 0, 0 } + }; + + HPREF_ELEMENT_TYPE refsegm_scl_newelstypes[] = + { + HP_SEGM_SINGCORNERL, + HP_SEGM, + HP_NONE, + }; + + int refsegm_scl_newels[][8] = + { + { 1, 3 }, + { 3, 2 }, + { 0, 0 }, + }; + HPRef_Struct refsegm_scl = + { + HP_SEGM, + refsegm_scl_splitedges, + 0, 0, + refsegm_scl_newelstypes, + refsegm_scl_newels + }; + + + + // HP_SEGM_SINGCORNERR + int refsegm_scr_splitedges[][3] = + { + { 2, 1, 3 }, + { 0, 0, 0 } + }; + + HPREF_ELEMENT_TYPE refsegm_scr_newelstypes[] = + { + HP_SEGM, + HP_SEGM_SINGCORNERR, + HP_NONE, + }; + int refsegm_scr_newels[][8] = + { + { 1, 3 }, + { 3, 2 }, + { 0, 0 }, + }; + HPRef_Struct refsegm_scr = + { + HP_SEGM, + refsegm_scr_splitedges, + 0, 0, + refsegm_scr_newelstypes, + refsegm_scr_newels + }; + + + + + + + // HP_SEGM_SINGCORNERS = 3, + int refsegm_sc2_splitedges[][3] = + { + { 1, 2, 3 }, + { 2, 1, 4 }, + { 0, 0, 0 } + }; + + HPREF_ELEMENT_TYPE refsegm_sc2_newelstypes[] = + { + HP_SEGM_SINGCORNERL, + HP_SEGM_SINGCORNERR, + HP_SEGM, + HP_NONE, + }; + int refsegm_sc2_newels[][8] = + { + { 1, 3 }, + { 4, 2 }, + { 3, 4 }, + { 0, 0 }, + }; + HPRef_Struct refsegm_sc2 = + { + HP_SEGM, + refsegm_sc2_splitedges, + 0, 0, + refsegm_sc2_newelstypes, + refsegm_sc2_newels + }; + + + + diff --git a/libsrc/meshing/hpref_tet.hpp b/libsrc/meshing/hpref_tet.hpp new file mode 100644 index 00000000..df0e2af8 --- /dev/null +++ b/libsrc/meshing/hpref_tet.hpp @@ -0,0 +1,3128 @@ + + + +// HP_TET +int reftet_splitedges[][3] = +{ + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_newelstypes[] = +{ + HP_TET, + HP_NONE, +}; +int reftet_newels[][8] = +{ + { 1, 2, 3, 4 }, +}; +HPRef_Struct reftet = +{ + HP_TET, + reftet_splitedges, + 0, 0, + reftet_newelstypes, + reftet_newels +}; + + + +/* *********** Tet - Refinement - 0 edges *************** */ + +// HP_TET_0E_1V +int reftet_0e_1v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_0e_1v_newelstypes[] = +{ + HP_TET_0E_1V, + HP_PRISM, + HP_NONE, +}; +int reftet_0e_1v_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 5, 6, 7, 2, 3, 4 } +}; +HPRef_Struct reftet_0e_1v = +{ + HP_TET, + reftet_0e_1v_splitedges, + 0, 0, + reftet_0e_1v_newelstypes, + reftet_0e_1v_newels +}; + + + +// HP_TET_0E_2V +int reftet_0e_2v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_0e_2v_newelstypes[] = +{ + HP_TET_0E_1V, + HP_TET_0E_1V, + HP_PRISM, + HP_PRISM, + HP_NONE, +}; +int reftet_0e_2v_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 2, 10, 9, 8 }, + { 5, 6, 7, 8, 9, 10 }, + { 4, 10, 7, 3, 9, 6 }, +}; +HPRef_Struct reftet_0e_2v = +{ + HP_TET, + reftet_0e_2v_splitedges, + 0, 0, + reftet_0e_2v_newelstypes, + reftet_0e_2v_newels +}; + + + + + +// HP_TET_0E_3V +int reftet_0e_3v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 0, 0, 0 } +}; +int reftet_0e_3v_splitfaces[][4] = + { + { 1, 2, 3, 14 }, + { 2, 3, 1, 15 }, + { 3, 1, 2, 16 }, + { 0, 0, 0, 0 }, + }; +HPREF_ELEMENT_TYPE reftet_0e_3v_newelstypes[] = +{ + HP_PYRAMID_0E_1V, + HP_PYRAMID_0E_1V, + HP_PYRAMID_0E_1V, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_TET, + HP_NONE, +}; +int reftet_0e_3v_newels[][8] = +{ + { 1, 5, 14, 6, 7 }, + { 2, 9, 15, 8, 10 }, + { 3, 11, 16, 12, 13 }, + { 5, 14, 7, 8, 15, 10 }, + { 9, 15, 10, 12, 16, 13 }, + { 6, 7, 14, 11, 13, 16 }, + { 14, 15, 16, 7, 10, 13 }, + { 7, 10, 13, 4 } +}; +HPRef_Struct reftet_0e_3v = +{ + HP_TET, + reftet_0e_3v_splitedges, + reftet_0e_3v_splitfaces, + 0, + reftet_0e_3v_newelstypes, + reftet_0e_3v_newels +}; + + + + + +// HP_TET_0E_4V +int reftet_0e_4v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_0e_4v_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 1, 2, 4, 18 }, + { 1, 3, 4, 19 }, + + { 2, 1, 3, 20 }, + { 2, 1, 4, 21 }, + { 2, 3, 4, 22 }, + + { 3, 1, 2, 23 }, + { 3, 1, 4, 24 }, + { 3, 2, 4, 25 }, + + { 4, 1, 2, 26 }, + { 4, 1, 3, 27 }, + { 4, 2, 3, 28 }, + { 0, 0, 0, 0 }, + }; +int reftet_0e_4v_splitelements[][5] = + { + { 1, 2, 3, 4, 29 }, + { 2, 3, 4, 1, 30 }, + { 3, 4, 1, 2, 31 }, + { 4, 1, 2, 3, 32 }, + { 0 }, + }; +HPREF_ELEMENT_TYPE reftet_0e_4v_newelstypes[] = +{ + HP_HEX_0E_1V, + HP_HEX_0E_1V, + HP_HEX_0E_1V, + HP_HEX_0E_1V, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_TET, + HP_NONE, +}; +int reftet_0e_4v_newels[][8] = +{ + { 1, 5, 17, 6, 7, 18, 29, 19 }, + { 2, 9, 20, 8, 10, 22, 30, 21 }, + { 3, 11, 23, 12, 13, 24, 31, 25 }, + { 4, 15, 26, 14, 16, 28, 32, 27 }, + { 5, 17, 18, 8, 20, 21 }, + { 18, 17, 29, 21, 20, 30 }, + { 6, 19, 17, 11, 24, 23 }, + { 17, 19, 29, 23, 24, 31 }, + { 7, 18, 19, 14, 26, 27 }, + { 19, 18, 29, 27, 26, 32 }, + { 9, 20, 22, 12, 23, 25 }, + { 22, 20, 30, 25, 23, 31 }, + { 10, 22, 21, 15, 28, 26 }, + { 21, 22, 30, 26, 28, 32 }, + { 13, 24, 25, 16, 27, 28 }, + { 25, 24, 31, 28, 27, 32 }, + { 17, 20, 23, 29, 30, 31 }, + { 18, 26, 21, 29, 32, 30 }, + { 19, 24, 27, 29, 31, 32 }, + { 22, 28, 25, 30, 32, 31 }, + { 29, 30, 31, 32 }, +}; +HPRef_Struct reftet_0e_4v = +{ + HP_TET, + reftet_0e_4v_splitedges, + reftet_0e_4v_splitfaces, + reftet_0e_4v_splitelements, + reftet_0e_4v_newelstypes, + reftet_0e_4v_newels +}; + + + + + + + + + + + + + + + + + +/* *********** Tet - Refinement - 1 edge *************** */ + + + +// HP_TET_1E_0V +int reftet_1e_0v_splitedges[][3] = +{ + { 1, 3, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 2, 4, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_1e_0v_newelstypes[] = +{ + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_NONE, +}; +int reftet_1e_0v_newels[][8] = +{ + { 1, 5, 6, 2, 7, 8 }, + { 7, 3, 5, 8, 4, 6 } +}; +HPRef_Struct reftet_1e_0v = +{ + HP_TET, + reftet_1e_0v_splitedges, + 0, 0, + reftet_1e_0v_newelstypes, + reftet_1e_0v_newels +}; + + + + + +// HP_TET_1E_1VA +int reftet_1e_1va_splitedges[][3] = +{ + { 1, 3, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 2, 4, 8 }, + { 1, 2, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_1e_1va_newelstypes[] = +{ + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_NONE, +}; +int reftet_1e_1va_newels[][8] = +{ + { 1, 9, 5, 6 }, + { 9, 5, 6, 2, 7, 8 }, + { 7, 3, 5, 8, 4, 6 } +}; +HPRef_Struct reftet_1e_1va = +{ + HP_TET, + reftet_1e_1va_splitedges, + 0, 0, + reftet_1e_1va_newelstypes, + reftet_1e_1va_newels +}; + + + + + + +// HP_TET_1E_1VB +int reftet_1e_1vb_splitedges[][3] = +{ + { 1, 3, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 2, 4, 8 }, + { 4, 1, 9 }, + { 4, 2, 10 }, + { 4, 3, 11 }, + { 0, 0, 0 } +}; +int reftet_1e_1vb_splitelements[][5] = +{ + { 4, 1, 2, 3, 12 }, + { 0 } +}; + +HPREF_ELEMENT_TYPE reftet_1e_1vb_newelstypes[] = +{ + HP_PRISM_SINGEDGE, + HP_TET_0E_1V, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_NONE, +}; +int reftet_1e_1vb_newels[][8] = +{ + { 1, 5, 6, 2, 7, 8 }, + { 4, 11, 10, 9 }, + { 7, 8, 10, 11, 12 }, + { 3, 7, 11, 12 }, + { 5, 11, 9, 6, 12 }, + { 5, 3, 11, 12 }, + { 6, 9, 10, 8, 12 }, + { 5, 7, 3, 12 }, + { 5, 6, 8, 7, 12 }, + { 9, 11, 10, 12 } +}; +HPRef_Struct reftet_1e_1vb = +{ + HP_TET, + reftet_1e_1vb_splitedges, + 0, + reftet_1e_1vb_splitelements, + reftet_1e_1vb_newelstypes, + reftet_1e_1vb_newels +}; + + + + + + + + +// HP_TET_1E_2VA +int reftet_1e_2va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_1e_2va_newelstypes[] = +{ + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_NONE, +}; +int reftet_1e_2va_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 2, 8, 10, 9 }, + { 5, 6, 7, 8, 9, 10 }, + { 4, 10, 7, 3, 9, 6 }, +}; +HPRef_Struct reftet_1e_2va = +{ + HP_TET, + reftet_1e_2va_splitedges, + 0, 0, + reftet_1e_2va_newelstypes, + reftet_1e_2va_newels +}; + + + + + + + +// HP_TET_1E_2VB +int reftet_1e_2vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 1, 10 }, + { 3, 2, 11 }, + { 3, 4, 12 }, + { 0, 0, 0 } +}; +int reftet_1e_2vb_splitelements[][5] = +{ + { 3, 4, 1, 2, 13 }, + { 0 } +}; + +HPREF_ELEMENT_TYPE reftet_1e_2vb_newelstypes[] = +{ + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_TET_0E_1V, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_NONE, +}; +int reftet_1e_2vb_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 5, 6, 7, 2, 8, 9 }, + { 3, 10, 11, 12 }, + + { 8, 9, 12, 11, 13 }, + { 4, 12, 9, 13 }, + { 6, 10, 12, 7, 13 }, + { 4, 7, 12, 13 }, + { 6, 8, 11, 10, 13 }, + { 4, 9, 7, 13 }, + { 6, 7, 9, 8, 13 }, + { 10, 11, 12, 13 }, +}; +HPRef_Struct reftet_1e_2vb = +{ + HP_TET, + reftet_1e_2vb_splitedges, + 0, + reftet_1e_2vb_splitelements, + reftet_1e_2vb_newelstypes, + reftet_1e_2vb_newels +}; + + + + + + +// HP_TET_1E_2VC +int reftet_1e_2vc_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 4, 1, 10 }, + { 4, 2, 11 }, + { 4, 3, 12 }, + { 0, 0, 0 } +}; +int reftet_1e_2vc_splitelements[][5] = +{ + { 4, 1, 2, 3, 13 }, + { 0 } +}; + +HPREF_ELEMENT_TYPE reftet_1e_2vc_newelstypes[] = +{ + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_TET_0E_1V, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_NONE, +}; +int reftet_1e_2vc_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 5, 6, 7, 2, 8, 9 }, + { 4, 11, 10, 12 }, + { 8, 9, 11, 12, 13 }, + { 3, 8, 12, 13 }, + { 7, 6, 12, 10, 13 }, + { 3, 12, 6, 13 }, + { 9, 7, 10, 11, 13 }, + { 3, 6, 8, 13 }, + { 6, 7, 9, 8, 13 }, + { 10, 12, 11, 13 } +}; +HPRef_Struct reftet_1e_2vc = +{ + HP_TET, + reftet_1e_2vc_splitedges, + 0, + reftet_1e_2vc_splitelements, + reftet_1e_2vc_newelstypes, + reftet_1e_2vc_newels +}; + + + + + + + + +/* + +// HP_TET_1E_2VD +int reftet_1e_2vd_splitedges[][3] = +{ + { 1, 3, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 2, 4, 8 }, + { 3, 1, 9 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 4, 1, 12 }, + { 4, 2, 13 }, + { 4, 3, 14 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_1e_2vd_newelstypes[] = +{ + HP_PRISM_SINGEDGE, + HP_TET_0E_1V, + HP_TET_0E_1V, + HP_PRISM, + HP_HEX, + HP_NONE, +}; +int reftet_1e_2vd_newels[][8] = +{ + { 1, 5, 6, 2, 7, 8 }, + { 4, 13, 12, 14 }, + { 3, 10, 11, 9 }, + { 14, 13, 12, 11, 10, 9 }, + { 6, 12, 13, 8, 5, 9, 10, 7 }, +}; +HPRef_Struct reftet_1e_2vd = +{ + HP_TET, + reftet_1e_2vd_splitedges, + 0, 0, + reftet_1e_2vd_newelstypes, + reftet_1e_2vd_newels +}; + +*/ + + + + +// HP_TET_1E_2VD, // 1 v on edge +int reftet_1e_2vd_splitedges[][3] = +{ + // { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + // { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_1e_2vd_splitfaces[][4] = + { + { 1, 3, 4, 19 }, + { 2, 3, 4, 22 }, + { 3, 1, 4, 24 }, + { 3, 2, 4, 25 }, + { 4, 1, 3, 27 }, + { 4, 2, 3, 28 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_1e_2vd_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_TET_0E_1V, + HP_TET_0E_1V, + HP_PRISM, + HP_HEX, + HP_PYRAMID, + HP_HEX, + HP_PYRAMID, + HP_PRISM, + HP_PRISM, + HP_NONE, + }; +int reftet_1e_2vd_newels[][8] = +{ + { 1, 6, 7, 2, 9, 10 }, + { 3, 11, 12, 13 }, + { 4, 16, 15, 14 }, + { 7, 6, 19, 10, 9, 22 }, + { 7, 19, 27, 14, 10, 22, 28, 15 }, + { 14, 15, 28, 27, 16 }, + { 9, 6, 19, 22, 12, 11, 24, 25 }, + { 12, 11, 24, 25, 13 }, + { 19, 24, 27, 22, 25, 28 }, + { 16, 28, 27, 13, 25, 24 } +}; +HPRef_Struct reftet_1e_2vd = +{ + HP_TET, + reftet_1e_2vd_splitedges, + reftet_1e_2vd_splitfaces, + 0, + reftet_1e_2vd_newelstypes, + reftet_1e_2vd_newels +}; + + + + + + + + + + + + + + + +// HP_TET_1E_3VA +int reftet_1e_3va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 0, 0, 0 } +}; +int reftet_1e_3va_splitelements[][5] = +{ + { 1, 2, 3, 4, 14 }, + { 0 } +}; + +HPREF_ELEMENT_TYPE reftet_1e_3va_newelstypes[] = +{ + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_TET_0E_1V, + + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_PYRAMID, + HP_TET, + HP_NONE, +}; +int reftet_1e_3va_newels[][8] = +{ + { 5, 6, 7, 8, 9, 10 }, + { 1, 5, 6, 7 }, + { 2, 8, 10, 9 }, + { 3, 11, 12, 13 }, + + { 6, 7, 10, 9, 14 }, + { 4, 10, 7, 14 }, + { 9, 10, 13, 12, 14 }, + { 4, 13, 10, 14 }, + { 6, 11, 13, 7, 14 }, + { 4, 7, 13, 14 }, + { 6, 11, 12, 9, 14 }, + { 11, 13, 12, 14 }, +}; + +HPRef_Struct reftet_1e_3va = +{ + HP_TET, + reftet_1e_3va_splitedges, + 0, + reftet_1e_3va_splitelements, + reftet_1e_3va_newelstypes, + reftet_1e_3va_newels +}; + + + + + + + + + + + + + + + + + + + + + + +// HP_TET_1E_3VB, // 1 v on edge +int reftet_1e_3vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + // { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_1e_3vb_splitfaces[][4] = + { + { 1, 3, 4, 19 }, + { 2, 3, 4, 22 }, + { 3, 1, 4, 24 }, + { 3, 2, 4, 25 }, + { 4, 1, 3, 27 }, + { 4, 2, 3, 28 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_1e_3vb_newelstypes[] = + { + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_TET_0E_1V, + HP_TET_0E_1V, + HP_PRISM, + HP_HEX, + HP_PYRAMID, + HP_HEX, + HP_PYRAMID, + HP_PRISM, + HP_PRISM, + HP_NONE, + }; +int reftet_1e_3vb_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 5, 6, 7, 2, 9, 10 }, + { 3, 11, 12, 13 }, + { 4, 16, 15, 14 }, + { 7, 6, 19, 10, 9, 22 }, + { 7, 19, 27, 14, 10, 22, 28, 15 }, + { 14, 15, 28, 27, 16 }, + { 9, 6, 19, 22, 12, 11, 24, 25 }, + { 12, 11, 24, 25, 13 }, + { 19, 24, 27, 22, 25, 28 }, + { 16, 28, 27, 13, 25, 24 } +}; +HPRef_Struct reftet_1e_3vb = +{ + HP_TET, + reftet_1e_3vb_splitedges, + reftet_1e_3vb_splitfaces, + 0, + reftet_1e_3vb_newelstypes, + reftet_1e_3vb_newels +}; + + + + + + +/* +// HP_TET_1E_4V +int reftet_1e_4v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_1e_4v_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 1, 2, 4, 18 }, + { 1, 3, 4, 19 }, + + { 2, 1, 3, 20 }, + { 2, 1, 4, 21 }, + { 2, 3, 4, 22 }, + + { 3, 1, 2, 23 }, + { 3, 1, 4, 24 }, + { 3, 2, 4, 25 }, + + { 4, 1, 2, 26 }, + { 4, 1, 3, 27 }, + { 4, 2, 3, 28 }, + { 0, 0, 0, 0 }, + }; +int reftet_1e_4v_splitelements[][5] = + { + { 1, 2, 3, 4, 29 }, + { 2, 3, 4, 1, 30 }, + { 3, 4, 1, 2, 31 }, + { 4, 1, 2, 3, 32 }, + { 0 }, + }; +HPREF_ELEMENT_TYPE reftet_1e_4v_newelstypes[] = +{ + HP_HEX_1E_1V, + HP_HEX_1E_1V, + HP_HEX_0E_1V, + HP_HEX_0E_1V, + HP_PRISM_SINGEDGE, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_TET, + HP_NONE, +}; +int reftet_1e_4v_newels[][8] = +{ + { 1, 5, 17, 6, 7, 18, 29, 19 }, + // { 2, 9, 20, 8, 10, 22, 30, 21 }, + { 2, 8, 21, 10, 9, 20, 30, 22 }, + { 3, 11, 23, 12, 13, 24, 31, 25 }, + { 4, 15, 26, 14, 16, 28, 32, 27 }, + { 5, 17, 18, 8, 20, 21 }, + { 18, 17, 29, 21, 20, 30 }, + { 6, 19, 17, 11, 24, 23 }, + { 17, 19, 29, 23, 24, 31 }, + { 7, 18, 19, 14, 26, 27 }, + { 19, 18, 29, 27, 26, 32 }, + { 9, 20, 22, 12, 23, 25 }, + { 22, 20, 30, 25, 23, 31 }, + { 10, 22, 21, 15, 28, 26 }, + { 21, 22, 30, 26, 28, 32 }, + { 13, 24, 25, 16, 27, 28 }, + { 25, 24, 31, 28, 27, 32 }, + { 17, 20, 23, 29, 30, 31 }, + { 18, 26, 21, 29, 32, 30 }, + { 19, 24, 27, 29, 31, 32 }, + { 22, 28, 25, 30, 32, 31 }, + + { 29, 30, 31, 32 }, +}; +HPRef_Struct reftet_1e_4v = +{ + HP_TET, + reftet_1e_4v_splitedges, + reftet_1e_4v_splitfaces, + reftet_1e_4v_splitelements, + reftet_1e_4v_newelstypes, + reftet_1e_4v_newels +}; +*/ + + + + +// HP_TET_1E_4V +int reftet_1e_4v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_1e_4v_splitfaces[][4] = + { + { 1, 3, 4, 17 }, + { 2, 3, 4, 18 }, + + { 3, 1, 4, 19 }, + { 3, 2, 4, 20 }, + + { 4, 1, 3, 21 }, + { 4, 2, 3, 22 }, + { 0, 0, 0, 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_1e_4v_newelstypes[] = +{ + HP_TET_1E_1VA, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_HEX, + HP_HEX, + HP_PRISM, + HP_PRISM, + + HP_PYRAMID, + HP_TET_0E_1V, + + HP_PYRAMID, + HP_TET_0E_1V, + + HP_NONE, +}; + +int reftet_1e_4v_newels[][8] = +{ + { 1, 5, 6, 7 }, + { 2, 8, 10, 9 }, + + { 5, 6, 7, 8, 9, 10 }, + { 7, 6, 17, 10, 9, 18 }, + + { 7, 10, 18, 17, 14, 15, 22, 21 }, + { 9, 6, 17, 18, 12, 11, 19, 20 }, + + { 17, 19, 21, 18, 20, 22 }, + { 16, 22, 21, 13, 20, 19 }, + + { 14, 15, 22, 21, 16 }, + { 4, 14, 16, 15 }, + { 12, 11, 19, 20, 13 }, + { 3, 11, 12, 13 }, + + + + { 1, 5, 17, 6, 7, 18, 29, 19 }, + // { 2, 9, 20, 8, 10, 22, 30, 21 }, + { 2, 8, 21, 10, 9, 20, 30, 22 }, + { 3, 11, 23, 12, 13, 24, 31, 25 }, + { 4, 15, 26, 14, 16, 28, 32, 27 }, + { 5, 17, 18, 8, 20, 21 }, + { 18, 17, 29, 21, 20, 30 }, + { 6, 19, 17, 11, 24, 23 }, + { 17, 19, 29, 23, 24, 31 }, + { 7, 18, 19, 14, 26, 27 }, + { 19, 18, 29, 27, 26, 32 }, + { 9, 20, 22, 12, 23, 25 }, + { 22, 20, 30, 25, 23, 31 }, + { 10, 22, 21, 15, 28, 26 }, + { 21, 22, 30, 26, 28, 32 }, + { 13, 24, 25, 16, 27, 28 }, + { 25, 24, 31, 28, 27, 32 }, + { 17, 20, 23, 29, 30, 31 }, + { 18, 26, 21, 29, 32, 30 }, + { 19, 24, 27, 29, 31, 32 }, + { 22, 28, 25, 30, 32, 31 }, + + { 29, 30, 31, 32 }, +}; +HPRef_Struct reftet_1e_4v = +{ + HP_TET, + reftet_1e_4v_splitedges, + reftet_1e_4v_splitfaces, + 0, + reftet_1e_4v_newelstypes, + reftet_1e_4v_newels +}; + + + + + + + + + + + + + +// HP_TET_2EA_0V, // 2 edges connected +int reftet_2ea_0v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 0, 0, 0 } +}; +int reftet_2ea_0v_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_0v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_2ea_0v_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 5, 17, 7, 2, 9, 10 }, + { 6, 7, 17, 3, 13, 12 }, + { 17, 9, 12, 7, 10, 13 }, + { 7, 10, 13, 4 }, +}; +HPRef_Struct reftet_2ea_0v = +{ + HP_TET, + reftet_2ea_0v_splitedges, + reftet_2ea_0v_splitfaces, + 0, + reftet_2ea_0v_newelstypes, + reftet_2ea_0v_newels +}; + + + + + + +// HP_TET_2EA_1VA, // 2 edges connected +int reftet_2ea_1va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 0, 0, 0 } +}; +int reftet_2ea_1va_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_1va_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_2ea_1va_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 5, 17, 7, 8, 9, 10 }, + { 2, 8, 10, 9 }, + { 6, 7, 17, 3, 13, 12 }, + { 17, 9, 12, 7, 10, 13 }, + { 7, 10, 13, 4 }, +}; +HPRef_Struct reftet_2ea_1va = +{ + HP_TET, + reftet_2ea_1va_splitedges, + reftet_2ea_1va_splitfaces, + 0, + reftet_2ea_1va_newelstypes, + reftet_2ea_1va_newels +}; + + + + + + + + +// HP_TET_2EA_1VB, +int reftet_2ea_1vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 0, 0, 0 } +}; +int reftet_2ea_1vb_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_1vb_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_2ea_1vb_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 3, 11, 12, 13 }, + { 5, 17, 7, 2, 9, 10 }, + { 6, 7, 17, 11, 13, 12 }, + { 17, 9, 12, 7, 10, 13 }, + { 7, 10, 13, 4 }, +}; +HPRef_Struct reftet_2ea_1vb = +{ + HP_TET, + reftet_2ea_1vb_splitedges, + reftet_2ea_1vb_splitfaces, + 0, + reftet_2ea_1vb_newelstypes, + reftet_2ea_1vb_newels +}; + + + + + + +// HP_TET_2EA_1VC, // 2 edges connected +int reftet_2ea_1vc_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + // { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_2ea_1vc_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 2, 3, 4, 18 }, + { 3, 4, 2, 19 }, + { 4, 2, 3, 20 }, + { 0, 0, 0, 0 } + }; +int reftet_2ea_1vc_splitelements[][5] = + { + { 1, 2, 3, 4, 21 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_1vc_newelstypes[] = + { + HP_PYRAMID_EDGES, + // HP_TET_1E_1VA, + HP_TET_0E_1V, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_TET, HP_TET, HP_TET, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, + HP_PYRAMID, HP_PYRAMID, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_TET, + // HP_PRISM, + // HP_PRISM, + HP_NONE, + }; +int reftet_2ea_1vc_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + // { 3, 11, 12, 13 }, + { 4, 15, 14, 16 }, + { 5, 17, 7, 2, 9, 10 }, + { 6, 7, 17, 3, 13, 12 }, + + { 9, 10, 18, 21 }, + { 13, 12, 19, 21 }, + { 15, 16, 20, 21 }, + { 18, 20, 19, 21 }, + { 10, 15, 20, 18, 21 }, + { 13, 19, 20, 16, 21 }, + { 9, 18, 19, 12, 21 }, + + { 7, 13, 16, 14, 21 }, + { 7, 14, 15, 10, 21 }, + { 9, 12, 17, 21 }, + { 7, 10, 9, 17, 21 }, + { 7, 17, 12, 13, 21 }, + { 14, 16, 15, 21 }, + // { 17, 9, 12, 7, 10, 13 }, + // { 7, 10, 13, 14, 15, 16 }, +}; +HPRef_Struct reftet_2ea_1vc = +{ + HP_TET, + reftet_2ea_1vc_splitedges, + reftet_2ea_1vc_splitfaces, + reftet_2ea_1vc_splitelements, + reftet_2ea_1vc_newelstypes, + reftet_2ea_1vc_newels +}; + + + + + + + + + + + + +// HP_TET_2EA_2VA, +int reftet_2ea_2va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 0, 0, 0 } +}; +int reftet_2ea_2va_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_2va_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_2ea_2va_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 3, 11, 12, 13 }, + { 2, 8, 10, 9 }, + { 5, 17, 7, 8, 9, 10 }, + { 6, 7, 17, 11, 13, 12 }, + { 17, 9, 12, 7, 10, 13 }, + { 7, 10, 13, 4 }, +}; +HPRef_Struct reftet_2ea_2va = +{ + HP_TET, + reftet_2ea_2va_splitedges, + reftet_2ea_2va_splitfaces, + 0, + reftet_2ea_2va_newelstypes, + reftet_2ea_2va_newels +}; + + + + + + + + + + + +// HP_TET_2EA_2VB, // 2 edges connected +int reftet_2ea_2vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + // { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_2ea_2vb_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 2, 3, 4, 18 }, + { 3, 4, 2, 19 }, + { 4, 2, 3, 20 }, + { 0, 0, 0, 0 } + }; +int reftet_2ea_2vb_splitelements[][5] = + { + { 1, 2, 3, 4, 21 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_2vb_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_TET_0E_1V, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_TET, HP_TET, HP_TET, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, + HP_PYRAMID, HP_PYRAMID, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_TET, + // HP_PRISM, + // HP_PRISM, + HP_NONE, + }; +int reftet_2ea_2vb_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 2, 8, 10, 9 }, + // { 3, 11, 12, 13 }, + { 4, 15, 14, 16 }, + { 5, 17, 7, 8, 9, 10 }, + { 6, 7, 17, 3, 13, 12 }, + + { 9, 10, 18, 21 }, + { 13, 12, 19, 21 }, + { 15, 16, 20, 21 }, + { 18, 20, 19, 21 }, + { 10, 15, 20, 18, 21 }, + { 13, 19, 20, 16, 21 }, + { 9, 18, 19, 12, 21 }, + + { 7, 13, 16, 14, 21 }, + { 7, 14, 15, 10, 21 }, + { 9, 12, 17, 21 }, + { 7, 10, 9, 17, 21 }, + { 7, 17, 12, 13, 21 }, + { 14, 16, 15, 21 }, + // { 17, 9, 12, 7, 10, 13 }, + // { 7, 10, 13, 14, 15, 16 }, +}; +HPRef_Struct reftet_2ea_2vb = +{ + HP_TET, + reftet_2ea_2vb_splitedges, + reftet_2ea_2vb_splitfaces, + reftet_2ea_2vb_splitelements, + reftet_2ea_2vb_newelstypes, + reftet_2ea_2vb_newels +}; + + + + + + + + + + +// HP_TET_2EA_2VC, // 2 edges connected +int reftet_2ea_2vc_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + // { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_2ea_2vc_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 2, 3, 4, 18 }, + { 3, 4, 2, 19 }, + { 4, 2, 3, 20 }, + { 0, 0, 0, 0 } + }; +int reftet_2ea_2vc_splitelements[][5] = + { + { 1, 2, 3, 4, 21 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_2vc_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_TET_0E_1V, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_TET, HP_TET, HP_TET, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, + HP_PYRAMID, HP_PYRAMID, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_TET, + // HP_PRISM, + // HP_PRISM, + HP_NONE, + }; +int reftet_2ea_2vc_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + // { 2, 8, 10, 9 }, + { 3, 11, 12, 13 }, + { 4, 15, 14, 16 }, + { 5, 17, 7, 2, 9, 10 }, + { 6, 7, 17, 11, 13, 12 }, + + { 9, 10, 18, 21 }, + { 13, 12, 19, 21 }, + { 15, 16, 20, 21 }, + { 18, 20, 19, 21 }, + { 10, 15, 20, 18, 21 }, + { 13, 19, 20, 16, 21 }, + { 9, 18, 19, 12, 21 }, + + { 7, 13, 16, 14, 21 }, + { 7, 14, 15, 10, 21 }, + { 9, 12, 17, 21 }, + { 7, 10, 9, 17, 21 }, + { 7, 17, 12, 13, 21 }, + { 14, 16, 15, 21 }, + // { 17, 9, 12, 7, 10, 13 }, + // { 7, 10, 13, 14, 15, 16 }, +}; +HPRef_Struct reftet_2ea_2vc = +{ + HP_TET, + reftet_2ea_2vc_splitedges, + reftet_2ea_2vc_splitfaces, + reftet_2ea_2vc_splitelements, + reftet_2ea_2vc_newelstypes, + reftet_2ea_2vc_newels +}; + + + + + + + + +// HP_TET_2EA_3V, // 2 edges connected +int reftet_2ea_3v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_2ea_3v_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 2, 3, 4, 18 }, + { 3, 4, 2, 19 }, + { 4, 2, 3, 20 }, + { 0, 0, 0, 0 } + }; +int reftet_2ea_3v_splitelements[][5] = + { + { 1, 2, 3, 4, 21 }, + { 0, 0, 0, 0 } + }; +HPREF_ELEMENT_TYPE reftet_2ea_3v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_TET_0E_1V, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_TET, HP_TET, HP_TET, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_PYRAMID, + HP_PYRAMID, HP_PYRAMID, HP_TET, + HP_PYRAMID, HP_PYRAMID, HP_TET, + // HP_PRISM, + // HP_PRISM, + HP_NONE, + }; +int reftet_2ea_3v_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 2, 8, 10, 9 }, + { 3, 11, 12, 13 }, + { 4, 15, 14, 16 }, + { 5, 17, 7, 8, 9, 10 }, + { 6, 7, 17, 11, 13, 12 }, + + { 9, 10, 18, 21 }, + { 13, 12, 19, 21 }, + { 15, 16, 20, 21 }, + { 18, 20, 19, 21 }, + { 10, 15, 20, 18, 21 }, + { 13, 19, 20, 16, 21 }, + { 9, 18, 19, 12, 21 }, + + { 7, 13, 16, 14, 21 }, + { 7, 14, 15, 10, 21 }, + { 9, 12, 17, 21 }, + { 7, 10, 9, 17, 21 }, + { 7, 17, 12, 13, 21 }, + { 14, 16, 15, 21 }, + // { 17, 9, 12, 7, 10, 13 }, + // { 7, 10, 13, 14, 15, 16 }, +}; +HPRef_Struct reftet_2ea_3v = +{ + HP_TET, + reftet_2ea_3v_splitedges, + reftet_2ea_3v_splitfaces, + reftet_2ea_3v_splitelements, + reftet_2ea_3v_newelstypes, + reftet_2ea_3v_newels +}; + + + + + + + +// HP_TET_2EB_0V, // 2 opposite edges +int reftet_2eb_0v_splitedges[][3] = +{ + { 1, 3, 5 }, + { 1, 4, 6 }, + { 2, 3, 7 }, + { 2, 4, 8 }, + { 3, 1, 9 }, + { 3, 2, 10 }, + { 4, 1, 11 }, + { 4, 2, 12 }, + { 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_0v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_HEX, + HP_NONE, + }; +int reftet_2eb_0v_newels[][8] = +{ + { 1, 5, 6, 2, 7, 8 }, + { 3, 9, 10, 4, 11, 12 }, + { 6, 11, 12, 8, 5, 9, 10, 7 }, +}; +HPRef_Struct reftet_2eb_0v = +{ + HP_TET, + reftet_2eb_0v_splitedges, + 0, 0, + reftet_2eb_0v_newelstypes, + reftet_2eb_0v_newels +}; + + +// HP_TET_2EB_1V, // V1 + + +// HP_TET_2EB_1V, // 2 opposite edges, V1 +int reftet_2eb_1v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_1v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_HEX, + HP_NONE, + }; +int reftet_2eb_1v_newels[][8] = +{ + { 5, 6, 7, 2, 9, 10 }, + { 4, 15, 14, 3, 12, 11 }, + { 1, 5, 6, 7 }, + // { 2, 8, 10, 9 }, + // { 3, 13, 11, 12 }, + // { 4, 16, 15, 14 }, + { 7, 14, 15, 10, 6, 11, 12, 9 } +}; +HPRef_Struct reftet_2eb_1v = +{ + HP_TET, + reftet_2eb_1v_splitedges, + 0, 0, + reftet_2eb_1v_newelstypes, + reftet_2eb_1v_newels +}; + + + +// HP_TET_2EB_2VA, // 2 opposite edges, V1,2 +int reftet_2eb_2va_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_2va_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_HEX, + HP_NONE, + }; +int reftet_2eb_2va_newels[][8] = +{ + { 5, 6, 7, 8, 9, 10 }, + { 4, 15, 14, 3, 12, 11 }, + { 1, 5, 6, 7 }, + { 2, 8, 10, 9 }, + // { 3, 13, 11, 12 }, + // { 4, 16, 15, 14 }, + { 7, 14, 15, 10, 6, 11, 12, 9 } +}; +HPRef_Struct reftet_2eb_2va = +{ + HP_TET, + reftet_2eb_2va_splitedges, + 0, 0, + reftet_2eb_2va_newelstypes, + reftet_2eb_2va_newels +}; + + +// HP_TET_2EB_2VB, // V1,3 +int reftet_2eb_2vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_2vb_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_HEX, + HP_NONE, + }; +int reftet_2eb_2vb_newels[][8] = +{ + { 5, 6, 7, 2, 9, 10 }, + { 4, 15, 14, 13, 12, 11 }, + { 1, 5, 6, 7 }, + // { 2, 8, 10, 9 }, + { 3, 13, 11, 12 }, + // { 4, 16, 15, 14 }, + { 7, 14, 15, 10, 6, 11, 12, 9 } +}; +HPRef_Struct reftet_2eb_2vb = +{ + HP_TET, + reftet_2eb_2vb_splitedges, + 0, 0, + reftet_2eb_2vb_newelstypes, + reftet_2eb_2vb_newels +}; + + + + +// HP_TET_2EB_2VC, // V1,4 +int reftet_2eb_2vc_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_2vc_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_HEX, + HP_NONE, + }; +int reftet_2eb_2vc_newels[][8] = +{ + { 5, 6, 7, 2, 9, 10 }, + { 16, 15, 14, 3, 12, 11 }, + { 1, 5, 6, 7 }, + // { 2, 8, 10, 9 }, + // { 3, 13, 11, 12 }, + { 4, 16, 15, 14 }, + { 7, 14, 15, 10, 6, 11, 12, 9 } +}; +HPRef_Struct reftet_2eb_2vc = +{ + HP_TET, + reftet_2eb_2vc_splitedges, + 0, 0, + reftet_2eb_2vc_newelstypes, + reftet_2eb_2vc_newels +}; + + + + + + +// HP_TET_2EB_3V, // V1,2,3 +int reftet_2eb_3v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_3v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_HEX, + HP_NONE, + }; +int reftet_2eb_3v_newels[][8] = +{ + { 5, 6, 7, 8, 9, 10 }, + { 4, 15, 14, 13, 12, 11 }, + { 1, 5, 6, 7 }, + { 2, 8, 10, 9 }, + { 3, 13, 11, 12 }, + // { 4, 16, 15, 14 }, + { 7, 14, 15, 10, 6, 11, 12, 9 } +}; +HPRef_Struct reftet_2eb_3v = +{ + HP_TET, + reftet_2eb_3v_splitedges, + 0, 0, + reftet_2eb_3v_newelstypes, + reftet_2eb_3v_newels +}; + + + + + + +// HP_TET_2EB_4V, // 2 opposite edges +int reftet_2eb_4v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftet_2eb_4v_newelstypes[] = + { + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_HEX, + HP_NONE, + }; +int reftet_2eb_4v_newels[][8] = +{ + { 5, 6, 7, 8, 9, 10 }, + { 16, 15, 14, 13, 12, 11 }, + { 1, 5, 6, 7 }, + { 2, 8, 10, 9 }, + { 3, 13, 11, 12 }, + { 4, 16, 15, 14 }, + { 7, 14, 15, 10, 6, 11, 12, 9 } +}; +HPRef_Struct reftet_2eb_4v = +{ + HP_TET, + reftet_2eb_4v_splitedges, + 0, 0, + reftet_2eb_4v_newelstypes, + reftet_2eb_4v_newels +}; + + + + + + + + + + + + + + + + + +// HP_TET_3EA_0V, +int reftet_3ea_0v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 4, 2, 12 }, + { 4, 3, 13 }, + { 0, 0, 0 } +}; +int reftet_3ea_0v_splitfaces[][4] = + { + { 1, 2, 3, 14 }, + { 1, 2, 4, 15 }, + { 1, 3, 4, 16 }, + { 2, 3, 4, 17 }, + { 3, 4, 2, 18 }, + { 4, 2, 3, 19 }, + { 0, 0, 0, 0 } + }; +int reftet_3ea_0v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3ea_0v_newelstypes[] = + { + HP_HEX_3E_0V, + HP_HEX_1E_0V, + HP_HEX_1E_0V, + HP_HEX_1E_0V, + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_3ea_0v_newels[][8] = +{ + { 1, 5, 14, 6, 7, 15, 20, 16 }, + { 5, 2, 8, 14, 15, 9, 17, 20 }, + { 3, 6, 14, 10, 11, 16, 20, 18 }, + { 7, 4, 12, 15, 16, 13, 19, 20 }, + { 11, 13, 16, 18, 19, 20 }, + { 15, 12, 9, 20, 19, 17 }, + { 8, 10, 14, 17, 18, 20 }, + { 20, 17, 18, 19 }, +}; +HPRef_Struct reftet_3ea_0v = +{ + HP_TET, + reftet_3ea_0v_splitedges, + reftet_3ea_0v_splitfaces, + reftet_3ea_0v_splitelements, + reftet_3ea_0v_newelstypes, + reftet_3ea_0v_newels +}; + + + + + + + + + + +// HP_TET_3EA_1V, +int reftet_3ea_1v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 4, 2, 12 }, + { 4, 3, 13 }, + { 2, 1, 21 }, + { 3, 1, 22 }, + { 4, 1, 23 }, + { 0, 0, 0 } +}; +int reftet_3ea_1v_splitfaces[][4] = + { + { 1, 2, 3, 14 }, + { 1, 2, 4, 15 }, + { 1, 3, 4, 16 }, + { 2, 3, 4, 17 }, + { 3, 4, 2, 18 }, + { 4, 2, 3, 19 }, + { 0, 0, 0, 0 } + }; +int reftet_3ea_1v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3ea_1v_newelstypes[] = + { + HP_HEX_3E_0V, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_3ea_1v_newels[][8] = +{ + { 1, 5, 14, 6, 7, 15, 20, 16 }, + + { 2, 21, 9, 8 }, + { 5, 14, 15, 21, 8, 9 }, + { 15, 14, 20, 9, 8, 17 }, + // { 3, 22, 10, 11 }, + // { 6, 16, 14, 22, 11, 10 }, + { 6, 16, 14, 3, 11, 10 }, + { 14, 16, 20, 10, 11, 18 }, + // { 4, 23, 13, 12 }, + // { 7, 15, 16, 23, 12, 13 }, + { 7, 15, 16, 4, 12, 13 }, + { 16, 15, 20, 13, 12, 19 }, + + { 11, 13, 16, 18, 19, 20 }, + { 15, 12, 9, 20, 19, 17 }, + { 8, 10, 14, 17, 18, 20 }, + { 20, 17, 18, 19 }, +}; +HPRef_Struct reftet_3ea_1v = +{ + HP_TET, + reftet_3ea_1v_splitedges, + reftet_3ea_1v_splitfaces, + reftet_3ea_1v_splitelements, + reftet_3ea_1v_newelstypes, + reftet_3ea_1v_newels +}; + + + + + + + + + + +// HP_TET_3EA_2V, +int reftet_3ea_2v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 4, 2, 12 }, + { 4, 3, 13 }, + { 2, 1, 21 }, + { 3, 1, 22 }, + { 4, 1, 23 }, + { 0, 0, 0 } +}; +int reftet_3ea_2v_splitfaces[][4] = + { + { 1, 2, 3, 14 }, + { 1, 2, 4, 15 }, + { 1, 3, 4, 16 }, + { 2, 3, 4, 17 }, + { 3, 4, 2, 18 }, + { 4, 2, 3, 19 }, + { 0, 0, 0, 0 } + }; +int reftet_3ea_2v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3ea_2v_newelstypes[] = + { + HP_HEX_3E_0V, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_3ea_2v_newels[][8] = +{ + { 1, 5, 14, 6, 7, 15, 20, 16 }, + + { 2, 21, 9, 8 }, + { 5, 14, 15, 21, 8, 9 }, + { 15, 14, 20, 9, 8, 17 }, + { 3, 22, 10, 11 }, + { 6, 16, 14, 22, 11, 10 }, + { 14, 16, 20, 10, 11, 18 }, + // { 4, 23, 13, 12 }, + { 7, 15, 16, 4, 12, 13 }, + { 16, 15, 20, 13, 12, 19 }, + + { 11, 13, 16, 18, 19, 20 }, + { 15, 12, 9, 20, 19, 17 }, + { 8, 10, 14, 17, 18, 20 }, + { 20, 17, 18, 19 }, +}; +HPRef_Struct reftet_3ea_2v = +{ + HP_TET, + reftet_3ea_2v_splitedges, + reftet_3ea_2v_splitfaces, + reftet_3ea_2v_splitelements, + reftet_3ea_2v_newelstypes, + reftet_3ea_2v_newels +}; + + + + + + + + +// HP_TET_3EA_3V, +int reftet_3ea_3v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 2, 10 }, + { 3, 4, 11 }, + { 4, 2, 12 }, + { 4, 3, 13 }, + { 2, 1, 21 }, + { 3, 1, 22 }, + { 4, 1, 23 }, + { 0, 0, 0 } +}; +int reftet_3ea_3v_splitfaces[][4] = + { + { 1, 2, 3, 14 }, + { 1, 2, 4, 15 }, + { 1, 3, 4, 16 }, + { 2, 3, 4, 17 }, + { 3, 4, 2, 18 }, + { 4, 2, 3, 19 }, + { 0, 0, 0, 0 } + }; +int reftet_3ea_3v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3ea_3v_newelstypes[] = + { + HP_HEX_3E_0V, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + + HP_PRISM, + HP_PRISM, + HP_PRISM, + HP_TET, + HP_NONE, + }; +int reftet_3ea_3v_newels[][8] = +{ + { 1, 5, 14, 6, 7, 15, 20, 16 }, + + { 2, 21, 9, 8 }, + { 5, 14, 15, 21, 8, 9 }, + { 15, 14, 20, 9, 8, 17 }, + { 3, 22, 10, 11 }, + { 6, 16, 14, 22, 11, 10 }, + { 14, 16, 20, 10, 11, 18 }, + { 4, 23, 13, 12 }, + { 7, 15, 16, 23, 12, 13 }, + { 16, 15, 20, 13, 12, 19 }, + + { 11, 13, 16, 18, 19, 20 }, + { 15, 12, 9, 20, 19, 17 }, + { 8, 10, 14, 17, 18, 20 }, + { 20, 17, 18, 19 }, +}; +HPRef_Struct reftet_3ea_3v = +{ + HP_TET, + reftet_3ea_3v_splitedges, + reftet_3ea_3v_splitfaces, + reftet_3ea_3v_splitelements, + reftet_3ea_3v_newelstypes, + reftet_3ea_3v_newels +}; + + + + + + + +// HP_TET_3EV_0V, +int reftet_3eb_0v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + // { 3, 2, 12 }, + { 3, 4, 13 }, + // { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_3eb_0v_splitfaces[][4] = + { + { 1, 2, 4, 17 }, + { 2, 1, 3, 18 }, + { 0, 0, 0, 0 } + }; +int reftet_3eb_0v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3eb_0v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PYRAMID_EDGES, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PYRAMID, + HP_PYRAMID, + HP_TET, + HP_TET, + HP_PYRAMID, + HP_PYRAMID, + HP_PYRAMID, + HP_NONE, + }; +int reftet_3eb_0v_newels[][8] = +{ + { 1, 7, 17, 5, 6 }, + { 2, 9, 18, 8, 10 }, + // { 3, 12, 13, 11 }, + // { 4, 14, 16, 15 }, + { 5, 6, 17, 8, 18, 10 }, + { 7, 17, 6, 4, 15, 16 }, + { 9, 18, 10, 3, 11, 13 }, + + { 10, 15, 16, 13, 20 }, + { 6, 11, 13, 16, 20 }, + { 10, 17, 15, 20 }, + { 6, 18, 11, 20 }, + { 6, 17, 10, 18, 20 }, + { 6, 16, 15, 17, 20 }, + { 18, 10, 13, 11, 20 }, +}; +HPRef_Struct reftet_3eb_0v = +{ + HP_TET, + reftet_3eb_0v_splitedges, + reftet_3eb_0v_splitfaces, + reftet_3eb_0v_splitelements, + reftet_3eb_0v_newelstypes, + reftet_3eb_0v_newels +}; + + + + + + + + + +// HP_TET_3EV_1V, +int reftet_3eb_1v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + // { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_3eb_1v_splitfaces[][4] = + { + { 1, 2, 4, 17 }, + { 2, 1, 3, 18 }, + { 0, 0, 0, 0 } + }; +int reftet_3eb_1v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3eb_1v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PYRAMID, + HP_PYRAMID, + HP_TET, + HP_TET, + HP_PYRAMID, + HP_PYRAMID, + HP_PYRAMID, + HP_NONE, + }; +int reftet_3eb_1v_newels[][8] = +{ + { 1, 7, 17, 5, 6 }, + { 2, 9, 18, 8, 10 }, + { 3, 12, 13, 11 }, + // { 4, 14, 16, 15 }, + { 5, 6, 17, 8, 18, 10 }, + { 7, 17, 6, 4, 15, 16 }, + { 9, 18, 10, 12, 11, 13 }, + + { 10, 15, 16, 13, 20 }, + { 6, 11, 13, 16, 20 }, + { 10, 17, 15, 20 }, + { 6, 18, 11, 20 }, + { 6, 17, 10, 18, 20 }, + { 6, 16, 15, 17, 20 }, + { 18, 10, 13, 11, 20 }, +}; +HPRef_Struct reftet_3eb_1v = +{ + HP_TET, + reftet_3eb_1v_splitedges, + reftet_3eb_1v_splitfaces, + reftet_3eb_1v_splitelements, + reftet_3eb_1v_newelstypes, + reftet_3eb_1v_newels +}; + + + + + + + + +// HP_TET_3EV_2V, +int reftet_3eb_2v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_3eb_2v_splitfaces[][4] = + { + { 1, 2, 4, 17 }, + { 2, 1, 3, 18 }, + { 0, 0, 0, 0 } + }; +int reftet_3eb_2v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3eb_2v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PYRAMID, + HP_PYRAMID, + HP_TET, + HP_TET, + HP_PYRAMID, + HP_PYRAMID, + HP_PYRAMID, + HP_NONE, + }; +int reftet_3eb_2v_newels[][8] = +{ + { 1, 7, 17, 5, 6 }, + { 2, 9, 18, 8, 10 }, + { 3, 12, 13, 11 }, + { 4, 14, 16, 15 }, + { 5, 6, 17, 8, 18, 10 }, + { 7, 17, 6, 14, 15, 16 }, + { 9, 18, 10, 12, 11, 13 }, + + { 10, 15, 16, 13, 20 }, + { 6, 11, 13, 16, 20 }, + { 10, 17, 15, 20 }, + { 6, 18, 11, 20 }, + { 6, 17, 10, 18, 20 }, + { 6, 16, 15, 17, 20 }, + { 18, 10, 13, 11, 20 }, +}; +HPRef_Struct reftet_3eb_2v = +{ + HP_TET, + reftet_3eb_2v_splitedges, + reftet_3eb_2v_splitfaces, + reftet_3eb_2v_splitelements, + reftet_3eb_2v_newelstypes, + reftet_3eb_2v_newels +}; + + + + + + + + + + + + + +// HP_TET_3EC_0V, +int reftet_3ec_0v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + // { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + // { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_3ec_0v_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 2, 1, 4, 18 }, + { 0, 0, 0, 0 } + }; +int reftet_3ec_0v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3ec_0v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PYRAMID_EDGES, + // HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PYRAMID, + HP_PYRAMID, + HP_TET, + HP_TET, + HP_PYRAMID, + HP_PYRAMID, + HP_PYRAMID, + HP_NONE, + }; +int reftet_3ec_0v_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 2, 8, 18, 10, 9 }, + // { 3, 11, 12, 13 }, + // { 4, 15, 14, 16 }, + { 5, 17, 7, 8, 9, 18 }, + { 6, 7, 17, 3, 13, 12 }, + { 10, 9, 18, 4, 16, 14 }, + + { 9, 16, 13, 12, 20 }, + { 7, 13, 16, 14, 20 }, + { 7, 14, 18, 20 }, + { 9, 12, 17, 20 }, + { 17, 7, 18, 9, 20 }, + { 7, 17, 12, 13, 20 }, + { 9, 18, 14, 16, 20 }, +}; +HPRef_Struct reftet_3ec_0v = +{ + HP_TET, + reftet_3ec_0v_splitedges, + reftet_3ec_0v_splitfaces, + reftet_3ec_0v_splitelements, + reftet_3ec_0v_newelstypes, + reftet_3ec_0v_newels +}; + + + + + + + + + +// HP_TET_3EC_1V, +int reftet_3ec_1v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + // { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_3ec_1v_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 2, 1, 4, 18 }, + { 0, 0, 0, 0 } + }; +int reftet_3ec_1v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3ec_1v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + // HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PYRAMID, + HP_PYRAMID, + HP_TET, + HP_TET, + HP_PYRAMID, + HP_PYRAMID, + HP_PYRAMID, + HP_NONE, + }; +int reftet_3ec_1v_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 2, 8, 18, 10, 9 }, + { 3, 11, 12, 13 }, + // { 4, 15, 14, 16 }, + { 5, 17, 7, 8, 9, 18 }, + { 6, 7, 17, 11, 13, 12 }, + { 10, 9, 18, 4, 16, 14 }, + + { 9, 16, 13, 12, 20 }, + { 7, 13, 16, 14, 20 }, + { 7, 14, 18, 20 }, + { 9, 12, 17, 20 }, + { 17, 7, 18, 9, 20 }, + { 7, 17, 12, 13, 20 }, + { 9, 18, 14, 16, 20 }, +}; +HPRef_Struct reftet_3ec_1v = +{ + HP_TET, + reftet_3ec_1v_splitedges, + reftet_3ec_1v_splitfaces, + reftet_3ec_1v_splitelements, + reftet_3ec_1v_newelstypes, + reftet_3ec_1v_newels +}; + + + + + + + + +// HP_TET_3EC_2V, +int reftet_3ec_2v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 2, 3, 9 }, + { 2, 4, 10 }, + { 3, 1, 11 }, + { 3, 2, 12 }, + { 3, 4, 13 }, + { 4, 1, 14 }, + { 4, 2, 15 }, + { 4, 3, 16 }, + { 0, 0, 0 } +}; +int reftet_3ec_2v_splitfaces[][4] = + { + { 1, 2, 3, 17 }, + { 2, 1, 4, 18 }, + { 0, 0, 0, 0 } + }; +int reftet_3ec_2v_splitelements[][5] = + { + { 1, 2, 3, 4, 20 }, + { 0 }, + }; + +HPREF_ELEMENT_TYPE reftet_3ec_2v_newelstypes[] = + { + HP_PYRAMID_EDGES, + HP_PYRAMID_EDGES, + HP_TET_1E_1VA, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + HP_PRISM_SINGEDGE, + + HP_PYRAMID, + HP_PYRAMID, + HP_TET, + HP_TET, + HP_PYRAMID, + HP_PYRAMID, + HP_PYRAMID, + HP_NONE, + }; +int reftet_3ec_2v_newels[][8] = +{ + { 1, 5, 17, 6, 7 }, + { 2, 8, 18, 10, 9 }, + { 3, 11, 12, 13 }, + { 4, 15, 14, 16 }, + { 5, 17, 7, 8, 9, 18 }, + { 6, 7, 17, 11, 13, 12 }, + { 10, 9, 18, 15, 16, 14 }, + + { 9, 16, 13, 12, 20 }, + { 7, 13, 16, 14, 20 }, + { 7, 14, 18, 20 }, + { 9, 12, 17, 20 }, + { 17, 7, 18, 9, 20 }, + { 7, 17, 12, 13, 20 }, + { 9, 18, 14, 16, 20 }, +}; +HPRef_Struct reftet_3ec_2v = +{ + HP_TET, + reftet_3ec_2v_splitedges, + reftet_3ec_2v_splitfaces, + reftet_3ec_2v_splitelements, + reftet_3ec_2v_newelstypes, + reftet_3ec_2v_newels +}; + + + + + + + + + + +/* ************************ 1 singular face ******************** */ + + +// HP_TET_1F_0E_0V +int reftet_1f_0e_0v_splitedges[][3] = +{ + { 2, 1, 5 }, + { 3, 1, 6 }, + { 4, 1, 7 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_1f_0e_0v_newelstypes[] = +{ + HP_PRISM_1FA_0E_0V, + HP_TET, + HP_NONE, +}; +int reftet_1f_0e_0v_newels[][8] = +{ + { 3, 2, 4, 6, 5, 7 }, + { 5, 7, 6, 1 } +}; +HPRef_Struct reftet_1f_0e_0v = +{ + HP_TET, + reftet_1f_0e_0v_splitedges, + 0, 0, + reftet_1f_0e_0v_newelstypes, + reftet_1f_0e_0v_newels +}; + + + + + +// HP_TET_1F_0E_1VA ... singular vertex in face +int reftet_1f_0e_1va_splitedges[][3] = +{ + { 2, 1, 5 }, + { 2, 3, 6 }, + { 2, 4, 7 }, + { 3, 1, 8 }, + { 4, 1, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_1f_0e_1va_newelstypes[] = +{ + HP_HEX_1F_0E_0V, + HP_TET_1F_0E_1VA, + HP_TET, + HP_NONE, +}; +int reftet_1f_0e_1va_newels[][8] = +{ + { 3, 6, 7, 4, 8, 5, 5, 9 }, + { 5, 2, 6, 7 }, + { 5, 9, 8, 1 }, +}; +HPRef_Struct reftet_1f_0e_1va = +{ + HP_TET, + reftet_1f_0e_1va_splitedges, + 0, 0, + reftet_1f_0e_1va_newelstypes, + reftet_1f_0e_1va_newels +}; + + + + + +// HP_TET_1F_0E_1VB ... singular vertex not in face +int reftet_1f_0e_1vb_splitedges[][3] = +{ + { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 1, 8 }, + { 3, 1, 9 }, + { 4, 1, 10 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftet_1f_0e_1vb_newelstypes[] = +{ + HP_PRISM_1FA_0E_0V, + HP_PRISM, + HP_TET_0E_1V, + HP_NONE, +}; +int reftet_1f_0e_1vb_newels[][8] = +{ + { 2, 4, 3, 8, 10, 9 }, + { 8, 10, 9, 5, 7, 6 }, + { 1, 5, 6, 7 }, +}; +HPRef_Struct reftet_1f_0e_1vb = +{ + HP_TET, + reftet_1f_0e_1vb_splitedges, + 0, 0, + reftet_1f_0e_1vb_newelstypes, + reftet_1f_0e_1vb_newels +}; + + + + + + + + +// HP_TET_1F_1EA_0V ... sing edge is 1..2 +int reftet_1f_1ea_0v_splitedges[][3] = +{ + { 1, 3, 5 }, + { 1, 4, 6 }, + { 2, 1, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 1, 10 }, + { 4, 1, 11 }, + { 0, 0, 0 } +}; + +int reftet_1f_1ea_0v_splitfaces[][4] = + { + { 2, 1, 3, 12 }, + { 2, 1, 4, 13 }, + { 0, 0, 0, 0 } + }; + + +HPREF_ELEMENT_TYPE reftet_1f_1ea_0v_newelstypes[] = +{ + HP_HEX_1F_0E_0V, + // HP_PRISM, + HP_PYRAMID_1FB_0E_1VA, + HP_TET_1E_1VA, + HP_PRISM_SINGEDGE, + HP_PRISM, + HP_NONE, +}; +int reftet_1f_1ea_0v_newels[][8] = +{ + { 3, 8, 9, 4, 10, 12, 13, 11 }, + // { 2, 9, 8, 7, 13, 12 }, + { 8, 9, 13, 12, 2 }, + { 2, 7, 13, 12 }, + { 7, 13, 12, 1, 6, 5 }, + { 6, 11, 13, 5, 10, 12 } +}; +HPRef_Struct reftet_1f_1ea_0v = +{ + HP_TET, + reftet_1f_1ea_0v_splitedges, + reftet_1f_1ea_0v_splitfaces, + 0, + reftet_1f_1ea_0v_newelstypes, + reftet_1f_1ea_0v_newels +}; + + + + + + + + +// HP_TET_1F_1EB_0V singular edge in face, edge is 2-3 +int reftet_1f_1eb_0v_splitedges[][3] = +{ + { 2, 1, 5 }, + { 2, 4, 6 }, + { 3, 1, 7 }, + { 3, 4, 8 }, + { 4, 1, 9 }, + { 0, 0, 0 } +}; + + +HPREF_ELEMENT_TYPE reftet_1f_1eb_0v_newelstypes[] = +{ + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FA_0E_0V, + HP_TET, + HP_NONE, +}; +int reftet_1f_1eb_0v_newels[][8] = +{ + // { 2, 5, 6, 3, 7, 8 }, + { 3, 8, 7, 2, 6, 5 }, + { 6, 4, 8, 5, 9, 7 }, + { 5, 9, 7, 1} +}; +HPRef_Struct reftet_1f_1eb_0v = +{ + HP_TET, + reftet_1f_1eb_0v_splitedges, + 0, 0, + reftet_1f_1eb_0v_newelstypes, + reftet_1f_1eb_0v_newels +}; + + + + + + + + + + +/* ************************ 2 singular faces ******************** */ + + +// HP_TET_2F_0E_0V +int reftet_2f_0e_0v_splitedges[][3] = +{ + { 1, 2, 5 }, + { 2, 1, 6 }, + { 3, 1, 7 }, + { 3, 2, 8 }, + { 4, 1, 9 }, + { 4, 2, 10 }, + { 0, 0, 0 } +}; + +int reftet_2f_0e_0v_splitfaces[][4] = + { + { 3, 1, 2, 11 }, + { 4, 1, 2, 12 }, + { 0, 0, 0, 0 } + }; + + +HPREF_ELEMENT_TYPE reftet_2f_0e_0v_newelstypes[] = +{ + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FA_0E_0V, + HP_PRISM_1FB_1EA_0V, + HP_PRISM_1FB_1EA_0V, + HP_TET, + HP_NONE, +}; +int reftet_2f_0e_0v_newels[][8] = +{ + { 2, 10, 8, 6, 12, 11 }, + { 1, 7, 9, 5, 11, 12 }, + // { 3, 11, 8, 4, 12, 10 }, + { 4, 10, 12, 3, 8, 11 }, + { 3, 7, 11, 4, 9, 12 }, + { 5, 6, 11, 12 } +}; +HPRef_Struct reftet_2f_0e_0v = +{ + HP_TET, + reftet_2f_0e_0v_splitedges, + reftet_2f_0e_0v_splitfaces, + 0, + reftet_2f_0e_0v_newelstypes, + reftet_2f_0e_0v_newels +}; + diff --git a/libsrc/meshing/hpref_trig.hpp b/libsrc/meshing/hpref_trig.hpp new file mode 100644 index 00000000..3676ad0f --- /dev/null +++ b/libsrc/meshing/hpref_trig.hpp @@ -0,0 +1,776 @@ + + +// HP_TRIG +int reftrig_splitedges[][3] = +{ + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_newelstypes[] = +{ + HP_TRIG, + HP_NONE, +}; +int reftrig_newels[][8] = +{ + { 1, 2, 3 }, +}; +HPRef_Struct reftrig = +{ + HP_TRIG, + reftrig_splitedges, + 0, 0, + reftrig_newelstypes, + reftrig_newels +}; + + + +// HP_TRIG_SINGCORNER +int reftrig_singcorner_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singcorner_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_QUAD, + HP_NONE, +}; +int reftrig_singcorner_newels[][8] = +{ + { 1, 4, 5 }, + { 2, 3, 5, 4 }, +}; +HPRef_Struct reftrig_singcorner = +{ + HP_TRIG, + reftrig_singcorner_splitedges, + 0, 0, + reftrig_singcorner_newelstypes, + reftrig_singcorner_newels +}; + + +/* +// HP_TRIG_SINGCORNER, trigs only +int reftrig_singcorner_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singcorner_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_TRIG, + HP_TRIG, + HP_NONE, +}; +int reftrig_singcorner_newels[][8] = +{ + { 1, 4, 5 }, + { 4, 2, 5 }, + { 5, 2, 3 }, +}; +HPRef_Struct reftrig_singcorner = +{ + HP_TRIG, + reftrig_singcorner_splitedges, + 0, 0, + reftrig_singcorner_newelstypes, + reftrig_singcorner_newels +}; +*/ + + + + + +// HP_TRIG_SINGCORNER12 +int reftrig_singcorner12_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 1, 6 }, + { 2, 3, 7 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singcorner12_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD, + HP_TRIG, + HP_NONE, +}; +int reftrig_singcorner12_newels[][8] = +{ + { 1, 4, 5 }, + { 2, 7, 6 }, + { 4, 6, 7, 5 }, + { 5, 7, 3 }, +}; +HPRef_Struct reftrig_singcorner12 = +{ + HP_TRIG, + reftrig_singcorner12_splitedges, + 0, 0, + reftrig_singcorner12_newelstypes, + reftrig_singcorner12_newels +}; + + + + +// HP_TRIG_SINGCORNER123_2D +int reftrig_singcorner123_2D_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 1, 6 }, + { 2, 3, 7 }, + { 3, 1, 8 }, + { 3, 2, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singcorner123_2D_newelstypes[] = +{ + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_TRIG_SINGCORNER, + HP_QUAD, + HP_QUAD, + HP_NONE, +}; +int reftrig_singcorner123_2D_newels[][8] = +{ + { 1, 4, 5 }, + { 2, 7, 6 }, + { 3, 8, 9 }, + { 4, 6, 8, 5 }, + { 6, 7, 9, 8 }, +}; +HPRef_Struct reftrig_singcorner123_2D = +{ + HP_TRIG, + reftrig_singcorner123_2D_splitedges, + 0, 0, + reftrig_singcorner123_2D_newelstypes, + reftrig_singcorner123_2D_newels +}; + + + + + + +// HP_TRIG_SINGCORNER123 +int reftrig_singcorner123_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 1, 6 }, + { 2, 3, 7 }, + { 3, 1, 8 }, + { 3, 2, 9 }, + { 0, 0, 0 } +}; + +int reftrig_singcorner123_splitfaces[][4] = +{ + { 1, 2, 3, 10 }, + { 2, 3, 1, 11 }, + { 3, 1, 2, 12 }, + { 0, 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singcorner123_newelstypes[] = +{ + HP_DUMMY_QUAD_SINGCORNER, + HP_DUMMY_QUAD_SINGCORNER, + HP_DUMMY_QUAD_SINGCORNER, + // HP_TRIG_SINGCORNER, + // HP_TRIG, + // HP_TRIG_SINGCORNER, + // HP_TRIG, + // HP_TRIG_SINGCORNER, + // HP_TRIG, + HP_QUAD, + HP_QUAD, + HP_QUAD, + HP_TRIG, + HP_NONE, +}; +int reftrig_singcorner123_newels[][8] = +{ + { 1, 4, 10, 5 }, + { 2, 7, 11, 6 }, + { 3, 8, 12, 9 }, + // { 1, 4, 5 }, + // { 5, 4, 10 }, + // { 2, 7, 6 }, + // { 6, 7, 11 }, + // { 3, 8, 9 }, + // { 8, 12, 9 }, + { 4, 6, 11, 10 }, + { 7, 9, 12, 11 }, + { 8, 5, 10, 12 }, + { 10, 11, 12 }, +}; +HPRef_Struct reftrig_singcorner123 = +{ + HP_TRIG, + reftrig_singcorner123_splitedges, + reftrig_singcorner123_splitfaces, + 0, + reftrig_singcorner123_newelstypes, + reftrig_singcorner123_newels +}; + +// HP_TRIG_SINGEDGE +int reftrig_singedge_splitedges[][3] = +{ + { 2, 3, 4 }, + { 1, 3, 5 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedge_newelstypes[] = +{ + HP_TRIG, + HP_QUAD_SINGEDGE, + HP_NONE, +}; +int reftrig_singedge_newels[][8] = +{ + { 4, 3, 5 }, + { 1, 2, 4, 5 }, +}; +HPRef_Struct reftrig_singedge = +{ + HP_TRIG, + reftrig_singedge_splitedges, + 0, 0, + reftrig_singedge_newelstypes, + reftrig_singedge_newels +}; + + + + + + +// HP_TRIG_SINGEDGECORNER1 +int reftrig_singedgecorner1_splitedges[][3] = +{ + { 1, 2, 6 }, + { 1, 3, 5 }, + { 2, 3, 4 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedgecorner1_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_NONE, +}; +int reftrig_singedgecorner1_newels[][8] = +{ + { 1, 6, 5 }, + { 6, 2, 4, 5 }, + { 5, 4, 3 }, +}; +HPRef_Struct reftrig_singedgecorner1 = +{ + HP_TRIG, + reftrig_singedgecorner1_splitedges, + 0, 0, + reftrig_singedgecorner1_newelstypes, + reftrig_singedgecorner1_newels +}; + + + + + + + + +// HP_TRIG_SINGEDGECORNER2 +int reftrig_singedgecorner2_splitedges[][3] = +{ + { 2, 1, 6 }, + { 1, 3, 5 }, + { 2, 3, 4 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedgecorner2_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_NONE, +}; +int reftrig_singedgecorner2_newels[][8] = +{ + { 6, 2, 4}, + { 1, 6, 4, 5 }, + { 5, 4, 3 }, +}; +HPRef_Struct reftrig_singedgecorner2 = +{ + HP_TRIG, + reftrig_singedgecorner2_splitedges, + 0, 0, + reftrig_singedgecorner2_newelstypes, + reftrig_singedgecorner2_newels +}; + + + + +// HP_TRIG_SINGEDGECORNER12 +int reftrig_singedgecorner12_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 1, 6 }, + { 2, 3, 7 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedgecorner12_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_NONE, +}; +int reftrig_singedgecorner12_newels[][8] = +{ + { 1, 4, 5 }, + { 6, 2, 7 }, + { 4, 6, 7, 5 }, + { 5, 7, 3 }, +}; +HPRef_Struct reftrig_singedgecorner12 = +{ + HP_TRIG, + reftrig_singedgecorner12_splitedges, + 0, 0, + reftrig_singedgecorner12_newelstypes, + reftrig_singedgecorner12_newels +}; + + + + + + + +// HP_TRIG_SINGEDGECORNER3 +int reftrig_singedgecorner3_splitedges[][3] = +{ + { 1, 3, 4 }, + { 3, 1, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedgecorner3_newelstypes[] = +{ + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int reftrig_singedgecorner3_newels[][8] = +{ + { 1, 2, 6, 4 }, + { 4, 6, 7, 5 }, + { 3, 5, 7 }, +}; +HPRef_Struct reftrig_singedgecorner3 = +{ + HP_TRIG, + reftrig_singedgecorner3_splitedges, + 0, 0, + reftrig_singedgecorner3_newelstypes, + reftrig_singedgecorner3_newels +}; + + + + +// HP_TRIG_SINGEDGECORNER13 +int reftrig_singedgecorner13_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 3, 6 }, + { 3, 1, 7 }, + { 3, 2, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedgecorner13_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int reftrig_singedgecorner13_newels[][8] = +{ + { 1, 4, 5 }, + { 4, 2, 6, 5 }, + { 5, 6, 8, 7 }, + { 3, 7, 8 }, +}; +HPRef_Struct reftrig_singedgecorner13 = +{ + HP_TRIG, + reftrig_singedgecorner13_splitedges, + 0, 0, + reftrig_singedgecorner13_newelstypes, + reftrig_singedgecorner13_newels +}; + + + + + +// HP_TRIG_SINGEDGECORNER23 +int reftrig_singedgecorner23_splitedges[][3] = +{ + { 1, 3, 4 }, + { 2, 1, 5 }, + { 2, 3, 6 }, + { 3, 1, 7 }, + { 3, 2, 8 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedgecorner23_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int reftrig_singedgecorner23_newels[][8] = +{ + { 5, 2, 6 }, + { 1, 5, 6, 4 }, + { 4, 6, 8, 7 }, + { 3, 7, 8 }, +}; +HPRef_Struct reftrig_singedgecorner23 = +{ + HP_TRIG, + reftrig_singedgecorner23_splitedges, + 0, 0, + reftrig_singedgecorner23_newelstypes, + reftrig_singedgecorner23_newels +}; + + + +// HP_TRIG_SINGEDGECORNER123 +int reftrig_singedgecorner123_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 1, 6 }, + { 2, 3, 7 }, + { 3, 1, 8 }, + { 3, 2, 9 }, + { 0, 0, 0 } +}; +HPREF_ELEMENT_TYPE reftrig_singedgecorner123_newelstypes[] = +{ + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD, + HP_TRIG_SINGCORNER, + HP_NONE, +}; +int reftrig_singedgecorner123_newels[][8] = +{ + { 1, 4, 5 }, + { 6, 2, 7 }, + { 4, 6, 7, 5 }, + { 5, 7, 9, 8 }, + { 3, 8, 9 }, +}; +HPRef_Struct reftrig_singedgecorner123 = +{ + HP_TRIG, + reftrig_singedgecorner123_splitedges, + 0, 0, + reftrig_singedgecorner123_newelstypes, + reftrig_singedgecorner123_newels +}; + +// HP_TRIG_SINGEDGES +int reftrig_singedges_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 0, 0, 0 } +}; +int reftrig_singedges_splitfaces[][4] = +{ + { 1, 2, 3, 8 }, + { 0, 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftrig_singedges_newelstypes[] = +{ + // HP_QUAD_2E, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG, + HP_NONE, +}; +int reftrig_singedges_newels[][8] = +{ + // { 1, 4, 8, 5 }, + { 1, 4, 8 }, + { 5, 1, 8 }, + { 4, 2, 6, 8 }, + { 3, 5, 8, 7 }, + { 6, 7, 8 }, +}; +HPRef_Struct reftrig_singedges = +{ + HP_TRIG, + reftrig_singedges_splitedges, + reftrig_singedges_splitfaces, + 0, + reftrig_singedges_newelstypes, + reftrig_singedges_newels +}; + + + + + + + + +// HP_TRIG_SINGEDGES2 +int reftrig_singedges2_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 1, 6 }, + { 2, 3, 7 }, + { 3, 2, 8 }, + { 0, 0, 0 } +}; +int reftrig_singedges2_splitfaces[][4] = +{ + { 1, 2, 3, 9 }, + { 0, 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftrig_singedges2_newelstypes[] = +{ + // HP_QUAD_2E, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG, + HP_NONE, +}; +int reftrig_singedges2_newels[][8] = +{ + // { 1, 4, 9, 5 }, + { 1, 4, 9 }, + { 5, 1, 9 }, + { 4, 6, 7, 9 }, + { 3, 5, 9, 8 }, + { 6, 2, 7 }, + { 7, 8, 9 }, +}; +HPRef_Struct reftrig_singedges2 = +{ + HP_TRIG, + reftrig_singedges2_splitedges, + reftrig_singedges2_splitfaces, + 0, + reftrig_singedges2_newelstypes, + reftrig_singedges2_newels +}; + + + + +// HP_TRIG_SINGEDGES3 +int reftrig_singedges3_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 3, 6 }, + { 3, 1, 7 }, + { 3, 2, 8 }, + { 0, 0, 0 } +}; +int reftrig_singedges3_splitfaces[][4] = +{ + { 1, 2, 3, 9 }, + { 0, 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftrig_singedges3_newelstypes[] = +{ + // HP_QUAD_2E, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG, + HP_NONE, +}; +int reftrig_singedges3_newels[][8] = +{ + // { 1, 4, 9, 5 }, + { 1, 4, 9 }, + { 5, 1, 9 }, + { 4, 2, 6, 9 }, + { 7, 5, 9, 8 }, + { 3, 7, 8 }, + { 6, 8, 9 }, +}; +HPRef_Struct reftrig_singedges3 = +{ + HP_TRIG, + reftrig_singedges3_splitedges, + reftrig_singedges3_splitfaces, + 0, + reftrig_singedges3_newelstypes, + reftrig_singedges3_newels +}; + + + + + + +// HP_TRIG_SINGEDGES23 +int reftrig_singedges23_splitedges[][3] = +{ + { 1, 2, 4 }, + { 1, 3, 5 }, + { 2, 1, 6 }, + { 2, 3, 7 }, + { 3, 1, 8 }, + { 3, 2, 9 }, + { 0, 0, 0 } +}; +int reftrig_singedges23_splitfaces[][4] = +{ + { 1, 2, 3, 10 }, + { 0, 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftrig_singedges23_newelstypes[] = +{ + // HP_QUAD_2E, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG, + HP_NONE, +}; +int reftrig_singedges23_newels[][8] = +{ + // { 1, 4, 10, 5 }, + { 1 , 4, 10 }, + { 5, 1, 10 }, + { 4, 6, 7, 10 }, + { 8, 5, 10, 9 }, + { 6, 2, 7 }, + { 3, 8, 9 }, + { 7, 9, 10 }, +}; +HPRef_Struct reftrig_singedges23 = +{ + HP_TRIG, + reftrig_singedges23_splitedges, + reftrig_singedges23_splitfaces, + 0, + reftrig_singedges23_newelstypes, + reftrig_singedges23_newels +}; + + +// HP_TRIG_3SINGEDGES +int reftrig_3singedges_splitedges[][3] = +{ + { 1, 2, 4 }, + { 2, 1, 5 }, + { 2, 3, 6 }, + { 3, 2, 7 }, + { 3, 1, 8 }, + { 1, 3, 9 }, + { 0, 0, 0 } +}; +int reftrig_3singedges_splitfaces[][4] = +{ + { 1, 2, 3, 10 }, + { 2, 3, 1, 11 }, + { 3, 1, 2, 12 }, + { 0, 0, 0, 0 } +}; + +HPREF_ELEMENT_TYPE reftrig_3singedges_newelstypes[] = +{ + HP_TRIG, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_QUAD_SINGEDGE, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_TRIG_SINGEDGECORNER1, + HP_TRIG_SINGEDGECORNER2, + HP_NONE, +}; +int reftrig_3singedges_newels[][8] = +{ + { 10, 11, 12 }, + { 4, 5, 11, 10 }, + { 6, 7, 12, 11 }, + { 8, 9, 10, 12 }, + { 1, 4, 10 }, + { 9, 1, 10 }, + { 2, 6, 11 }, + { 5, 2, 11 }, + { 3, 8, 12 }, + { 7, 3, 12 }, +}; +HPRef_Struct reftrig_3singedges = +{ + HP_TRIG, + reftrig_3singedges_splitedges, + reftrig_3singedges_splitfaces, + 0, + reftrig_3singedges_newelstypes, + reftrig_3singedges_newels +}; diff --git a/libsrc/meshing/hprefinement.cpp b/libsrc/meshing/hprefinement.cpp new file mode 100644 index 00000000..21b1d1fa --- /dev/null +++ b/libsrc/meshing/hprefinement.cpp @@ -0,0 +1,1969 @@ +#include +#include "meshing.hpp" +#include "hprefinement.hpp" + +namespace netgen +{ + +#include "hpref_segm.hpp" +#include "hpref_trig.hpp" +#include "hpref_quad.hpp" +#include "hpref_tet.hpp" +#include "hpref_prism.hpp" +#include "hpref_hex.hpp" +#include "hpref_pyramid.hpp" +#include "classifyhpel.hpp" + + + void HPRefElement :: Reset(void) + { + np = 8; + for (int i = 0; i < 8; i++) + { + pnums[i] = -1; + param[i][0] = param[i][1] = param[i][2] = 0; + domin=-1; domout=-1; // he: + } + } + + HPRefElement :: HPRefElement () + { + Reset(); + } + + HPRefElement :: HPRefElement(Element & el) + { + //Reset(); + np = el.GetNV(); + for (int i=0; igeom == HP_TET) + hps = &reftet; + if (hps->geom == HP_TRIG) + hps = &reftrig; + } + */ + + if (!hps) + { + cout << "Attention hps : hp-refinement not implemented for case " << type << endl; + PrintSysError ("hp-refinement not implemented for case ", type); + } + + return hps; + } + + bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoiclt_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint, int & levels, int & act_ref); + + bool ClassifyHPElements (Mesh & mesh, Array & elements, int & act_ref, int & levels); + + + void InitHPElements(Mesh & mesh, Array & elements) + { + for(ElementIndex i = 0; i < mesh.GetNE(); i++) + { + HPRefElement hpel(mesh[i]); + hpel.coarse_elnr = i; + + switch (mesh[i].GetType()) + { + case PRISM: hpel.type = HP_PRISM; break; + case HEX: hpel.type = HP_HEX; break; + case TET: hpel.type = HP_TET; break; + case PYRAMID: hpel.type = HP_PYRAMID; break; + + default: + cerr << "HPRefElement: illegal elementtype (1) " << mesh[i].GetType() << endl; + throw NgException ("HPRefElement: illegal elementtype (1)"); + } + elements.Append(hpel); + } + + for(SurfaceElementIndex i = 0; i < mesh.GetNSE(); i++) + { + HPRefElement hpel(mesh[i]); + hpel.coarse_elnr = i; + switch(mesh[i].GetType()) + { + case TRIG: hpel.type = HP_TRIG; break; + case QUAD: hpel.type = HP_QUAD; break; + + default: + cerr << "HPRefElement: illegal elementtype (1b) " << mesh[i].GetType() << endl; + throw NgException ("HPRefElement: illegal elementtype (1b)"); + } + elements.Append(hpel); + } + + for(SegmentIndex i = 0; i < mesh.GetNSeg(); i++) + { + Segment & seg = mesh[i]; + HPRefElement hpel(mesh[i]); + hpel.coarse_elnr = i; + hpel.type = HP_SEGM; + hpel.index = seg.edgenr + 10000*seg.si; + if(seg.edgenr >= 10000) + { + throw NgException("assumption that seg.edgenr < 10000 is wrong"); + } + elements.Append(hpel); + } + } + + + + /* ******************************* DoRefinement *************************************** */ + void DoRefinement (Mesh & mesh, Array & elements, + Refinement * ref, double fac1) + { + elements.SetAllocSize (5 * elements.Size()); + INDEX_2_HASHTABLE newpts(elements.Size()+1); + INDEX_3_HASHTABLE newfacepts(elements.Size()+1); + + // prepare new points + + fac1 = max(0.001,min(0.33,fac1)); + cout << " in HP-REFINEMENT with fac1 " << fac1 << endl; + *testout << " in HP-REFINEMENT with fac1 " << fac1 << endl; + + + int oldelsize = elements.Size(); + + for (int i = 0; i < oldelsize; i++) + { + HPRefElement & el = elements[i]; + HPRef_Struct * hprs = Get_HPRef_Struct (el.type); + + if (!hprs) + { + cout << "Refinementstruct not defined for element " << el.type << endl; + continue; + } + + int j = 0; + while (hprs->splitedges[j][0]) + { + INDEX_2 i2(el.pnums[hprs->splitedges[j][0]-1], + el.pnums[hprs->splitedges[j][1]-1]); + if (!newpts.Used (i2)) + { + Point<3> np; + for( int l=0;l<3;l++) + np(l) = (1-fac1)*mesh.Point(i2.I1())(l) + + fac1 * mesh.Point(i2.I2())(l); + + int npi = mesh.AddPoint (np); + newpts.Set (i2, npi); + } + j++; + } + + j = 0; + if (hprs->splitfaces) + while (hprs->splitfaces[j][0]) + { + INDEX_3 i3(el.pnums[hprs->splitfaces[j][0]-1], + el.pnums[hprs->splitfaces[j][1]-1], + el.pnums[hprs->splitfaces[j][2]-1]); + + if (i3.I2() > i3.I3()) Swap (i3.I2(), i3.I3()); + + if (!newfacepts.Used (i3)) + { + Point<3> np; + for( int l=0;l<3;l++) + np(l) = (1-2*fac1)*mesh.Point(i3.I1())(l) + + fac1*mesh.Point(i3.I2())(l) + fac1*mesh.Point(i3.I3())(l); + int npi = mesh.AddPoint (np); + newfacepts.Set (i3, npi); + } + j++; + } + } + + for (int i = 0; i < oldelsize; i++) + { + HPRefElement el = elements[i]; + HPRef_Struct * hprs = Get_HPRef_Struct (el.type); + int newlevel = el.levelx + 1; + + int oldnp = 0; + switch (hprs->geom) + { + case HP_SEGM: oldnp = 2; break; + case HP_TRIG: oldnp = 3; break; + case HP_QUAD: oldnp = 4; break; + case HP_TET: oldnp = 4; break; + case HP_PYRAMID: oldnp = 5; break; + case HP_PRISM: oldnp = 6; break; + case HP_HEX: oldnp = 8; break; + + default: + cerr << "HPRefElement: illegal type (3) " << hprs->geom << endl; + throw NgException ("HPRefElement::SetType: illegal type (3)"); + } + + + if (el.type == HP_SEGM || + el.type == HP_TRIG || + el.type == HP_QUAD || + el.type == HP_TET || + el.type == HP_PRISM || + el.type == HP_HEX || + el.type == HP_PYRAMID) + newlevel = el.levelx; + + if (!hprs) continue; + + int newpnums[64]; + double newparam[64][3]; + + int j; + for (j = 0; j < oldnp; j++) + { + newpnums[j] = el.pnums[j]; + for (int l = 0; l < 3; l++) + newparam[j][l] = el.param[j][l]; + } + + // split edges, incl. transferring curvature + j = 0; + while (hprs->splitedges[j][0]) + { + INDEX_2 i2(el.pnums[hprs->splitedges[j][0]-1], + el.pnums[hprs->splitedges[j][1]-1]); + + int npi = newpts.Get(i2); + newpnums[hprs->splitedges[j][2]-1] = npi; + + for (int l = 0; l < 3; l++) + newparam[hprs->splitedges[j][2]-1][l] = + (1-fac1) * el.param[hprs->splitedges[j][0]-1][l] + + fac1 * el.param[hprs->splitedges[j][1]-1][l]; + + j++; + } + + // split faces + j = 0; + if (hprs->splitfaces) + while (hprs->splitfaces[j][0]) + { + INDEX_3 i3(el.pnums[hprs->splitfaces[j][0]-1], + el.pnums[hprs->splitfaces[j][1]-1], + el.pnums[hprs->splitfaces[j][2]-1]); + if (i3.I2() > i3.I3()) + Swap (i3.I2(), i3.I3()); + int npi = newfacepts.Get(i3); + newpnums[hprs->splitfaces[j][3]-1] = npi; + + + for (int l = 0; l < 3; l++) + newparam[hprs->splitfaces[j][3]-1][l] = + (1-2*fac1) * el.param[hprs->splitfaces[j][0]-1][l] + + fac1 * el.param[hprs->splitfaces[j][1]-1][l] + + fac1 * el.param[hprs->splitfaces[j][2]-1][l]; + j++; + } + // split elements + j = 0; + if (hprs->splitelements) + while (hprs->splitelements[j][0]) + { + //int pi1 = el.pnums[hprs->splitelements[j][0]-1]; + Point<3> np; + for( int l=0;l<3;l++) + np(l) = (1-3*fac1)* mesh.Point(el.pnums[hprs->splitelements[j][0]-1])(l) + + fac1* mesh.Point(el.pnums[hprs->splitelements[j][1]-1])(l) + + fac1* mesh.Point(el.pnums[hprs->splitelements[j][2]-1])(l) + + fac1* mesh.Point(el.pnums[hprs->splitelements[j][3]-1])(l); + + int npi = mesh.AddPoint (np); + + newpnums[hprs->splitelements[j][4]-1] = npi; + + + for (int l = 0; l < 3; l++) + newparam[hprs->splitelements[j][4]-1][l] = + (1-3*fac1) * el.param[hprs->splitelements[j][0]-1][l] + + fac1 * el.param[hprs->splitelements[j][1]-1][l] + + fac1 * el.param[hprs->splitelements[j][2]-1][l] + + fac1 * el.param[hprs->splitelements[j][3]-1][l]; + + j++; + } + + j = 0; + + /* + *testout << " newpnums = "; + for (int hi = 0; hi < 64; hi++) + *testout << newpnums[hi] << " "; + *testout << endl; + */ + + while (hprs->neweltypes[j]) + { + HPRef_Struct * hprsnew = Get_HPRef_Struct (hprs->neweltypes[j]); + HPRefElement newel(el); + + newel.type = hprs->neweltypes[j]; + + // newel.index = elements[i].index; + // newel.coarse_elnr = elements[i].coarse_elnr; + newel.levelx = newel.levely = newel.levelz = newlevel; + switch(hprsnew->geom) + { + case HP_SEGM: newel.np=2; break; + case HP_QUAD: newel.np=4; break; + case HP_TRIG: newel.np=3; break; + case HP_HEX: newel.np=8; break; + case HP_PRISM: newel.np=6; break; + case HP_TET: newel.np=4; break; + case HP_PYRAMID: newel.np=5; break; + default: + throw NgException (string("hprefinement.cpp: illegal type")); + } + + for (int k = 0; k < newel.np; k++) + newel.pnums[k] = newpnums[hprs->newels[j][k]-1]; + + /* + *testout << " newel pnums " ; + for (int k = 0; k < newel.np; k++) + *testout << newel.pnums[k] << "\t"; + *testout << endl; + */ + + for (int k = 0; k < newel.np; k++) + { + for (int l = 0; l < 3; l++) + { + newel.param[k][l] = newparam[hprs->newels[j][k]-1][l]; + // *testout << newel.param[k][l] << " \t "; + } + // *testout << endl; + } + + if (j == 0) + elements[i] = newel; // overwrite old element + else + elements.Append (newel); + j++; + } + } + } + + + + + + + /* ************************** DoRefineDummies ******************************** */ + + void DoRefineDummies (Mesh & mesh, Array & elements, + Refinement * ref) + { + int oldelsize = elements.Size(); + + for (int i = 0; i < oldelsize; i++) + { + HPRefElement el = elements[i]; + + HPRef_Struct * hprs = Get_HPRef_Struct (el.type); + if (!hprs) continue; + + if (el.type != HP_DUMMY_QUAD_SINGCORNER && + el.type != HP_PYRAMID_EDGES && + el.type != HP_PYRAMID_0E_1V && + el.type != HP_HEX_0E_1V && + el.type != HP_HEX_1E_1V && + el.type != HP_HEX_1E_0V && + el.type != HP_HEX_3E_0V + ) continue; + + int newlevel = el.levelx; + + int newpnums[8]; + int j; + for (j = 0; j < 8; j++) + newpnums[j] = el.pnums[j]; + + double newparam[8][3]; + for (j = 0; j < 8; j++) + for (int k = 0; k < 3; k++) + newparam[j][k] = el.param[j][k]; + + j = 0; + while (hprs->neweltypes[j]) + { + HPRef_Struct * hprsnew = Get_HPRef_Struct (hprs->neweltypes[j]); + HPRefElement newel(el); + switch(hprsnew->geom) + { + case HP_SEGM: newel.np=2; break; + case HP_QUAD: newel.np=4; break; + case HP_TRIG: newel.np=3; break; + case HP_HEX: newel.np=8; break; + case HP_PRISM: newel.np=6; break; + case HP_TET: newel.np=4; break; + case HP_PYRAMID: newel.np=5; break; + + default: + cerr << "HPRefElement: illegal type (4) " << hprsnew->geom << endl; + throw NgException ("HPRefElement: illegal type (4)"); + + } + newel.type = hprs->neweltypes[j]; + for (int k = 0; k < 8; k++) + newel.pnums[k] = newpnums[hprs->newels[j][k]-1]; + newel.index = el.index; + newel.coarse_elnr = el.coarse_elnr; + newel.levelx = newel.levely = newel.levelz = newlevel; + + for (int k = 0; k < 8; k++) + for (int l = 0; l < 3; l++) + newel.param[k][l] = newparam[hprs->newels[j][k]-1][l]; + + if (j == 0) + elements[i] = newel; + else + elements.Append (newel); + j++; + } + } + } + + + + + + + + void SubdivideDegeneratedHexes (Mesh & mesh, Array & elements, double fac1) + { + int oldne = elements.Size(); + for (int i = 0; i < oldne; i++) + if (Get_HPRef_Struct (elements[i].type)->geom == HP_HEX) + { + bool common = 0; + for (int j = 0; j < 8; j++) + for (int k = 0; k < j; k++) + if (elements[i].pnums[j] == elements[i].pnums[k]) + common = 1; + if (common) + { + + + cout << " Degenerate Hex found " << endl; + *testout << " Degenerate Hex found " << endl; + HPRefElement el = elements[i]; + HPRefElement newel = el; + + Point<3> center(0,0,0); + double newparam[3] = { 0, 0, 0 }; + + for (int j = 0; j < 8; j++) + { + + + center += 0.125 * Vec<3>(mesh[el.pnums[j]]); + // 0.125 originates form 8 points not from fac1; + + for (int l = 0; l < 3; l++) + newparam[l] += 0.125 * el.param[j][l]; + + } + + int npi = mesh.AddPoint (center); + + const ELEMENT_FACE * faces = MeshTopology::GetFaces1 (HEX); + + for (int j = 0; j < 6; j++) + { + Array pts; + for (int k = 0; k < 4; k++) + { + bool same = 0; + for (int l = 0; l < pts.Size(); l++) + if (el.pnums[pts[l]] == el.pnums[faces[j][k]-1]) + same = 1; + if (!same) + pts.Append (faces[j][k]-1); + + } + + + if (pts.Size() == 3) // TrigFace -> TET + { + + for (int k = 0; k < 3; k++) + { + newel.pnums[k] = el.pnums[pts[2-k]]; + for (int l = 0; l < 3; l++) + newel.param[k][l] = el.param[pts[2-k]][l]; + } + newel.pnums[3] = npi; + for (int l = 0; l < 3; l++) + newel.param[3][l] = newparam[l]; + + newel.type = HP_TET; + newel.np = 4; + } + else + { + for (int k = 0; k < 4; k++) + { + newel.pnums[k] = el.pnums[pts[3-k]]; + for (int l = 0; l < 3; l++) + newel.param[k][l] = el.param[pts[3-k]][l]; + } + + newel.pnums[4] = npi; + for (int l = 0; l < 3; l++) + newel.param[4][l] = newparam[l]; + + newel.type = HP_PYRAMID; + newel.np = 5; + } + + if (j == 0) + elements[i] = newel; + else + elements.Append (newel); + + + } + + /* const ELEMENT_EDGE * edges = MeshTopology::GetEdges (HEX); + + for(int k=0;k<12;k++) + { + int e[2]; + for(int l=0;l<2;l++) e[l] = edges[k][l]-1; + if(el.PNum(e[0]+1)!=el.PNum(e[1]+1)) + { + newel.SetType(HP_SEGM); + for(int l=0;l<2;l++) + { + newel.pnums[0] = el.PNum(e[l]+1); + newel.pnums[1] = npi; + for(int j=0;j<3;j++) + { + // newel.param[0][j] = el.param[e[l]][j]; + // newel.param[1][j] = newparam[j]; + } + + elements.Append(newel); + } + newel.SetType(HP_TRIG); + newel.pnums[0] = el.PNum(e[0]+1); + newel.pnums[1] = el.PNum(e[1]+1); + newel.pnums[2] = npi; + + *testout << "DEGHEX TRIG :: newpnums " << newel.pnums[0] << "\t" << newel.pnums[1] << "\t" << newel.pnums[2] << endl; + cout << "DEGHEX TRIG :: newpnums " << newel.pnums[0] << "\t" << newel.pnums[1] << "\t" << newel.pnums[2] << endl; + for(int j=0;j<3;j++) + { + // newel.param[0][j] = el.param[e[0]][j]; + // newel.param[1][j] = el.param[e[1]][j]; + // newel.param[2][j] = newparam[j]; + } + + elements.Append(newel); + } + + }*/ + } + } + } + + + void CalcStatistics (Array & elements) + { + return; +#ifdef ABC + int i, p; + int nsegm = 0, ntrig = 0, nquad = 0; + int nhex = 0, nprism = 0, npyramid = 0, ntet = 0; + int maxlevel = 0; + + for (i = 1; i <= elements.Size(); i++) + { + const HPRefElement & el = elements.Get(i); + maxlevel = max2 (el.level, maxlevel); + switch (Get_HPRef_Struct (el.type)->geom) + { + case HP_SEGM: + + { + nsegm++; + break; + } + case HP_TRIG: + { + ntrig ++; + break; + } + case HP_QUAD: + { + nquad++; + break; + } + case HP_TET: + { + ntet++; + break; + } + + case HP_PRISM: + { + nprism++; + break; + } + + case HP_PYRAMID: + { + npyramid++; + break; + } + + case HP_HEX: + { + nhex++; + break; + } + + default: + { + cerr << "statistics error, unknown element type" << endl; + } + } + } + + cout << "level = " << maxlevel << endl; + cout << "nsegm = " << nsegm << endl; + cout << "ntrig = " << ntrig << ", nquad = " << nquad << endl; + cout << "ntet = " << ntet << ", npyr = " << npyramid + << ", nprism = " << nprism << ", nhex = " << nhex << endl; + + return; + + double memcost = 0, cpucost = 0; + for (p = 1; p <= 20; p++) + { + memcost = (ntet + nprism + nhex) * pow (static_cast(p), 6.0); + cpucost = (ntet + nprism + nhex) * pow (static_cast(p), 9.0); + cout << "costs for p = " << p << ": mem = " << memcost << ", cpu = " << cpucost << endl; + } + + double memcosttet = 0; + double memcostprism = 0; + double memcosthex = 0; + double memcostsctet = 0; + double memcostscprism = 0; + double memcostschex = 0; + double cpucosttet = 0; + double cpucostprism = 0; + double cpucosthex = 0; + + for (i = 1; i <= elements.Size(); i++) + { + const HPRefElement & el = elements.Get(i); + switch (el.type) + { + case HP_TET: + case HP_TET_0E_1V: + case HP_TET_1E_0V: + case HP_TET_1E_1VA: + { + int p1 = maxlevel - el.level + 1; + (*testout) << "p1 = " << p1 << ", P1^6 = " << pow (static_cast(p1), 6.0) + << " (p1-3)^6 = " << pow ( static_cast(max2(p1-3, 0)), 6.0) + << " p1^3 = " << pow ( static_cast(p1), 3.0) + << " (p1-3)^3 = " << pow ( static_cast(p1-3), 3.0) + << " [p1^3-(p1-3)^3]^2 = " << sqr (pow (static_cast(p1),3.0) - pow ( static_cast(p1-3), 3.0)) + << endl; + + p1 /= 2 +1; + memcosttet += pow (static_cast(p1), 6.0); + memcostsctet += pow (static_cast(p1), 6.0) - pow ( static_cast(max2(p1-3, 1)), 6.0); + cpucosttet += pow (static_cast(p1), 9.0); + break; + } + case HP_PRISM: + case HP_PRISM_SINGEDGE: + { + int p1 = maxlevel - el.level + 1; + p1 /= 2 +1; + memcostprism += pow (static_cast(p1), 6.0); + memcostscprism += pow (static_cast(p1), 6.0) - pow ( static_cast(max2(p1-3, 1)), 6.0); + cpucostprism += pow (static_cast(p1), 9.0); + break; + } + case HP_HEX: + { + int p1 = maxlevel - el.level + 1; + int p2 = maxlevel; + p1 /= 2 +1; + p2 /= 2 +1; + memcosthex += pow (static_cast(p1), 4.0) * pow (static_cast(p2), 2.0); + memcostschex += pow (static_cast(p1), 6.0) - pow ( static_cast(max2(p1-2, 0)), 6.0); + cpucosthex += pow (static_cast(p1), 6.0) * pow (static_cast(p2), 3.0); + break; + } + default: + ; + } + } + cout << "TET: hp-memcost = " << memcosttet + << ", scmemcost = " << memcostsctet + << ", cpucost = " << cpucosttet + << endl; + cout << "PRI: hp-memcost = " << memcostprism + << ", scmemcost = " << memcostscprism + << ", cpucost = " << cpucostprism << endl; + cout << "HEX: hp-memcost = " << memcosthex + << ", scmemcost = " << memcostschex + << ", cpucost = " << cpucosthex << endl; +#endif + } + + + + void ReorderPoints (Mesh & mesh, Array & hpelements) + { + Array map (mesh.GetNP()); + + for (int i = 1; i <= mesh.GetNP(); i++) + map[i] = i; + + int nwrong(0), nright(0); + for (int k = 0; k < 5; k++) + { + nwrong = nright = 0; + for (int i = 0; i < hpelements.Size(); i++) + { + const HPRefElement & hpel = hpelements[i]; + + if (Get_HPRef_Struct (hpel.type) -> geom == HP_PRISM) + { + int minbot = 0, mintop = 0; + for (int j = 0; j < 3; j++) + { + if (map[hpel.pnums[j]] < map[hpel.pnums[minbot]]) minbot = j; + if (map[hpel.pnums[j+3]] < map[hpel.pnums[mintop+3]]) mintop = j; + } + if (minbot != mintop) + nwrong++; + else + nright++; + + if (minbot != mintop) + { + if (map[hpel.pnums[minbot]] < map[hpel.pnums[mintop+3]]) + swap (map[hpel.pnums[3+minbot]], map[hpel.pnums[3+mintop]]); + else + swap (map[hpel.pnums[minbot]], map[hpel.pnums[mintop]]); + } + } + } + // cout << nwrong << " wrong prisms, " << nright << " right prisms" << endl; + } + + cout << nwrong << " wrong prisms, " << nright << " right prisms" << endl; + + + Array hpts(mesh.GetNP()); + + for (int i = 1; i <= mesh.GetNP(); i++) + hpts[map[i]] = mesh.Point(i); + + for (int i = 1; i <= mesh.GetNP(); i++) + mesh.Point(i) = hpts[i]; + + for (int i = 0; i < hpelements.Size(); i++) + { + HPRefElement & hpel = hpelements[i]; + for (int j = 0; j < hpel.np; j++) + hpel.pnums[j] = map[hpel.pnums[j]]; + } + } + + + + /* ***************************** HPRefinement ********************************** */ + + void HPRefinement (Mesh & mesh, Refinement * ref, int levels, double fac1, bool setorders, bool reflevels) + { + PrintMessage (1, "HP Refinement called, levels = ", levels); + + + // NgLock mem_lock (mem_mutex,1); + + mesh.coarsemesh = new Mesh; + *mesh.coarsemesh = mesh; + + // #ifdef CURVEDELEMS_NEW + const_cast (mesh.coarsemesh->GetCurvedElements() ). + BuildCurvedElements (ref, mesh.GetCurvedElements().GetOrder()); + // #endif + + + delete mesh.hpelements; + mesh.hpelements = new Array; + + Array & hpelements = *mesh.hpelements; + + InitHPElements(mesh,hpelements); + + Array nplevel; + nplevel.Append (mesh.GetNP()); + + int act_ref=1; + bool sing = ClassifyHPElements (mesh,hpelements, act_ref, levels); + + sing = true; // iterate at least once + while(sing) + { + cout << " Start new hp-refinement: step " << act_ref << endl; + + DoRefinement (mesh, hpelements, ref, fac1); + DoRefineDummies (mesh, hpelements, ref); + + nplevel.Append (mesh.GetNP()); + CalcStatistics (hpelements); + + SubdivideDegeneratedHexes (mesh, hpelements,fac1); + + ReorderPoints (mesh, hpelements); + + mesh.ClearSegments(); + mesh.ClearSurfaceElements(); + mesh.ClearVolumeElements(); + + for (int i = 0; i < hpelements.Size(); i++) + { + HPRefElement & hpel = hpelements[i]; + if (Get_HPRef_Struct (hpel.type)) + switch (Get_HPRef_Struct (hpel.type) -> geom) + { + case HP_SEGM: + { + Segment seg; + seg[0] = hpel.pnums[0]; + seg[1] = hpel.pnums[1]; + // NOTE: only for less than 10000 elements (HACK) !!! + seg.edgenr = hpel.index % 10000; + seg.si = hpel.index / 10000; + + /* + seg.epgeominfo[0].dist = hpel.param[0][0]; // he: war hpel.param[0][0] + seg.epgeominfo[1].dist = hpel.param[1][0]; // he: war hpel.param[1][0] + */ + + const Segment & coarseseg = mesh.coarsemesh->LineSegment(hpel.coarse_elnr+1); + double d1 = coarseseg.epgeominfo[0].dist; + double d2 = coarseseg.epgeominfo[1].dist; + + // seg.epgeominfo[0].dist = hpel.param[0][0]; // he: war hpel.param[0][0] + // seg.epgeominfo[1].dist = hpel.param[1][0]; // he: war hpel.param[1][0] + + seg.epgeominfo[0].dist = d1 + hpel.param[0][0] * (d2-d1); // JS, June 08 + seg.epgeominfo[1].dist = d1 + hpel.param[1][0] * (d2-d1); + + + seg.epgeominfo[0].edgenr = seg.edgenr; + seg.epgeominfo[1].edgenr = seg.edgenr; + seg.domin = hpel.domin; seg.domout=hpel.domout; // he: needed for segments! + seg.hp_elnr = i; + seg.singedge_left = hpel.singedge_left; + seg.singedge_right = hpel.singedge_right; + mesh.AddSegment (seg); + break; + } + + case HP_TRIG: + case HP_QUAD: + { + Element2d el(hpel.np); + for(int j=0;j geom)); + } + } + cout << " Start with Update Topology " << endl; + mesh.UpdateTopology(); + cout << " Mesh Update Topology done " << endl; + + act_ref++; + + sing = ClassifyHPElements(mesh,hpelements, act_ref, levels); + } + + cout << " HP-Refinement done with " << --act_ref << " refinement steps." << endl; + + if(act_ref>=1) + { + for(ElementIndex i=0;i v(hpel.param[edges[j][0]-1][0]-hpel.param[edges[j][1]-1][0], + hpel.param[edges[j][0]-1][1]-hpel.param[edges[j][1]-1][1], + hpel.param[edges[j][0]-1][2]-hpel.param[edges[j][1]-1][2]); + dist[edge_dir[j]] = max(v.Length(),dist[edge_dir[j]]); + } + + int refi[3]; + for(int j=0;j<3;j++) + refi[j] = int(max(double(floor(log(dist[ord_dir[j]]/sqrt(2.))/log(fac1))),0.)); + + // cout << " ref " << refi[0] << "\t" << refi[1] << "\t" << refi[2] << endl; + // cout << " order " << act_ref +1 - refi[0] << "\t" << act_ref +1 - refi[1] << "\t" << act_ref +1 - refi[2] << endl; + + if(setorders) + mesh[i].SetOrder(act_ref+1-refi[0],act_ref+1-refi[1],act_ref+1-refi[2]); + } + for(SurfaceElementIndex i=0;i v(hpel.param[edges[j][0]-1][0]-hpel.param[edges[j][1]-1][0], + hpel.param[edges[j][0]-1][1]-hpel.param[edges[j][1]-1][1], + hpel.param[edges[j][0]-1][2]-hpel.param[edges[j][1]-1][2]); + dist[edge_dir[j]] = max(v.Length(),dist[edge_dir[j]]); + } + + int refi[3]; + for(int j=0;j<3;j++) + refi[j] = int(max(double(floor(log(dist[ord_dir[j]]/sqrt(2.))/log(fac1))),0.)); + + if(setorders) + mesh[i].SetOrder(act_ref+1-refi[0],act_ref+1-refi[1],act_ref+1-refi[2]); + + // cout << " ref " << refi[0] << "\t" << refi[1] << endl; + // cout << " order " << act_ref +1 - refi[0] << "\t" << act_ref +1 - refi[1] << endl; + } + } + } + +bool CheckSingularities(Mesh & mesh, INDEX_2_HASHTABLE & edges, INDEX_2_HASHTABLE & edgepoint_dom, + BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE & faces, INDEX_2_HASHTABLE & face_edges, + INDEX_2_HASHTABLE & surf_edges, Array & facepoint, int & levels, int & act_ref) +{ + bool sing = 0; + if (mesh.GetDimension() == 3) + { + /* + // check, if point has as least 3 different surfs: + + Array surfonpoint(mesh.GetNP()); + surfonpoint = INDEX_3(0,0,0); + + for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el = mesh[sei]; + int ind = el.GetIndex(); + for (int j = 0; j < el.GetNP(); j++) + { + INDEX_3 & i3 = surfonpoint[el[j]]; + if (ind != i3.I1() && ind != i3.I2() && ind != i3.I3()) + { + i3.I1() = i3.I2(); + i3.I2() = i3.I3(); + i3.I3() = ind; + } + } + } + for (int i = 1; i <= mesh.GetNP(); i++) + if (surfonpoint.Get(i).I1()) + cornerpoint.Set(i); + */ + cornerpoint.Clear(); + + for (int i = 1; i <= mesh.GetNP(); i++) + { + if (mesh.Point(i).Singularity() * levels >= act_ref) + { + cornerpoint.Set(i); + sing = 1; + } + } + cout << endl; + + for (int i = 1; i <= mesh.GetNSeg(); i++) + if (mesh.LineSegment(i).singedge_left * levels >= act_ref) + { + INDEX_2 i2 (mesh.LineSegment(i)[0], + mesh.LineSegment(i)[1]); + + /* + // before + edges.Set (i2, 1); + i2.Sort(); + INDEX_2 i2s(i2.I2(), i2.I1()); + edges.Set (i2s, 1); + */ + + edges.Set (i2, 1); + INDEX_2 i2s(i2.I2(), i2.I1()); + edges.Set (i2s, 1); + + + edgepoint.Set (i2.I1()); + edgepoint.Set (i2.I2()); + sing = 1; + } + + // if 2 adjacent edges of an element are singular, the + // commen point must be a singular point + for (int i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement(i); + const ELEMENT_EDGE * eledges = MeshTopology::GetEdges1 (el.GetType()); + int nedges = MeshTopology::GetNEdges (el.GetType()); + for (int j = 0; j < nedges; j++) + for (int k = 0; k < nedges; k++) + if (j != k) + { + INDEX_2 ej(el.PNum(eledges[j][0]), el.PNum(eledges[j][1])); + ej.Sort(); + INDEX_2 ek(el.PNum(eledges[k][0]), el.PNum(eledges[k][1])); + ek.Sort(); + if (edges.Used(ej) && edges.Used(ek)) + { + if (ej.I1() == ek.I1()) cornerpoint.Set (ek.I1()); + if (ej.I1() == ek.I2()) cornerpoint.Set (ek.I2()); + if (ej.I2() == ek.I1()) cornerpoint.Set (ek.I1()); + if (ej.I2() == ek.I2()) cornerpoint.Set (ek.I2()); + } + } + } + + edgepoint.Or (cornerpoint); + (*testout) << "cornerpoint = " << endl << cornerpoint << endl; + (*testout) << "edgepoint = " << endl << edgepoint << endl; + + facepoint = 0; + for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & el = mesh[sei]; + const FaceDescriptor & fd = mesh.GetFaceDescriptor (el.GetIndex()); + + int domnr = 0; + if (fd.DomainInSingular() * levels < act_ref && fd.DomainOutSingular() * levels < act_ref) + { domnr=0; continue;} + + if (fd.DomainInSingular() * levels >= act_ref) + { + domnr = fd.DomainIn(); + sing = 1; + } + if (fd.DomainOutSingular() * levels >= act_ref) + { + domnr = fd.DomainOut(); + sing = 1; + } + if (fd.DomainInSingular() * levels >= act_ref + && fd.DomainOutSingular() * levels >= act_ref) + { + domnr = -1; + sing = 1; + } + + INDEX_3 i3; + if (el.GetNP() == 3) + i3 = INDEX_3::Sort (el[0], el[1], el[2]); + else + { + INDEX_4 i4 (el[0], el[1], el[2], el[3]); + i4.Sort(); + i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); + } + faces.Set (i3, domnr); + + for (int j = 0; j < el.GetNP(); j++) + { + face_edges.Set (INDEX_2::Sort (el[j], el[(j+1)%el.GetNP()]), domnr); + + surf_edges.Set (INDEX_2::Sort (el[j], el[(j+1)%el.GetNP()]), fd.SurfNr()+1); + + facepoint[el[j]] = domnr; + } + + } + (*testout) << "singular faces = " << faces << endl; + (*testout) << "singular faces_edges = " << face_edges << endl; + } + else + { + // 2D case + + // check, if point has as least 3 different surfs: + Array surfonpoint(mesh.GetNP()); + + for (int i = 1; i <= mesh.GetNP(); i++) + surfonpoint.Elem(i) = INDEX_3(0,0,0); + + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + int ind = seg.edgenr; + + if (seg.singedge_left * levels >= act_ref) + { + INDEX_2 i2 (mesh.LineSegment(i)[0], + mesh.LineSegment(i)[1]); + edges.Set(i2,1); + edgepoint.Set(i2.I1()); + edgepoint.Set(i2.I2()); + *testout << " singleft " << endl; + *testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl; + *testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl; + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I1()), 1); + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domin, i2.I2()), 1); + sing = 1; + + } + + if (seg.singedge_right * levels >= act_ref) + { + INDEX_2 i2 (mesh.LineSegment(i)[1], + mesh.LineSegment(i)[0]); + edges.Set (i2, 1); + edgepoint.Set(i2.I1()); + edgepoint.Set(i2.I2()); + + *testout << " singright " << endl; + *testout << " mesh.LineSegment(i).domout " << mesh.LineSegment(i).domout << endl; + *testout << " mesh.LineSegment(i).domin " << mesh.LineSegment(i).domin << endl; + + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I1()), 1); + edgepoint_dom.Set (INDEX_2(mesh.LineSegment(i).domout, i2.I2()), 1); + sing = 1; + } + + // (*testout) << "seg = " << ind << ", " << seg[0] << "-" << seg[1] << endl; + + + if (seg.singedge_left * levels >= act_ref + || seg.singedge_right* levels >= act_ref) + { + for (int j = 0; j < 2; j++) + { + int pi = (j == 0) ? seg[0] : seg[1]; + INDEX_3 & i3 = surfonpoint.Elem(pi); + if (ind != i3.I1() && + ind != i3.I2()) + { + i3.I1() = i3.I2(); + i3.I2() = ind; + } + } + } + } + + + for (int i = 1; i <= mesh.GetNP(); i++) + { + // mark points for refinement that are in corners between two anisotropic edges + if (surfonpoint.Get(i).I1()) + { + // cornerpoint.Set(i); // disabled by JS, Aug 2009 + edgepoint.Set(i); + } + + // mark points for refinement that are explicity specified in input file + if (mesh.Point(i).Singularity()*levels >= act_ref) + { + cornerpoint.Set(i); + edgepoint.Set(i); + sing = 1; + } + } + + edgepoint.Or (cornerpoint); + + (*testout) << "2d sing edges: " << endl << edges << endl; + (*testout) << "2d cornerpoints: " << endl << cornerpoint << endl + << "2d edgepoints: " << endl << edgepoint << endl; + + facepoint = 0; + } + + if (!sing) + cout << "PrepareElements no more to do for actual refinement " << act_ref << endl; + + return(sing); +} + + + + bool ClassifyHPElements (Mesh & mesh, Array & elements, int & act_ref, int & levels) + { + INDEX_2_HASHTABLE edges(mesh.GetNSeg()+1); + BitArray edgepoint(mesh.GetNP()); + INDEX_2_HASHTABLE edgepoint_dom(mesh.GetNSeg()+1); + + edgepoint.Clear(); + BitArray cornerpoint(mesh.GetNP()); + cornerpoint.Clear(); + + // value = nr > 0 ... refine elements in domain nr + // value = -1 ..... refine elements in any domain + INDEX_3_HASHTABLE faces(mesh.GetNSE()+1); + INDEX_2_HASHTABLE face_edges(mesh.GetNSE()+1); + INDEX_2_HASHTABLE surf_edges(mesh.GetNSE()+1); + Array facepoint(mesh.GetNP()); + + bool sing = CheckSingularities(mesh, edges, edgepoint_dom, + cornerpoint, edgepoint, faces, face_edges, + surf_edges, facepoint, levels, act_ref); + + if(sing==0) return(sing); + + int cnt_undef = 0, cnt_nonimplement = 0; + Array misses(10000); + misses = 0; + + (*testout) << "edgepoint_dom = " << endl << edgepoint_dom << endl; + + for( int i = 0; igeom) + { + case HP_TET: + { + hpel.type = ClassifyTet(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces,face_edges, surf_edges, facepoint); + break; + } + case HP_PRISM: + { + hpel.type = ClassifyPrism(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces, + face_edges, surf_edges, facepoint); + + + break; + } + case HP_HEX: + { + hpel.type = hpel.type = ClassifyHex(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces, + face_edges, surf_edges, facepoint); + break; + } + case HP_TRIG: + { + int dim = mesh.GetDimension(); + const FaceDescriptor & fd = mesh.GetFaceDescriptor (hpel.GetIndex()); + + hpel.type = ClassifyTrig(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, + faces, face_edges, surf_edges, facepoint, dim, fd); + + dd = 2; + break; + } + case HP_QUAD: + { + int dim = mesh.GetDimension(); + const FaceDescriptor & fd = mesh.GetFaceDescriptor (hpel.GetIndex()); + hpel.type = ClassifyQuad(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, + faces, face_edges, surf_edges, facepoint, dim, fd); + + dd = 2; + break; + } + case HP_SEGM: + { + hpel.type = ClassifySegm(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, + faces, face_edges, surf_edges, facepoint); + dd = 1; + break; + } + case HP_PYRAMID: + { + hpel.type = ClassifyPyramid(hpel, edges, edgepoint_dom, cornerpoint, edgepoint, faces, + face_edges, surf_edges, facepoint); + + cout << " ** Pyramid classified " << hpel.type << endl; + break; + } + default: + { + cout << "illegal element type for hp-prepare elements " << hpel.type << endl; + throw NgException ("hprefinement.cpp: don't know how to set parameters"); + } + } + + if(hpel.type == HP_NONE) + cnt_undef++; + + //else + //cout << "elem " << i << " classified type " << hpel.type << endl; + + + + if (!Get_HPRef_Struct (hpel.type)) + { + (*testout) << "hp-element-type " << hpel.type << " not implemented " << endl; + (*testout) << " elType " << hprs->geom << endl; + (cout) << " elType " << hprs->geom << endl; + cnt_nonimplement++; + misses[hpel.type]++; + } + + + for(int j=0; jgeom) + { + case HP_SEGM: np=2; sing_edge_left=0; sing_edge_right=0; break; + case HP_QUAD: np=4; break; + case HP_TRIG: np=3; break; + case HP_HEX: np=8; break; + case HP_PRISM: np=6; break; + case HP_TET: np=4; break; + case HP_PYRAMID: np=5; break; + } + index = el.index; + levelx = el.levelx; + levely = el.levely; + levelz = el.levelz; + type = el.type; + coarse_elnr = el.coarse_elnr; + singedge_left = el.singedge_left; + singedge_right = el.singedge_left; + } */ + + HPREF_ELEMENT_TYPE type; + PointIndex pnums[8]; + double param[8][3]; + int index; + int levelx; + int levely; + int levelz; + int np; + int coarse_elnr; + int domin, domout; // he: needed for segment!! in 3d there should be surf1, surf2!! + // int coarse_hpelnr; + PointIndex & operator[](int i) { return(pnums[i]);} + PointIndex & PNumMod(int i) { return pnums[(i-1) % np]; }; + PointIndex & PNum(int i) {return pnums[(i-1)]; }; + int GetIndex () const { return index; }; + double singedge_left, singedge_right; + + + // EdgePointGeomInfo epgeominfo[2]; + +}; + + + +extern void HPRefinement (Mesh & mesh, Refinement * ref, int levels, + double fac1=0.125, bool setorders=true, bool ref_level = false); + + +#endif + diff --git a/libsrc/meshing/improve2.cpp b/libsrc/meshing/improve2.cpp new file mode 100644 index 00000000..bd62bdd0 --- /dev/null +++ b/libsrc/meshing/improve2.cpp @@ -0,0 +1,853 @@ +#include + +#include "meshing.hpp" +#include + +#ifndef SMALLLIB +//#ifndef NOTCL +//#include +//#endif +#endif + +namespace netgen +{ + + class Neighbour + { + int nr[3]; + int orient[3]; + + public: + Neighbour () { ; } + + void SetNr (int side, int anr) { nr[side] = anr; } + int GetNr (int side) { return nr[side]; } + + void SetOrientation (int side, int aorient) { orient[side] = aorient; } + int GetOrientation (int side) { return orient[side]; } + + + + /* + void SetNr1 (int side, int anr) { nr[side-1] = anr; } + int GetNr1 (int side) { return nr[side-1]; } + + void SetOrientation1 (int side, int aorient) { orient[side-1] = aorient; } + int GetOrientation1 (int side) { return orient[side-1]; } + */ + }; + + + + + class trionedge + { + public: + int tnr; + int sidenr; + + trionedge () { tnr = 0; sidenr = 0; } + trionedge (int atnr, int asidenr) + { tnr = atnr; sidenr = asidenr; } + }; + + + + + void MeshOptimize2d :: EdgeSwapping (Mesh & mesh, int usemetric) + { + if (!faceindex) + { + if (usemetric) + PrintMessage (3, "Edgeswapping, metric"); + else + PrintMessage (3, "Edgeswapping, topological"); + + for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) + { + EdgeSwapping (mesh, usemetric); + + if (multithread.terminate) + throw NgException ("Meshing stopped"); + } + + faceindex = 0; + mesh.CalcSurfacesOfNode(); + return; + } + + + static int timer = NgProfiler::CreateTimer ("EdgeSwapping 2D"); + NgProfiler::RegionTimer reg1 (timer); + + static int timerstart = NgProfiler::CreateTimer ("EdgeSwapping 2D start"); + NgProfiler::StartTimer (timerstart); + + + Array seia; + mesh.GetSurfaceElementsOfFace (faceindex, seia); + + for (int i = 0; i < seia.Size(); i++) + if (mesh[seia[i]].GetNP() != 3) + { + GenericImprove (mesh); + return; + } + + int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr(); + + Array neighbors(mesh.GetNSE()); + INDEX_2_HASHTABLE other(seia.Size() + 2); + + + Array swapped(mesh.GetNSE()); + Array pdef(mesh.GetNP()); + Array pangle(mesh.GetNP()); + + + // int e; + // double d; + // Vec3d nv1, nv2; + + // double loch(-1); + static const double minangle[] = { 0, 1.481, 2.565, 3.627, 4.683, 5.736, 7, 9 }; + + + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & sel = mesh[seia[i]]; + for (int j = 0; j < 3; j++) + pangle[sel[j]] = 0.0; + } + // pangle = 0; + + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & sel = mesh[seia[i]]; + for (int j = 0; j < 3; j++) + { + POINTTYPE typ = mesh[sel[j]].Type(); + if (typ == FIXEDPOINT || typ == EDGEPOINT) + { + pangle[sel[j]] += + Angle (mesh[sel[(j+1)%3]] - mesh[sel[j]], + mesh[sel[(j+2)%3]] - mesh[sel[j]]); + } + } + } + + // for (PointIndex pi = PointIndex::BASE; + // pi < mesh.GetNP()+PointIndex::BASE; pi++) + + // pdef = 0; + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & sel = mesh[seia[i]]; + for (int j = 0; j < 3; j++) + { + PointIndex pi = sel[j]; + if (mesh[pi].Type() == INNERPOINT || mesh[pi].Type() == SURFACEPOINT) + pdef[pi] = -6; + else + for (int j = 0; j < 8; j++) + if (pangle[pi] >= minangle[j]) + pdef[pi] = -1-j; + } + } + + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & sel = mesh[seia[i]]; + for (int j = 0; j < 3; j++) + pdef[sel[j]]++; + } + + for (int i = 0; i < seia.Size(); i++) + { + for (int j = 0; j < 3; j++) + { + neighbors[seia[i]].SetNr (j, -1); + neighbors[seia[i]].SetOrientation (j, 0); + } + } + + /* + Array normals(mesh.GetNP()); + for (i = 1; i <= mesh.GetNSE(); i++) + { + Element2d & hel = mesh.SurfaceElement(i); + if (hel.GetIndex() == faceindex) + for (k = 1; k <= 3; k++) + { + int pi = hel.PNum(k); + SelectSurfaceOfPoint (mesh.Point(pi), hel.GeomInfoPi(k)); + int surfi = mesh.GetFaceDescriptor(faceindex).SurfNr(); + GetNormalVector (surfi, mesh.Point(pi), normals.Elem(pi)); + normals.Elem(pi) /= normals.Elem(pi).Length(); + } + } + */ + + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & sel = mesh[seia[i]]; + + for (int j = 0; j < 3; j++) + { + PointIndex pi1 = sel.PNumMod(j+2); + PointIndex pi2 = sel.PNumMod(j+3); + + // double loch = mesh.GetH(mesh[pi1]); + + INDEX_2 edge(pi1, pi2); + edge.Sort(); + + if (mesh.IsSegment (pi1, pi2)) + continue; + + /* + if (segments.Used (edge)) + continue; + */ + INDEX_2 ii2 (pi1, pi2); + if (other.Used (ii2)) + { + // INDEX_2 i2s(ii2); + // i2s.Sort(); + + int i2 = other.Get(ii2).tnr; + int j2 = other.Get(ii2).sidenr; + + neighbors[seia[i]].SetNr (j, i2); + neighbors[seia[i]].SetOrientation (j, j2); + neighbors[i2].SetNr (j2, seia[i]); + neighbors[i2].SetOrientation (j2, j); + } + else + { + other.Set (INDEX_2 (pi2, pi1), trionedge (seia[i], j)); + } + } + } + + for (int i = 0; i < seia.Size(); i++) + swapped[seia[i]] = 0; + + NgProfiler::StopTimer (timerstart); + + + + int t = 4; + int done = 0; + while (!done && t >= 2) + { + for (int i = 0; i < seia.Size(); i++) + { + SurfaceElementIndex t1 = seia[i]; + + if (mesh[t1].IsDeleted()) + continue; + + if (mesh[t1].GetIndex() != faceindex) + continue; + + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + for (int o1 = 0; o1 < 3; o1++) + { + bool should; + + + SurfaceElementIndex t2 = neighbors[t1].GetNr (o1); + int o2 = neighbors[t1].GetOrientation (o1); + + if (t2 == -1) continue; + if (swapped[t1] || swapped[t2]) continue; + + + PointIndex pi1 = mesh[t1].PNumMod(o1+1+1); + PointIndex pi2 = mesh[t1].PNumMod(o1+1+2); + PointIndex pi3 = mesh[t1].PNumMod(o1+1); + PointIndex pi4 = mesh[t2].PNumMod(o2+1); + + PointGeomInfo gi1 = mesh[t1].GeomInfoPiMod(o1+1+1); + PointGeomInfo gi2 = mesh[t1].GeomInfoPiMod(o1+1+2); + PointGeomInfo gi3 = mesh[t1].GeomInfoPiMod(o1+1); + PointGeomInfo gi4 = mesh[t2].GeomInfoPiMod(o2+1); + + bool allowswap = true; + + Vec<3> auxvec1 = mesh[pi3]-mesh[pi4]; + Vec<3> auxvec2 = mesh[pi1]-mesh[pi4]; + + allowswap = allowswap && fabs(1.-(auxvec1*auxvec2)/(auxvec1.Length()*auxvec2.Length())) > 1e-4; + + if(!allowswap) + continue; + + // normal of new + Vec<3> nv1 = Cross (auxvec1, auxvec2); + + auxvec1 = mesh.Point(pi4)-mesh.Point(pi3); + auxvec2 = mesh.Point(pi2)-mesh.Point(pi3); + allowswap = allowswap && fabs(1.-(auxvec1*auxvec2)/(auxvec1.Length()*auxvec2.Length())) > 1e-4; + + + if(!allowswap) + continue; + + Vec<3> nv2 = Cross (auxvec1, auxvec2); + + + // normals of original + Vec<3> nv3 = Cross (mesh[pi1]-mesh[pi4], mesh[pi2]-mesh[pi4]); + Vec<3> nv4 = Cross (mesh[pi2]-mesh[pi3], mesh[pi1]-mesh[pi3]); + + nv3 *= -1; + nv4 *= -1; + nv3.Normalize(); + nv4.Normalize(); + + nv1.Normalize(); + nv2.Normalize(); + + Vec<3> nvp3, nvp4; + SelectSurfaceOfPoint (mesh.Point(pi3), gi3); + GetNormalVector (surfnr, mesh.Point(pi3), gi3, nvp3); + + nvp3.Normalize(); + + SelectSurfaceOfPoint (mesh.Point(pi4), gi4); + GetNormalVector (surfnr, mesh.Point(pi4), gi4, nvp4); + + nvp4.Normalize(); + + + + double critval = cos (M_PI / 6); // 30 degree + allowswap = allowswap && + (nv1 * nvp3 > critval) && + (nv1 * nvp4 > critval) && + (nv2 * nvp3 > critval) && + (nv2 * nvp4 > critval) && + (nvp3 * nv3 > critval) && + (nvp4 * nv4 > critval); + + + double horder = Dist (mesh.Point(pi1), mesh.Point(pi2)); + + if ( // nv1 * nv2 >= 0 && + nv1.Length() > 1e-3 * horder * horder && + nv2.Length() > 1e-3 * horder * horder && + allowswap ) + { + if (!usemetric) + { + int e = pdef[pi1] + pdef[pi2] - pdef[pi3] - pdef[pi4]; + double d = + Dist2 (mesh.Point(pi1), mesh.Point(pi2)) - + Dist2 (mesh.Point(pi3), mesh.Point(pi4)); + + should = e >= t && (e > 2 || d > 0); + } + else + { + double loch = mesh.GetH(mesh[pi1]); + should = + CalcTriangleBadness (mesh.Point(pi4), mesh.Point(pi3), mesh.Point(pi1), + metricweight, loch) + + CalcTriangleBadness (mesh.Point(pi3), mesh.Point(pi4), mesh.Point(pi2), + metricweight, loch) < + CalcTriangleBadness (mesh.Point(pi1), mesh.Point(pi2), mesh.Point(pi3), + metricweight, loch) + + CalcTriangleBadness (mesh.Point(pi2), mesh.Point(pi1), mesh.Point(pi4), + metricweight, loch); + + } + + if (allowswap) + { + Element2d sw1 (pi4, pi3, pi1); + Element2d sw2 (pi3, pi4, pi2); + + int legal1 = + mesh.LegalTrig (mesh.SurfaceElement (t1)) + + mesh.LegalTrig (mesh.SurfaceElement (t2)); + int legal2 = + mesh.LegalTrig (sw1) + mesh.LegalTrig (sw2); + + if (legal1 < legal2) should = 1; + if (legal2 < legal1) should = 0; + } + + if (should) + { + // do swapping ! + + done = 1; + + mesh[t1].PNum(1) = pi1; + mesh[t1].PNum(2) = pi4; + mesh[t1].PNum(3) = pi3; + + mesh[t2].PNum(1) = pi2; + mesh[t2].PNum(2) = pi3; + mesh[t2].PNum(3) = pi4; + + mesh[t1].GeomInfoPi(1) = gi1; + mesh[t1].GeomInfoPi(2) = gi4; + mesh[t1].GeomInfoPi(3) = gi3; + + mesh[t2].GeomInfoPi(1) = gi2; + mesh[t2].GeomInfoPi(2) = gi3; + mesh[t2].GeomInfoPi(3) = gi4; + + pdef[pi1]--; + pdef[pi2]--; + pdef[pi3]++; + pdef[pi4]++; + + swapped[t1] = 1; + swapped[t2] = 1; + } + } + } + } + t--; + } + + mesh.SetNextTimeStamp(); + } + + + + + + + + + void MeshOptimize2d :: CombineImprove (Mesh & mesh) + { + if (!faceindex) + { + PrintMessage (3, "Combine improve"); + + for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) + { + CombineImprove (mesh); + + if (multithread.terminate) + throw NgException ("Meshing stopped"); + } + faceindex = 0; + return; + } + + + static int timer = NgProfiler::CreateTimer ("Combineimprove 2D"); + NgProfiler::RegionTimer reg (timer); + + static int timerstart = NgProfiler::CreateTimer ("Combineimprove 2D start"); + NgProfiler::StartTimer (timerstart); + + + static int timerstart1 = NgProfiler::CreateTimer ("Combineimprove 2D start1"); + NgProfiler::StartTimer (timerstart1); + + + + // int i, j, k, l; + // PointIndex pi; + // SurfaceElementIndex sei; + + + Array seia; + mesh.GetSurfaceElementsOfFace (faceindex, seia); + + + for (int i = 0; i < seia.Size(); i++) + if (mesh[seia[i]].GetNP() != 3) + return; + + + + int surfnr = 0; + if (faceindex) + surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr(); + + + // PointIndex pi1, pi2; + // MeshPoint p1, p2, pnew; + double bad1, bad2; + Vec<3> nv; + + int np = mesh.GetNP(); + //int nse = mesh.GetNSE(); + + TABLE elementsonnode(np); + Array hasonepi, hasbothpi; + + for (int i = 0; i < seia.Size(); i++) + { + Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + elementsonnode.Add (el[j], seia[i]); + } + + Array fixed(np); + fixed = false; + + NgProfiler::StopTimer (timerstart1); + + /* + for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) + { + INDEX_2 i2(mesh[si][0], mesh[si][1]); + fixed[i2.I1()] = true; + fixed[i2.I2()] = true; + } + */ + + for (int i = 0; i < seia.Size(); i++) + { + Element2d & sel = mesh[seia[i]]; + for (int j = 0; j < sel.GetNP(); j++) + { + PointIndex pi1 = sel.PNumMod(j+2); + PointIndex pi2 = sel.PNumMod(j+3); + if (mesh.IsSegment (pi1, pi2)) + { + fixed[pi1] = true; + fixed[pi2] = true; + } + } + } + + + + for(int i = 0; i < mesh.LockedPoints().Size(); i++) + fixed[mesh.LockedPoints()[i]] = true; + + + + Array,PointIndex::BASE> normals(np); + + for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++) + { + if (elementsonnode[pi].Size()) + { + Element2d & hel = mesh[elementsonnode[pi][0]]; + for (int k = 0; k < 3; k++) + if (hel[k] == pi) + { + SelectSurfaceOfPoint (mesh[pi], hel.GeomInfoPi(k+1)); + GetNormalVector (surfnr, mesh[pi], hel.GeomInfoPi(k+1), normals[pi]); + break; + } + } + } + + NgProfiler::StopTimer (timerstart); + + for (int i = 0; i < seia.Size(); i++) + { + SurfaceElementIndex sei = seia[i]; + Element2d & elem = mesh[sei]; + if (elem.IsDeleted()) continue; + + for (int j = 0; j < 3; j++) + { + PointIndex pi1 = elem[j]; + PointIndex pi2 = elem[(j+1) % 3]; + + if (pi1 < PointIndex::BASE || + pi2 < PointIndex::BASE) + continue; + + /* + INDEX_2 i2(pi1, pi2); + i2.Sort(); + if (segmentht.Used(i2)) + continue; + */ + + bool debugflag = 0; + + if (debugflag) + { + (*testout) << "Combineimprove, face = " << faceindex + << "pi1 = " << pi1 << " pi2 = " << pi2 << endl; + } + + /* + // save version: + if (fixed.Get(pi1) || fixed.Get(pi2)) + continue; + if (pi2 < pi1) swap (pi1, pi2); + */ + + // more general + if (fixed[pi2]) + Swap (pi1, pi2); + + if (fixed[pi2]) + continue; + + double loch = mesh.GetH (mesh[pi1]); + + INDEX_2 si2 (pi1, pi2); + si2.Sort(); + + /* + if (edgetested.Used (si2)) + continue; + edgetested.Set (si2, 1); + */ + + hasonepi.SetSize(0); + hasbothpi.SetSize(0); + + for (int k = 0; k < elementsonnode[pi1].Size(); k++) + { + const Element2d & el2 = mesh[elementsonnode[pi1][k]]; + + if (el2.IsDeleted()) continue; + + if (el2[0] == pi2 || el2[1] == pi2 || el2[2] == pi2) + { + hasbothpi.Append (elementsonnode[pi1][k]); + nv = Cross (Vec3d (mesh[el2[0]], mesh[el2[1]]), + Vec3d (mesh[el2[0]], mesh[el2[2]])); + } + else + { + hasonepi.Append (elementsonnode[pi1][k]); + } + } + + + Element2d & hel = mesh[hasbothpi[0]]; + for (int k = 0; k < 3; k++) + if (hel[k] == pi1) + { + SelectSurfaceOfPoint (mesh[pi1], + hel.GeomInfoPi(k+1)); + GetNormalVector (surfnr, mesh[pi1], hel.GeomInfoPi(k+1), nv); + break; + } + + // nv = normals.Get(pi1); + + + + for (int k = 0; k < elementsonnode[pi2].Size(); k++) + { + const Element2d & el2 = mesh[elementsonnode[pi2][k]]; + if (el2.IsDeleted()) continue; + + if (el2[0] == pi1 || el2[1] == pi1 || el2[2] == pi1) + ; + else + hasonepi.Append (elementsonnode[pi2][k]); + } + + bad1 = 0; + int illegal1 = 0, illegal2 = 0; + for (int k = 0; k < hasonepi.Size(); k++) + { + const Element2d & el = mesh[hasonepi[k]]; + bad1 += CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]], + nv, -1, loch); + illegal1 += 1-mesh.LegalTrig(el); + } + + for (int k = 0; k < hasbothpi.Size(); k++) + { + const Element2d & el = mesh[hasbothpi[k]]; + bad1 += CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]], + nv, -1, loch); + illegal1 += 1-mesh.LegalTrig(el); + } + bad1 /= (hasonepi.Size()+hasbothpi.Size()); + + MeshPoint p1 = mesh[pi1]; + MeshPoint p2 = mesh[pi2]; + + MeshPoint pnew = p1; + mesh[pi1] = pnew; + mesh[pi2] = pnew; + + bad2 = 0; + for (int k = 0; k < hasonepi.Size(); k++) + { + Element2d & el = mesh[hasonepi[k]]; + double err = + CalcTriangleBadness (mesh[el[0]], mesh[el[1]], mesh[el[2]], + nv, -1, loch); + bad2 += err; + + Vec<3> hnv = Cross (Vec3d (mesh[el[0]], + mesh[el[1]]), + Vec3d (mesh[el[0]], + mesh[el[2]])); + if (hnv * nv < 0) + bad2 += 1e10; + + for (int l = 0; l < 3; l++) + if ( (normals[el[l]] * nv) < 0.5) + bad2 += 1e10; + + illegal2 += 1-mesh.LegalTrig(el); + } + bad2 /= hasonepi.Size(); + + mesh[pi1] = p1; + mesh[pi2] = p2; + + + if (debugflag) + { + (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl; + } + + + bool should = (bad2 < bad1 && bad2 < 1e4); + if (bad2 < 1e4) + { + if (illegal1 > illegal2) should = 1; + if (illegal2 > illegal1) should = 0; + } + + + if (should) + { + // (*testout) << "combine !" << endl; + // (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl; + + + mesh[pi1] = pnew; + PointGeomInfo gi; + // bool gi_set(false); + + + Element2d *el1p(NULL); + int l = 0; + while(mesh[elementsonnode[pi1][l]].IsDeleted() && lGetNP(); l++) + if ((*el1p)[l] == pi1) + { + gi = el1p->GeomInfoPi (l+1); + // gi_set = true; + } + + // (*testout) << "Connect point " << pi2 << " to " << pi1 << "\n"; + for (int k = 0; k < elementsonnode[pi2].Size(); k++) + { + Element2d & el = mesh[elementsonnode[pi2][k]]; + if(el.IsDeleted()) continue; + elementsonnode.Add (pi1, elementsonnode[pi2][k]); + + bool haspi1 = 0; + for (l = 0; l < el.GetNP(); l++) + if (el[l] == pi1) + haspi1 = 1; + if (haspi1) continue; + + for (int l = 0; l < el.GetNP(); l++) + { + if (el[l] == pi2) + { + el[l] = pi1; + el.GeomInfoPi (l+1) = gi; + } + + fixed[el[l]] = true; + } + } + + /* + for (k = 0; k < hasbothpi.Size(); k++) + { + cout << mesh[hasbothpi[k]] << endl; + for (l = 0; l < 3; l++) + cout << mesh[mesh[hasbothpi[k]][l]] << " "; + cout << endl; + } + */ + + for (int k = 0; k < hasbothpi.Size(); k++) + { + mesh[hasbothpi[k]].Delete(); + /* + for (l = 0; l < 4; l++) + mesh[hasbothpi[k]][l] = PointIndex::BASE-1; + */ + } + + } + } + } + + // mesh.Compress(); + mesh.SetNextTimeStamp(); + } + + + void MeshOptimize2d :: CheckMeshApproximation (Mesh & mesh) + { + // Check angles between elements and normals at corners + /* + + int i, j; + int ne = mesh.GetNSE(); + int surfnr; + + Vec3d n, ng; + Array ngs(3); + + (*mycout) << "Check Surface Approxiamtion" << endl; + (*testout) << "Check Surface Approxiamtion" << endl; + + for (i = 1; i <= ne; i++) + { + const Element2d & el = mesh.SurfaceElement(i); + surfnr = mesh.GetFaceDescriptor (el.GetIndex()).SurfNr(); + Vec3d n = Cross (mesh.Point (el.PNum(1)) - mesh.Point (el.PNum(2)), + mesh.Point (el.PNum(1)) - mesh.Point (el.PNum(3))); + n /= n.Length(); + + for (j = 1; j <= el.GetNP(); j++) + { + SelectSurfaceOfPoint (mesh.Point(el.PNum(j)), el.GeomInfoPi(j)); + GetNormalVector (surfnr, mesh.Point(el.PNum(j)), ng); + ng /= ng.Length(); + ngs.Elem(j) = ng; + + double angle = (180.0 / M_PI) * Angle (n, ng); + if (angle > 60) + { + (*testout) << "el " << i << " node " << el.PNum(j) + << "has angle = " << angle << endl; + } + } + + for (j = 1; j <= 3; j++) + { + double angle = (180.0 / M_PI) * Angle (ngs.Get(j), ngs.Get(j%3+1)); + if (angle > 60) + { + (*testout) << "el " << i << " node-node " + << ngs.Get(j) << " - " << ngs.Get(j%3+1) + << " has angle = " << angle << endl; + } + } + } + */ + } +} diff --git a/libsrc/meshing/improve2.hpp b/libsrc/meshing/improve2.hpp new file mode 100644 index 00000000..dad6a3ae --- /dev/null +++ b/libsrc/meshing/improve2.hpp @@ -0,0 +1,102 @@ +#ifndef FILE_IMPROVE2 +#define FILE_IMPROVE2 + + + +/// +class MeshOptimize2d +{ + int faceindex; + int improveedges; + double metricweight; + int writestatus; + +public: + /// + MeshOptimize2d (); + /// + void ImproveMesh (Mesh & mesh2d, const MeshingParameters & mp); + void ImproveMeshJacobian (Mesh & mesh2d, const MeshingParameters & mp); + void ImproveVolumeMesh (Mesh & mesh); + void ProjectBoundaryPoints(Array & surfaceindex, + const Array* > & from, Array* > & dest); + + void EdgeSwapping (Mesh & mesh, int usemetric); + void CombineImprove (Mesh & mesh); + + void GenericImprove (Mesh & mesh); + + + void SetFaceIndex (int fi) { faceindex = fi; } + void SetImproveEdges (int ie) { improveedges = ie; } + void SetMetricWeight (double mw) { metricweight = mw; } + void SetWriteStatus (int ws) { writestatus = ws; } + + + + /// + virtual void SelectSurfaceOfPoint (const Point<3> & p, + const PointGeomInfo & gi); + /// + virtual void ProjectPoint (INDEX /* surfind */, Point<3> & /* p */) const { }; + + /// project point, use gi as initial value, and compute new gi + virtual int ProjectPointGI (INDEX surfind, Point<3> & p, PointGeomInfo & gi) const + { ProjectPoint (surfind, p); return CalcPointGeomInfo (surfind, gi, p); } + + /// + virtual void ProjectPoint2 (INDEX /* surfind */, INDEX /* surfind2 */, Point<3> & /* p */) const { }; + + /// liefert zu einem 3d-Punkt die geominfo (Dreieck) und liefert 1, wenn erfolgreich, + /// 0, wenn nicht (Punkt ausserhalb von chart) + virtual int CalcPointGeomInfo(PointGeomInfo& gi, const Point<3> & /*p3*/) const + { gi.trignum = 1; return 1;}; + + virtual int CalcPointGeomInfo(int /* surfind */, PointGeomInfo& gi, const Point<3> & p3) const + { return CalcPointGeomInfo (gi, p3); } + + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, PointGeomInfo & gi, Vec<3> & n) const; + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const; + + void CheckMeshApproximation (Mesh & mesh); + + + /// + friend class Opti2SurfaceMinFunction; + /// + friend class Opti2EdgeMinFunction; + /// + friend double Opti2FunctionValueGrad (const Vector & x, Vector & grad); + /// + friend double Opti2EdgeFunctionValueGrad (const Vector & x, Vector & grad); + + + +}; + + +extern void CalcTriangleBadness (double x2, double x3, double y3, + double metricweight, + double h, double & badness, + double & g1x, double & g1y); + + + + +extern double CalcTriangleBadness (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + double metricweight, + double h); + +extern double CalcTriangleBadness (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + const Vec<3> & n, + double metricweight, + double h); + +#endif + + diff --git a/libsrc/meshing/improve2gen.cpp b/libsrc/meshing/improve2gen.cpp new file mode 100644 index 00000000..fab74c66 --- /dev/null +++ b/libsrc/meshing/improve2gen.cpp @@ -0,0 +1,455 @@ +#include + +#include "meshing.hpp" +#include + +namespace netgen +{ + + class ImprovementRule + { + public: + Array oldels; + Array newels; + Array deledges; + Array incelsonnode; + Array reused; + int bonus; + int onp; + }; + + + void MeshOptimize2d :: GenericImprove (Mesh & mesh) + { + if (!faceindex) + { + if (writestatus) + PrintMessage (3, "Generic Improve"); + + for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) + GenericImprove (mesh); + + faceindex = 0; + } + + // int j, k, l, ri; + int np = mesh.GetNP(); + int ne = mesh.GetNSE(); + // SurfaceElementIndex sei; + + +// for (SurfaceElementIndex sei = 0; sei < ne; sei++) +// { +// const Element2d & el = mesh[sei]; +// (*testout) << "element " << sei << ": " < rules; + Array elmap; + Array elrot; + Array pmap; + Array pgi; + + int surfnr = mesh.GetFaceDescriptor (faceindex).SurfNr(); + + ImprovementRule * r1; + + // 2 triangles to quad + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3)); + r1->oldels.Append (Element2d (3, 2, 4)); + r1->newels.Append (Element2d (1, 2, 4, 3)); + r1->deledges.Append (INDEX_2 (2,3)); + r1->onp = 4; + r1->bonus = 2; + rules.Append (r1); + + // 2 quad to 1 quad + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (4, 3, 2, 5)); + r1->newels.Append (Element2d (1, 2, 5, 4)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->deledges.Append (INDEX_2 (3, 4)); + r1->onp = 5; + r1->bonus = 0; + rules.Append (r1); + + // swap quads + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (3, 2, 5, 6)); + r1->newels.Append (Element2d (1, 6, 3, 4)); + r1->newels.Append (Element2d (1, 2, 5, 6)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->onp = 6; + r1->bonus = 0; + rules.Append (r1); + + // three quads to 2 + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (2, 5, 6, 3)); + r1->oldels.Append (Element2d (3, 6, 7, 4)); + r1->newels.Append (Element2d (1, 2, 5, 4)); + r1->newels.Append (Element2d (4, 5, 6, 7)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->deledges.Append (INDEX_2 (3, 4)); + r1->deledges.Append (INDEX_2 (3, 6)); + r1->onp = 7; + r1->bonus = -1; + rules.Append (r1); + + // quad + 2 connected trigs to quad + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (2, 5, 3)); + r1->oldels.Append (Element2d (3, 5, 4)); + r1->newels.Append (Element2d (1, 2, 5, 4)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->deledges.Append (INDEX_2 (3, 4)); + r1->deledges.Append (INDEX_2 (3, 5)); + r1->onp = 5; + r1->bonus = 0; + rules.Append (r1); + + // quad + 2 non-connected trigs to quad (a and b) + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (2, 6, 3)); + r1->oldels.Append (Element2d (1, 4, 5)); + r1->newels.Append (Element2d (1, 3, 4, 5)); + r1->newels.Append (Element2d (1, 2, 6, 3)); + r1->deledges.Append (INDEX_2 (1, 4)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->onp = 6; + r1->bonus = 0; + rules.Append (r1); + + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (2, 6, 3)); + r1->oldels.Append (Element2d (1, 4, 5)); + r1->newels.Append (Element2d (1, 2, 4, 5)); + r1->newels.Append (Element2d (4, 2, 6, 3)); + r1->deledges.Append (INDEX_2 (1, 4)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->onp = 6; + r1->bonus = 0; + rules.Append (r1); + + // two quad + trig -> one quad + trig + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (2, 5, 6, 3)); + r1->oldels.Append (Element2d (4, 3, 6)); + r1->newels.Append (Element2d (1, 2, 6, 4)); + r1->newels.Append (Element2d (2, 5, 6)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->deledges.Append (INDEX_2 (3, 4)); + r1->deledges.Append (INDEX_2 (3, 6)); + r1->onp = 6; + r1->bonus = -1; + rules.Append (r1); + + // swap quad + trig (a and b) + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (2, 5, 3)); + r1->newels.Append (Element2d (2, 5, 3, 4)); + r1->newels.Append (Element2d (1, 2, 4)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->onp = 5; + r1->bonus = 0; + rules.Append (r1); + + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (2, 5, 3)); + r1->newels.Append (Element2d (1, 2, 5, 3)); + r1->newels.Append (Element2d (1, 3, 4)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->onp = 5; + r1->bonus = 0; + rules.Append (r1); + + + // 2 quads to quad + 2 trigs + r1 = new ImprovementRule; + r1->oldels.Append (Element2d (1, 2, 3, 4)); + r1->oldels.Append (Element2d (3, 2, 5, 6)); + r1->newels.Append (Element2d (1, 5, 6, 4)); + r1->newels.Append (Element2d (1, 2, 5)); + r1->newels.Append (Element2d (4, 6, 3)); + r1->deledges.Append (INDEX_2 (2, 3)); + r1->onp = 6; + r1->bonus = 0; + // rules.Append (r1); + + + + + Array mapped(rules.Size()); + Array used(rules.Size()); + used = 0; + mapped = 0; + + + + for (int ri = 0; ri < rules.Size(); ri++) + { + ImprovementRule & rule = *rules[ri]; + rule.incelsonnode.SetSize (rule.onp); + rule.reused.SetSize (rule.onp); + + for (int j = 1; j <= rule.onp; j++) + { + rule.incelsonnode.Elem(j) = 0; + rule.reused.Elem(j) = 0; + } + + for (int j = 1; j <= rule.oldels.Size(); j++) + { + const Element2d & el = rule.oldels.Elem(j); + for (int k = 1; k <= el.GetNP(); k++) + rule.incelsonnode.Elem(el.PNum(k))--; + } + + for (int j = 1; j <= rule.newels.Size(); j++) + { + const Element2d & el = rule.newels.Elem(j); + for (int k = 1; k <= el.GetNP(); k++) + { + rule.incelsonnode.Elem(el.PNum(k))++; + rule.reused.Elem(el.PNum(k)) = 1; + } + } + } + + + + + TABLE elonnode(np); + Array nelonnode(np); + TABLE nbels(ne); + + nelonnode = -4; + + for (SurfaceElementIndex sei = 0; sei < ne; sei++) + { + const Element2d & el = mesh[sei]; + + if (el.GetIndex() == faceindex && !el.IsDeleted()) + { + for (int j = 0; j < el.GetNP(); j++) + elonnode.Add (el[j], sei); + } + if(!el.IsDeleted()) + { + for (int j = 0; j < el.GetNP(); j++) + nelonnode[el[j]]++; + } + } + + for (SurfaceElementIndex sei = 0; sei < ne; sei++) + { + const Element2d & el = mesh[sei]; + if (el.GetIndex() == faceindex && !el.IsDeleted()) + { + for (int j = 0; j < el.GetNP(); j++) + { + for (int k = 0; k < elonnode[el[j]].Size(); k++) + { + int nbel = elonnode[el[j]] [k]; + bool inuse = false; + for (int l = 0; l < nbels[sei].Size(); l++) + if (nbels[sei][l] == nbel) + inuse = true; + if (!inuse) + nbels.Add (sei, nbel); + } + } + } + } + + + for (int ri = 0; ri < rules.Size(); ri++) + { + const ImprovementRule & rule = *rules[ri]; + + elmap.SetSize (rule.oldels.Size()); + elrot.SetSize (rule.oldels.Size()); + pmap.SetSize (rule.onp); + pgi.SetSize (rule.onp); + + + for (SurfaceElementIndex sei = 0; sei < ne; sei++) + { + if (multithread.terminate) + break; + if (mesh[sei].IsDeleted()) continue; + + elmap[0] = sei; + FlatArray neighbours = nbels[sei]; + + for (elrot[0] = 0; elrot[0] < mesh[sei].GetNP(); elrot[0]++) + { + const Element2d & el0 = mesh[sei]; + const Element2d & rel0 = rule.oldels[0]; + + if (el0.GetIndex() != faceindex) continue; + if (el0.IsDeleted()) continue; + if (el0.GetNP() != rel0.GetNP()) continue; + + + pmap = PointIndex (-1); + + for (int k = 0; k < el0.GetNP(); k++) + { + pmap.Elem(rel0[k]) = el0.PNumMod(k+elrot[0]+1); + pgi.Elem(rel0[k]) = el0.GeomInfoPiMod(k+elrot[0]+1); + } + + ok = 1; + for (int i = 1; i < elmap.Size(); i++) + { + // try to find a mapping for reference-element i + + const Element2d & rel = rule.oldels[i]; + bool possible = 0; + + for (elmap[i] = 0; elmap[i] < neighbours.Size(); elmap[i]++) + { + const Element2d & el = mesh[neighbours[elmap[i]]]; + if (el.IsDeleted()) continue; + if (el.GetNP() != rel.GetNP()) continue; + + for (elrot[i] = 0; elrot[i] < rel.GetNP(); elrot[i]++) + { + possible = 1; + + for (int k = 0; k < rel.GetNP(); k++) + if (pmap.Elem(rel[k]) != -1 && + pmap.Elem(rel[k]) != el.PNumMod (k+elrot[i]+1)) + possible = 0; + + if (possible) + { + for (int k = 0; k < el.GetNP(); k++) + { + pmap.Elem(rel[k]) = el.PNumMod(k+elrot[i]+1); + pgi.Elem(rel[k]) = el.GeomInfoPiMod(k+elrot[i]+1); + } + break; + } + } + if (possible) break; + } + + if (!possible) + { + ok = 0; + break; + } + + elmap[i] = neighbours[elmap[i]]; + } + + for(int i=0; ok && i olddef) + continue; + + // calc metric badness + double bad1 = 0, bad2 = 0; + Vec<3> n; + + SelectSurfaceOfPoint (mesh.Point(pmap.Get(1)), pgi.Get(1)); + GetNormalVector (surfnr, mesh.Point(pmap.Get(1)), pgi.Elem(1), n); + + for (int j = 1; j <= rule.oldels.Size(); j++) + bad1 += mesh.SurfaceElement(elmap.Get(j)).CalcJacobianBadness (mesh.Points(), n); + + // check new element: + for (int j = 1; j <= rule.newels.Size(); j++) + { + const Element2d & rnel = rule.newels.Get(j); + Element2d nel(rnel.GetNP()); + for (int k = 1; k <= rnel.GetNP(); k++) + nel.PNum(k) = pmap.Get(rnel.PNum(k)); + + bad2 += nel.CalcJacobianBadness (mesh.Points(), n); + } + + if (bad2 > 1e3) continue; + + if (newdef == olddef && bad2 > bad1) continue; + + + // generate new element: + for (int j = 1; j <= rule.newels.Size(); j++) + { + const Element2d & rnel = rule.newels.Get(j); + Element2d nel(rnel.GetNP()); + nel.SetIndex (faceindex); + for (int k = 1; k <= rnel.GetNP(); k++) + { + nel.PNum(k) = pmap.Get(rnel.PNum(k)); + nel.GeomInfoPi(k) = pgi.Get(rnel.PNum(k)); + } + + mesh.AddSurfaceElement(nel); + } + + for (int j = 0; j < rule.oldels.Size(); j++) + mesh.DeleteSurfaceElement ( elmap[j] ); + + for (int j = 1; j <= pmap.Size(); j++) + nelonnode[pmap.Get(j)] += rule.incelsonnode.Get(j); + + used[ri]++; + } + } + } + + mesh.Compress(); + + for (int ri = 0; ri < rules.Size(); ri++) + { + PrintMessage (5, "rule ", ri+1, " ", + mapped[ri], "/", used[ri], " mapped/used"); + } + } + + + + +} diff --git a/libsrc/meshing/improve3.cpp b/libsrc/meshing/improve3.cpp new file mode 100644 index 00000000..435ba4cd --- /dev/null +++ b/libsrc/meshing/improve3.cpp @@ -0,0 +1,2773 @@ +#include + +#include "meshing.hpp" + +#ifdef SOLIDGEOM +#include +#endif +#include + +namespace netgen +{ + +/* + Combine two points to one. + Set new point into the center, if both are + inner points. + Connect inner point to boundary point, if one + point is inner point. +*/ + +void MeshOptimize3d :: CombineImprove (Mesh & mesh, + OPTIMIZEGOAL goal) +{ + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + + TABLE elementsonnode(np); + Array hasonepi, hasbothpi; + + Array oneperr; + Array elerrs (ne); + + PrintMessage (3, "CombineImprove"); + (*testout) << "Start CombineImprove" << "\n"; + + // mesh.CalcSurfacesOfNode (); + const char * savetask = multithread.task; + multithread.task = "Combine Improve"; + + + double totalbad = 0; + for (ElementIndex ei = 0; ei < ne; ei++) + { + double elerr = CalcBad (mesh.Points(), mesh[ei], 0); + totalbad += elerr; + elerrs[ei] = elerr; + } + + if (goal == OPT_QUALITY) + { + totalbad = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << totalbad << endl; + PrintMessage (5, "Total badness = ", totalbad); + } + + for (ElementIndex ei = 0; ei < ne; ei++) + if (!mesh[ei].IsDeleted()) + for (int j = 0; j < mesh[ei].GetNP(); j++) + elementsonnode.Add (mesh[ei][j], ei); + + INDEX_2_HASHTABLE edgetested (np+1); + + int cnt = 0; + + for (ElementIndex ei = 0; ei < ne; ei++) + { + if (multithread.terminate) + break; + + multithread.percent = 100.0 * (ei+1) / ne; + + if (mesh.ElementType(ei) == FIXEDELEMENT) + continue; + + for (int j = 0; j < 6; j++) + { + Element & elemi = mesh[ei]; + if (elemi.IsDeleted()) continue; + + static const int tetedges[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + PointIndex pi1 = elemi[tetedges[j][0]]; + PointIndex pi2 = elemi[tetedges[j][1]]; + + if (pi2 < pi1) Swap (pi1, pi2); + + INDEX_2 si2 (pi1, pi2); + si2.Sort(); + + if (edgetested.Used (si2)) continue; + edgetested.Set (si2, 1); + + + // hasonepoint.SetSize(0); + // hasbothpoints.SetSize(0); + hasonepi.SetSize(0); + hasbothpi.SetSize(0); + + FlatArray row1 = elementsonnode[pi1]; + for (int k = 0; k < row1.Size(); k++) + { + Element & elem = mesh[row1[k]]; + if (elem.IsDeleted()) continue; + + if (elem[0] == pi2 || elem[1] == pi2 || + elem[2] == pi2 || elem[3] == pi2) + { + hasbothpi.Append (row1[k]); + } + else + { + hasonepi.Append (row1[k]); + } + } + + FlatArray row2 = elementsonnode[pi2]; + for (int k = 0; k < row2.Size(); k++) + { + Element & elem = mesh[row2[k]]; + if (elem.IsDeleted()) continue; + + if (elem[0] == pi1 || elem[1] == pi1 || + elem[2] == pi1 || elem[3] == pi1) + ; + else + { + hasonepi.Append (row2[k]); + } + } + + double bad1 = 0; + for (int k = 0; k < hasonepi.Size(); k++) + bad1 += elerrs[hasonepi[k]]; + for (int k = 0; k < hasbothpi.Size(); k++) + bad1 += elerrs[hasbothpi[k]]; + + MeshPoint p1 = mesh[pi1]; + MeshPoint p2 = mesh[pi2]; + + + // if (mesh.PointType(pi2) != INNERPOINT) + if (p2.Type() != INNERPOINT) + continue; + + MeshPoint pnew; + // if (mesh.PointType(pi1) != INNERPOINT) + if (p1.Type() != INNERPOINT) + pnew = p1; + else + pnew = Center (p1, p2); + + mesh[pi1] = pnew; + mesh[pi2] = pnew; + + oneperr.SetSize (hasonepi.Size()); + + double bad2 = 0; + for (int k = 0; k < hasonepi.Size(); k++) + { + const Element & elem = mesh[hasonepi[k]]; + double err = CalcBad (mesh.Points(), elem, 0); + // CalcTetBadness (mesh[elem[0]], mesh[elem[1]], + // mesh[elem[2]], mesh[elem[3]], 0, mparam); + bad2 += err; + oneperr[k] = err; + } + + mesh[pi1] = p1; + mesh[pi2] = p2; + + // if (mesh.PointType(pi1) != INNERPOINT) + if (p1.Type() != INNERPOINT) + { + for (int k = 0; k < hasonepi.Size(); k++) + { + Element & elem = mesh[hasonepi[k]]; + int l; + for (l = 0; l < 4; l++) + if (elem[l] == pi2) + { + elem[l] = pi1; + break; + } + + elem.flags.illegal_valid = 0; + if (!mesh.LegalTet(elem)) + bad2 += 1e4; + + if (l < 4) + { + elem.flags.illegal_valid = 0; + elem[l] = pi2; + } + } + } + + if (bad2 / hasonepi.Size() < + bad1 / (hasonepi.Size()+hasbothpi.Size())) + { + mesh[pi1] = pnew; + cnt++; + + FlatArray row = elementsonnode[pi2]; + for (int k = 0; k < row.Size(); k++) + { + Element & elem = mesh[row[k]]; + if (elem.IsDeleted()) continue; + + elementsonnode.Add (pi1, row[k]); + for (int l = 0; l < elem.GetNP(); l++) + if (elem[l] == pi2) + elem[l] = pi1; + + elem.flags.illegal_valid = 0; + if (!mesh.LegalTet (elem)) + (*testout) << "illegal tet " << elementsonnode[pi2][k] << endl; + } + + for (int k = 0; k < hasonepi.Size(); k++) + elerrs[hasonepi[k]] = oneperr[k]; + + for (int k = 0; k < hasbothpi.Size(); k++) + { + mesh[hasbothpi[k]].flags.illegal_valid = 0; + mesh[hasbothpi[k]].Delete(); + } + } + } + } + + mesh.Compress(); + mesh.MarkIllegalElements(); + + PrintMessage (5, cnt, " elements combined"); + (*testout) << "CombineImprove done" << "\n"; + + totalbad = 0; + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + totalbad += CalcBad (mesh.Points(), mesh[ei], 0); + + if (goal == OPT_QUALITY) + { + totalbad = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << totalbad << endl; + + int cntill = 0; + for (ElementIndex ei = 0; ei < ne; ei++) + if (!mesh.LegalTet (mesh[ei])) + cntill++; + + PrintMessage (5, cntill, " illegal tets"); + } + multithread.task = savetask; +} + + + + + +/* + Mesh improvement by edge splitting. + If mesh quality is improved by inserting a node into an inner edge, + the edge is split into two parts. +*/ +void MeshOptimize3d :: SplitImprove (Mesh & mesh, + OPTIMIZEGOAL goal) +{ + int j, k, l; + Point3d p1, p2, pnew; + + ElementIndex ei; + SurfaceElementIndex sei; + PointIndex pi1, pi2; + + double bad1, bad2, badmax, badlimit; + + + int cnt = 0; + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + + TABLE elementsonnode(np); + Array hasbothpoints; + + BitArray origpoint(np), boundp(np); + origpoint.Set(); + + Array elerrs(ne); + BitArray illegaltet(ne); + illegaltet.Clear(); + + const char * savetask = multithread.task; + multithread.task = "Split Improve"; + + + PrintMessage (3, "SplitImprove"); + (*testout) << "start SplitImprove" << "\n"; + + Array locfaces; + + INDEX_2_HASHTABLE edgetested (np); + + bad1 = 0; + badmax = 0; + for (ei = 0; ei < ne; ei++) + { + elerrs[ei] = CalcBad (mesh.Points(), mesh[ei], 0); + bad1 += elerrs[ei]; + if (elerrs[ei] > badmax) badmax = elerrs[ei]; + } + + PrintMessage (5, "badmax = ", badmax); + badlimit = 0.5 * badmax; + + + boundp.Clear(); + for (sei = 0; sei < mesh.GetNSE(); sei++) + for (j = 0; j < 3; j++) + boundp.Set (mesh[sei][j]); + + if (goal == OPT_QUALITY) + { + bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << bad1 << endl; + } + + for (ei = 0; ei < ne; ei++) + for (j = 0; j < mesh[ei].GetNP(); j++) + elementsonnode.Add (mesh[ei][j], ei); + + + mesh.MarkIllegalElements(); + if (goal == OPT_QUALITY || goal == OPT_LEGAL) + { + int cntill = 0; + for (ei = 0; ei < ne; ei++) + { + // if (!LegalTet (volelements.Get(i))) + if (mesh[ei].flags.illegal) + { + cntill++; + illegaltet.Set (ei+1); + } + } + // (*mycout) << cntill << " illegal tets" << endl; + } + + + for (ei = 0; ei < ne; ei++) + { + if (multithread.terminate) + break; + + multithread.percent = 100.0 * (ei+1) / ne; + + bool ltestmode = 0; + + + if (elerrs[ei] < badlimit && !illegaltet.Test(ei+1)) continue; + + if ((goal == OPT_LEGAL) && + !illegaltet.Test(ei+1) && + CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) + continue; + + + Element & elem = mesh[ei]; + + if (ltestmode) + { + (*testout) << "test el " << ei << endl; + for (j = 0; j < 4; j++) + (*testout) << elem[j] << " "; + (*testout) << endl; + } + + + for (j = 0; j < 6; j++) + { + + static const int tetedges[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + pi1 = elem[tetedges[j][0]]; + pi2 = elem[tetedges[j][1]]; + + if (pi2 < pi1) Swap (pi1, pi2); + if (pi2 > elementsonnode.Size()) continue; + + if (!origpoint.Test(pi1) || !origpoint.Test(pi2)) + continue; + + + INDEX_2 i2(pi1, pi2); + i2.Sort(); + + if (mesh.BoundaryEdge (pi1, pi2)) continue; + + if (edgetested.Used (i2) && !illegaltet.Test(ei+1)) continue; + edgetested.Set (i2, 1); + + hasbothpoints.SetSize (0); + for (k = 1; k <= elementsonnode.EntrySize(pi1); k++) + { + bool has1 = 0, has2 = 0; + + ElementIndex elnr = elementsonnode.Get(pi1, k); + Element & el = mesh[elnr]; + + for (l = 0; l < el.GetNP(); l++) + { + if (el[l] == pi1) has1 = 1; + if (el[l] == pi2) has2 = 1; + } + if (has1 && has2) + if (!hasbothpoints.Contains (elnr)) + hasbothpoints.Append (elnr); + } + + bad1 = 0; + for (k = 0; k < hasbothpoints.Size(); k++) + bad1 += CalcBad (mesh.Points(), mesh[hasbothpoints[k]], 0); + + + bool puretet = 1; + for (k = 0; k < hasbothpoints.Size(); k++) + if (mesh[hasbothpoints[k]].GetType() != TET) + puretet = 0; + if (!puretet) continue; + + p1 = mesh[pi1]; + p2 = mesh[pi2]; + + /* + pnew = Center (p1, p2); + + points.Elem(pi1) = pnew; + bad2 = 0; + for (k = 1; k <= hasbothpoints.Size(); k++) + bad2 += CalcBad (points, + volelements.Get(hasbothpoints.Get(k)), 0); + + points.Elem(pi1) = p1; + points.Elem(pi2) = pnew; + + for (k = 1; k <= hasbothpoints.Size(); k++) + bad2 += CalcBad (points, + volelements.Get(hasbothpoints.Get(k)), 0); + points.Elem(pi2) = p2; + */ + + + locfaces.SetSize (0); + for (k = 0; k < hasbothpoints.Size(); k++) + { + const Element & el = mesh[hasbothpoints[k]]; + + for (l = 0; l < 4; l++) + if (el[l] == pi1 || el[l] == pi2) + { + INDEX_3 i3; + Element2d face; + el.GetFace (l+1, face); + for (int kk = 1; kk <= 3; kk++) + i3.I(kk) = face.PNum(kk); + locfaces.Append (i3); + } + } + + PointFunction1 pf (mesh.Points(), locfaces, mp, -1); + OptiParameters par; + par.maxit_linsearch = 50; + par.maxit_bfgs = 20; + + pnew = Center (p1, p2); + Vector px(3); + px(0) = pnew.X(); + px(1) = pnew.Y(); + px(2) = pnew.Z(); + + if (elerrs[ei] > 0.1 * badmax) + BFGS (px, pf, par); + + bad2 = pf.Func (px); + + pnew.X() = px(0); + pnew.Y() = px(1); + pnew.Z() = px(2); + + + int hpinew = mesh.AddPoint (pnew); + // ptyps.Append (INNERPOINT); + + for (k = 0; k < hasbothpoints.Size(); k++) + { + Element & oldel = mesh[hasbothpoints[k]]; + Element newel1 = oldel; + Element newel2 = oldel; + + oldel.flags.illegal_valid = 0; + newel1.flags.illegal_valid = 0; + newel2.flags.illegal_valid = 0; + + for (l = 0; l < 4; l++) + { + if (newel1[l] == pi2) newel1[l] = hpinew; + if (newel2[l] == pi1) newel2[l] = hpinew; + } + + if (!mesh.LegalTet (oldel)) bad1 += 1e6; + if (!mesh.LegalTet (newel1)) bad2 += 1e6; + if (!mesh.LegalTet (newel2)) bad2 += 1e6; + } + + // mesh.PointTypes().DeleteLast(); + mesh.Points().DeleteLast(); + + if (bad2 < bad1) + /* (bad1 > 1e4 && boundp.Test(pi1) && boundp.Test(pi2)) */ + { + cnt++; + + PointIndex pinew = mesh.AddPoint (pnew); + + for (k = 0; k < hasbothpoints.Size(); k++) + { + Element & oldel = mesh[hasbothpoints[k]]; + Element newel = oldel; + + newel.flags.illegal_valid = 0; + oldel.flags.illegal_valid = 0; + + for (l = 0; l < 4; l++) + { + origpoint.Clear (oldel[l]); + + if (oldel[l] == pi2) oldel[l] = pinew; + if (newel[l] == pi1) newel[l] = pinew; + } + mesh.AddVolumeElement (newel); + } + + j = 10; + } + } + } + + + mesh.Compress(); + PrintMessage (5, cnt, " splits performed"); + + (*testout) << "Splitt - Improve done" << "\n"; + + if (goal == OPT_QUALITY) + { + bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << bad1 << endl; + + int cntill = 0; + ne = mesh.GetNE(); + for (ei = 0; ei < ne; ei++) + { + if (!mesh.LegalTet (mesh[ei])) + cntill++; + } + // cout << cntill << " illegal tets" << endl; + } + + multithread.task = savetask; +} + + + + + +void MeshOptimize3d :: SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal, + const BitArray * working_elements) +{ + PointIndex pi1(0), pi2(0), pi3(0), pi4(0), pi5(0), pi6(0); + int cnt = 0; + + Element el21(TET), el22(TET), el31(TET), el32(TET), el33(TET); + Element el1(TET), el2(TET), el3(TET), el4(TET); + Element el1b(TET), el2b(TET), el3b(TET), el4b(TET); + + double bad1, bad2, bad3; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + + // contains at least all elements at node + TABLE elementsonnode(np); + + Array hasbothpoints; + + PrintMessage (3, "SwapImprove "); + (*testout) << "\n" << "Start SwapImprove" << endl; + + const char * savetask = multithread.task; + multithread.task = "Swap Improve"; + + // mesh.CalcSurfacesOfNode (); + + INDEX_3_HASHTABLE faces(mesh.GetNOpenElements()/3 + 2); + if (goal == OPT_CONFORM) + { + for (int i = 1; i <= mesh.GetNOpenElements(); i++) + { + const Element2d & hel = mesh.OpenElement(i); + INDEX_3 face(hel[0], hel[1], hel[2]); + face.Sort(); + faces.Set (face, 1); + } + } + + // Calculate total badness + if (goal == OPT_QUALITY) + { + bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << bad1 << endl; + } + + // find elements on node + for (ElementIndex ei = 0; ei < ne; ei++) + for (int j = 0; j < mesh[ei].GetNP(); j++) + elementsonnode.Add (mesh[ei][j], ei); + + + // INDEX_2_HASHTABLE edgeused(2 * ne + 5); + INDEX_2_CLOSED_HASHTABLE edgeused(12 * ne + 5); + + for (ElementIndex ei = 0; ei < ne; ei++) + { + if (multithread.terminate) + break; + + multithread.percent = 100.0 * (ei+1) / ne; + + if ((mesh.ElementType(ei)) == FIXEDELEMENT) + continue; + + if(working_elements && + ei < working_elements->Size() && + !working_elements->Test(ei)) + continue; + + if (mesh[ei].IsDeleted()) + continue; + + if ((goal == OPT_LEGAL) && + mesh.LegalTet (mesh[ei]) && + CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) + continue; + + // int onlybedges = 1; + + for (int j = 0; j < 6; j++) + { + // loop over edges + + const Element & elemi = mesh[ei]; + if (elemi.IsDeleted()) continue; + + + // (*testout) << "check element " << elemi << endl; + + int mattyp = elemi.GetIndex(); + + static const int tetedges[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + pi1 = elemi[tetedges[j][0]]; + pi2 = elemi[tetedges[j][1]]; + + + if (pi2 < pi1) Swap (pi1, pi2); + + if (mesh.BoundaryEdge (pi1, pi2)) continue; + + + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + if (edgeused.Used(i2)) continue; + edgeused.Set (i2, 1); + + hasbothpoints.SetSize (0); + for (int k = 0; k < elementsonnode[pi1].Size(); k++) + { + bool has1 = 0, has2 = 0; + ElementIndex elnr = elementsonnode[pi1][k]; + const Element & elem = mesh[elnr]; + + if (elem.IsDeleted()) continue; + + for (int l = 0; l < elem.GetNP(); l++) + { + if (elem[l] == pi1) has1 = 1; + if (elem[l] == pi2) has2 = 1; + } + + if (has1 && has2) + { // only once + for (int l = 0; l < hasbothpoints.Size(); l++) + if (hasbothpoints[l] == elnr) + has1 = 0; + + if (has1) + hasbothpoints.Append (elnr); + } + } + + bool puretet = 1; + for (int k = 0; k < hasbothpoints.Size(); k++) + if (mesh[hasbothpoints[k]].GetType () != TET) + puretet = 0; + if (!puretet) + continue; + + int nsuround = hasbothpoints.Size(); + + if ( nsuround == 3 ) + { + Element & elem = mesh[hasbothpoints[0]]; + for (int l = 0; l < 4; l++) + if (elem[l] != pi1 && elem[l] != pi2) + { + pi4 = pi3; + pi3 = elem[l]; + } + + el31[0] = pi1; + el31[1] = pi2; + el31[2] = pi3; + el31[3] = pi4; + el31.SetIndex (mattyp); + + if (WrongOrientation (mesh.Points(), el31)) + { + Swap (pi3, pi4); + el31[2] = pi3; + el31[3] = pi4; + } + + pi5 = 0; + for (int k = 0; k < 3; k++) // JS, 201212 + { + const Element & elemk = mesh[hasbothpoints[k]]; + bool has1 = 0; + for (int l = 0; l < 4; l++) + if (elemk[l] == pi4) + has1 = 1; + if (has1) + { + for (int l = 0; l < 4; l++) + if (elemk[l] != pi1 && elemk[l] != pi2 && elemk[l] != pi4) + pi5 = elemk[l]; + } + } + + if(pi5 == 0) + throw NgException("Illegal state observed in SwapImprove"); + + + + el32[0] = pi1; + el32[1] = pi2; + el32[2] = pi4; + el32[3] = pi5; + el32.SetIndex (mattyp); + + el33[0] = pi1; + el33[1] = pi2; + el33[2] = pi5; + el33[3] = pi3; + el33.SetIndex (mattyp); + + elementsonnode.Add (pi4, hasbothpoints[1]); + elementsonnode.Add (pi3, hasbothpoints[2]); + + bad1 = CalcBad (mesh.Points(), el31, 0) + + CalcBad (mesh.Points(), el32, 0) + + CalcBad (mesh.Points(), el33, 0); + + el31.flags.illegal_valid = 0; + el32.flags.illegal_valid = 0; + el33.flags.illegal_valid = 0; + + if (!mesh.LegalTet(el31) || + !mesh.LegalTet(el32) || + !mesh.LegalTet(el33)) + bad1 += 1e4; + + el21[0] = pi3; + el21[1] = pi4; + el21[2] = pi5; + el21[3] = pi2; + el21.SetIndex (mattyp); + + el22[0] = pi5; + el22[1] = pi4; + el22[2] = pi3; + el22[3] = pi1; + el22.SetIndex (mattyp); + + bad2 = CalcBad (mesh.Points(), el21, 0) + + CalcBad (mesh.Points(), el22, 0); + + el21.flags.illegal_valid = 0; + el22.flags.illegal_valid = 0; + + if (!mesh.LegalTet(el21) || + !mesh.LegalTet(el22)) + bad2 += 1e4; + + + if (goal == OPT_CONFORM && bad2 < 1e4) + { + INDEX_3 face(pi3, pi4, pi5); + face.Sort(); + if (faces.Used(face)) + { + // (*testout) << "3->2 swap, could improve conformity, bad1 = " << bad1 + // << ", bad2 = " << bad2 << endl; + if (bad2 < 1e4) + bad1 = 2 * bad2; + } + /* + else + { + INDEX_2 hi1(pi3, pi4); + hi1.Sort(); + INDEX_2 hi2(pi3, pi5); + hi2.Sort(); + INDEX_2 hi3(pi4, pi5); + hi3.Sort(); + + if (boundaryedges->Used (hi1) || + boundaryedges->Used (hi2) || + boundaryedges->Used (hi3) ) + bad1 = 2 * bad2; + } + */ + } + + if (bad2 < bad1) + { + // (*mycout) << "3->2 " << flush; + // (*testout) << "3->2 conversion" << endl; + cnt++; + + + /* + (*testout) << "3->2 swap, old els = " << endl + << mesh[hasbothpoints[0]] << endl + << mesh[hasbothpoints[1]] << endl + << mesh[hasbothpoints[2]] << endl + << "new els = " << endl + << el21 << endl + << el22 << endl; + */ + + el21.flags.illegal_valid = 0; + el22.flags.illegal_valid = 0; + mesh[hasbothpoints[0]] = el21; + mesh[hasbothpoints[1]] = el22; + for (int l = 0; l < 4; l++) + mesh[hasbothpoints[2]][l] = 0; + mesh[hasbothpoints[2]].Delete(); + + for (int k = 0; k < 2; k++) + for (int l = 0; l < 4; l++) + elementsonnode.Add (mesh[hasbothpoints[k]][l], hasbothpoints[k]); + } + } + + if (nsuround == 4) + { + const Element & elem1 = mesh[hasbothpoints[0]]; + for (int l = 0; l < 4; l++) + if (elem1[l] != pi1 && elem1[l] != pi2) + { + pi4 = pi3; + pi3 = elem1[l]; + } + + el1[0] = pi1; el1[1] = pi2; + el1[2] = pi3; el1[3] = pi4; + el1.SetIndex (mattyp); + + if (WrongOrientation (mesh.Points(), el1)) + { + Swap (pi3, pi4); + el1[2] = pi3; + el1[3] = pi4; + } + + pi5 = 0; + for (int k = 0; k < 4; k++) + { + const Element & elem = mesh[hasbothpoints[k]]; + bool has1 = 0; + for (int l = 0; l < 4; l++) + if (elem[l] == pi4) + has1 = 1; + if (has1) + { + for (int l = 0; l < 4; l++) + if (elem[l] != pi1 && elem[l] != pi2 && elem[l] != pi4) + pi5 = elem[l]; + } + } + + pi6 = 0; + for (int k = 0; k < 4; k++) + { + const Element & elem = mesh[hasbothpoints[k]]; + bool has1 = 0; + for (int l = 0; l < 4; l++) + if (elem[l] == pi3) + has1 = 1; + if (has1) + { + for (int l = 0; l < 4; l++) + if (elem[l] != pi1 && elem[l] != pi2 && elem[l] != pi3) + pi6 = elem[l]; + } + } + + + /* + INDEX_2 i22(pi3, pi5); + i22.Sort(); + INDEX_2 i23(pi4, pi6); + i23.Sort(); + */ + + el1[0] = pi1; el1[1] = pi2; + el1[2] = pi3; el1[3] = pi4; + el1.SetIndex (mattyp); + + el2[0] = pi1; el2[1] = pi2; + el2[2] = pi4; el2[3] = pi5; + el2.SetIndex (mattyp); + + el3[0] = pi1; el3[1] = pi2; + el3[2] = pi5; el3[3] = pi6; + el3.SetIndex (mattyp); + + el4[0] = pi1; el4[1] = pi2; + el4[2] = pi6; el4[3] = pi3; + el4.SetIndex (mattyp); + + // elementsonnode.Add (pi4, hasbothpoints.Elem(2)); + // elementsonnode.Add (pi3, hasbothpoints.Elem(3)); + + bad1 = CalcBad (mesh.Points(), el1, 0) + + CalcBad (mesh.Points(), el2, 0) + + CalcBad (mesh.Points(), el3, 0) + + CalcBad (mesh.Points(), el4, 0); + + + el1.flags.illegal_valid = 0; + el2.flags.illegal_valid = 0; + el3.flags.illegal_valid = 0; + el4.flags.illegal_valid = 0; + + + if (goal != OPT_CONFORM) + { + if (!mesh.LegalTet(el1) || + !mesh.LegalTet(el2) || + !mesh.LegalTet(el3) || + !mesh.LegalTet(el4)) + bad1 += 1e4; + } + + el1[0] = pi3; el1[1] = pi5; + el1[2] = pi2; el1[3] = pi4; + el1.SetIndex (mattyp); + + el2[0] = pi3; el2[1] = pi5; + el2[2] = pi4; el2[3] = pi1; + el2.SetIndex (mattyp); + + el3[0] = pi3; el3[1] = pi5; + el3[2] = pi1; el3[3] = pi6; + el3.SetIndex (mattyp); + + el4[0] = pi3; el4[1] = pi5; + el4[2] = pi6; el4[3] = pi2; + el4.SetIndex (mattyp); + + bad2 = CalcBad (mesh.Points(), el1, 0) + + CalcBad (mesh.Points(), el2, 0) + + CalcBad (mesh.Points(), el3, 0) + + CalcBad (mesh.Points(), el4, 0); + + el1.flags.illegal_valid = 0; + el2.flags.illegal_valid = 0; + el3.flags.illegal_valid = 0; + el4.flags.illegal_valid = 0; + + if (goal != OPT_CONFORM) + { + if (!mesh.LegalTet(el1) || + !mesh.LegalTet(el2) || + !mesh.LegalTet(el3) || + !mesh.LegalTet(el4)) + bad2 += 1e4; + } + + + el1b[0] = pi4; el1b[1] = pi6; + el1b[2] = pi3; el1b[3] = pi2; + el1b.SetIndex (mattyp); + + el2b[0] = pi4; el2b[1] = pi6; + el2b[2] = pi2; el2b[3] = pi5; + el2b.SetIndex (mattyp); + + el3b[0] = pi4; el3b[1] = pi6; + el3b[2] = pi5; el3b[3] = pi1; + el3b.SetIndex (mattyp); + + el4b[0] = pi4; el4b[1] = pi6; + el4b[2] = pi1; el4b[3] = pi3; + el4b.SetIndex (mattyp); + + bad3 = CalcBad (mesh.Points(), el1b, 0) + + CalcBad (mesh.Points(), el2b, 0) + + CalcBad (mesh.Points(), el3b, 0) + + CalcBad (mesh.Points(), el4b, 0); + + el1b.flags.illegal_valid = 0; + el2b.flags.illegal_valid = 0; + el3b.flags.illegal_valid = 0; + el4b.flags.illegal_valid = 0; + + if (goal != OPT_CONFORM) + { + if (!mesh.LegalTet(el1b) || + !mesh.LegalTet(el2b) || + !mesh.LegalTet(el3b) || + !mesh.LegalTet(el4b)) + bad3 += 1e4; + } + + + /* + int swap2 = (bad2 < bad1) && (bad2 < bad3); + int swap3 = !swap2 && (bad3 < bad1); + + if ( ((bad2 < 10 * bad1) || + (bad2 < 1e6)) && mesh.BoundaryEdge (pi3, pi5)) + swap2 = 1; + else if ( ((bad3 < 10 * bad1) || + (bad3 < 1e6)) && mesh.BoundaryEdge (pi4, pi6)) + { + swap3 = 1; + swap2 = 0; + } + */ + bool swap2, swap3; + + if (goal != OPT_CONFORM) + { + swap2 = (bad2 < bad1) && (bad2 < bad3); + swap3 = !swap2 && (bad3 < bad1); + } + else + { + if (mesh.BoundaryEdge (pi3, pi5)) bad2 /= 1e6; + if (mesh.BoundaryEdge (pi4, pi6)) bad3 /= 1e6; + + swap2 = (bad2 < bad1) && (bad2 < bad3); + swap3 = !swap2 && (bad3 < bad1); + } + + + if (swap2 || swap3) + { + // (*mycout) << "4->4 " << flush; + cnt++; + // (*testout) << "4->4 conversion" << "\n"; + /* + (*testout) << "bad1 = " << bad1 + << " bad2 = " << bad2 + << " bad3 = " << bad3 << "\n"; + + (*testout) << "Points: " << pi1 << " " << pi2 << " " << pi3 + << " " << pi4 << " " << pi5 << " " << pi6 << "\n"; + (*testout) << "Elements: " + << hasbothpoints.Get(1) << " " + << hasbothpoints.Get(2) << " " + << hasbothpoints.Get(3) << " " + << hasbothpoints.Get(4) << " " << "\n"; + */ + + /* + { + int i1, j1; + for (i1 = 1; i1 <= 4; i1++) + { + for (j1 = 1; j1 <= 4; j1++) + (*testout) << volelements.Get(hasbothpoints.Get(i1)).PNum(j1) + << " "; + (*testout) << "\n"; + } + } + */ + } + + + if (swap2) + { + // (*mycout) << "bad1 = " << bad1 << " bad2 = " << bad2 << "\n"; + + + /* + (*testout) << "4->4 swap A, old els = " << endl + << mesh[hasbothpoints[0]] << endl + << mesh[hasbothpoints[1]] << endl + << mesh[hasbothpoints[2]] << endl + << mesh[hasbothpoints[3]] << endl + << "new els = " << endl + << el1 << endl + << el2 << endl + << el3 << endl + << el4 << endl; + */ + + + + el1.flags.illegal_valid = 0; + el2.flags.illegal_valid = 0; + el3.flags.illegal_valid = 0; + el4.flags.illegal_valid = 0; + + mesh[hasbothpoints[0]] = el1; + mesh[hasbothpoints[1]] = el2; + mesh[hasbothpoints[2]] = el3; + mesh[hasbothpoints[3]] = el4; + + for (int k = 0; k < 4; k++) + for (int l = 0; l < 4; l++) + elementsonnode.Add (mesh[hasbothpoints[k]][l], hasbothpoints[k]); + } + else if (swap3) + { + // (*mycout) << "bad1 = " << bad1 << " bad3 = " << bad3 << "\n"; + el1b.flags.illegal_valid = 0; + el2b.flags.illegal_valid = 0; + el3b.flags.illegal_valid = 0; + el4b.flags.illegal_valid = 0; + + + /* + (*testout) << "4->4 swap A, old els = " << endl + << mesh[hasbothpoints[0]] << endl + << mesh[hasbothpoints[1]] << endl + << mesh[hasbothpoints[2]] << endl + << mesh[hasbothpoints[3]] << endl + << "new els = " << endl + << el1b << endl + << el2b << endl + << el3b << endl + << el4b << endl; + */ + + + mesh[hasbothpoints[0]] = el1b; + mesh[hasbothpoints[1]] = el2b; + mesh[hasbothpoints[2]] = el3b; + mesh[hasbothpoints[3]] = el4b; + + for (int k = 0; k < 4; k++) + for (int l = 0; l < 4; l++) + elementsonnode.Add (mesh[hasbothpoints[k]][l], hasbothpoints[k]); + } + } + + if (nsuround >= 5) + { + Element hel(TET); + + ArrayMem suroundpts(nsuround); + ArrayMem tetused(nsuround); + + Element & elem = mesh[hasbothpoints[0]]; + + for (int l = 0; l < 4; l++) + if (elem[l] != pi1 && elem[l] != pi2) + { + pi4 = pi3; + pi3 = elem[l]; + } + + hel[0] = pi1; + hel[1] = pi2; + hel[2] = pi3; + hel[3] = pi4; + hel.SetIndex (mattyp); + + if (WrongOrientation (mesh.Points(), hel)) + { + Swap (pi3, pi4); + hel[2] = pi3; + hel[3] = pi4; + } + + + // suroundpts.SetSize (nsuround); + suroundpts[0] = pi3; + suroundpts[1] = pi4; + + tetused = 0; + tetused[0] = 1; + + for (int l = 2; l < nsuround; l++) + { + int oldpi = suroundpts[l-1]; + int newpi = 0; + + for (int k = 0; k < nsuround && !newpi; k++) + if (!tetused[k]) + { + const Element & nel = mesh[hasbothpoints[k]]; + + for (int k2 = 0; k2 < 4 && !newpi; k2++) + if (nel[k2] == oldpi) + { + newpi = + nel[0] + nel[1] + nel[2] + nel[3] + - pi1 - pi2 - oldpi; + + tetused[k] = 1; + suroundpts[l] = newpi; + } + } + } + + + bad1 = 0; + for (int k = 0; k < nsuround; k++) + { + hel[0] = pi1; + hel[1] = pi2; + hel[2] = suroundpts[k]; + hel[3] = suroundpts[(k+1) % nsuround]; + hel.SetIndex (mattyp); + + bad1 += CalcBad (mesh.Points(), hel, 0); + } + + // (*testout) << "nsuround = " << nsuround << " bad1 = " << bad1 << endl; + + + int bestl = -1; + int confface = -1; + int confedge = -1; + double badopt = bad1; + + for (int l = 0; l < nsuround; l++) + { + bad2 = 0; + + for (int k = l+1; k <= nsuround + l - 2; k++) + { + hel[0] = suroundpts[l]; + hel[1] = suroundpts[k % nsuround]; + hel[2] = suroundpts[(k+1) % nsuround]; + hel[3] = pi2; + + bad2 += CalcBad (mesh.Points(), hel, 0); + hel.flags.illegal_valid = 0; + if (!mesh.LegalTet(hel)) bad2 += 1e4; + + hel[2] = suroundpts[k % nsuround]; + hel[1] = suroundpts[(k+1) % nsuround]; + hel[3] = pi1; + + bad2 += CalcBad (mesh.Points(), hel, 0); + + hel.flags.illegal_valid = 0; + if (!mesh.LegalTet(hel)) bad2 += 1e4; + } + // (*testout) << "bad2," << l << " = " << bad2 << endl; + + if ( bad2 < badopt ) + { + bestl = l; + badopt = bad2; + } + + + if (goal == OPT_CONFORM) + // (bad2 <= 100 * bad1 || bad2 <= 1e6)) + { + bool nottoobad = + (bad2 <= bad1) || + (bad2 <= 100 * bad1 && bad2 <= 1e18) || + (bad2 <= 1e8); + + for (int k = l+1; k <= nsuround + l - 2; k++) + { + INDEX_3 hi3(suroundpts[l], + suroundpts[k % nsuround], + suroundpts[(k+1) % nsuround]); + hi3.Sort(); + if (faces.Used(hi3)) + { + // (*testout) << "could improve face conformity, bad1 = " << bad1 + // << ", bad 2 = " << bad2 << ", nottoobad = " << nottoobad << endl; + if (nottoobad) + confface = l; + } + } + + for (int k = l+2; k <= nsuround+l-2; k++) + { + if (mesh.BoundaryEdge (suroundpts[l], + suroundpts[k % nsuround])) + { + /* + *testout << "could improve edge conformity, bad1 = " << bad1 + << ", bad 2 = " << bad2 << ", nottoobad = " << nottoobad << endl; + */ + if (nottoobad) + confedge = l; + } + } + } + } + + if (confedge != -1) + bestl = confedge; + if (confface != -1) + bestl = confface; + + if (bestl != -1) + { + // (*mycout) << nsuround << "->" << 2 * (nsuround-2) << " " << flush; + cnt++; + + for (int k = bestl+1; k <= nsuround + bestl - 2; k++) + { + int k1; + + hel[0] = suroundpts[bestl]; + hel[1] = suroundpts[k % nsuround]; + hel[2] = suroundpts[(k+1) % nsuround]; + hel[3] = pi2; + hel.flags.illegal_valid = 0; + + /* + (*testout) << nsuround << "-swap, new el,top = " + << hel << endl; + */ + mesh.AddVolumeElement (hel); + + for (k1 = 0; k1 < 4; k1++) + elementsonnode.Add (hel[k1], mesh.GetNE()-1); + + + hel[2] = suroundpts[k % nsuround]; + hel[1] = suroundpts[(k+1) % nsuround]; + hel[3] = pi1; + + /* + (*testout) << nsuround << "-swap, new el,bot = " + << hel << endl; + */ + + mesh.AddVolumeElement (hel); + + for (k1 = 0; k1 < 4; k1++) + elementsonnode.Add (hel[k1], mesh.GetNE()-1); + } + + for (int k = 0; k < nsuround; k++) + { + Element & rel = mesh[hasbothpoints[k]]; + /* + (*testout) << nsuround << "-swap, old el = " + << rel << endl; + */ + rel.Delete(); + for (int k1 = 0; k1 < 4; k1++) + rel[k1] = 0; + + } + } + } + } + + /* + if (onlybedges) + { + (*testout) << "bad tet: " + << volelements.Get(i)[0] + << volelements.Get(i)[1] + << volelements.Get(i)[2] + << volelements.Get(i)[3] << "\n"; + + if (!mesh.LegalTet (volelements.Get(i))) + cerr << "Illegal tet" << "\n"; + } + */ + } + // (*mycout) << endl; + + /* + cout << "edgeused: "; + edgeused.PrintMemInfo(cout); + */ + PrintMessage (5, cnt, " swaps performed"); + + + + + + mesh.Compress (); + + /* + if (goal == OPT_QUALITY) + { + bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + // (*testout) << "Total badness = " << bad1 << endl; + } + */ + + /* + for (i = 1; i <= GetNE(); i++) + if (volelements.Get(i)[0]) + if (!mesh.LegalTet (volelements.Get(i))) + { + cout << "detected illegal tet, 2" << endl; + (*testout) << "detected illegal tet1: " << i << endl; + } + */ + + multithread.task = savetask; +} + + + + + + +void MeshOptimize3d :: SwapImproveSurface (Mesh & mesh, OPTIMIZEGOAL goal, + const BitArray * working_elements, + const Array< Array* > * idmaps) +{ + Array< Array* > locidmaps; + const Array< Array* > * used_idmaps; + + if(idmaps) + used_idmaps = idmaps; + else + { + used_idmaps = &locidmaps; + + for(int i=1; i<=mesh.GetIdentifications().GetMaxNr(); i++) + { + if(mesh.GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + locidmaps.Append(new Array); + mesh.GetIdentifications().GetMap(i,*locidmaps.Last(),true); + } + } + } + + + PointIndex pi1, pi2, pi3, pi4, pi5, pi6; + PointIndex pi1other, pi2other; + int cnt = 0; + + //double bad1, bad2, bad3, sbad; + double bad1, sbad; + double h; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + + int mattype, othermattype; + + + // contains at least all elements at node + TABLE elementsonnode(np); + TABLE surfaceelementsonnode(np); + TABLE surfaceindicesonnode(np); + + Array hasbothpoints; + Array hasbothpointsother; + + PrintMessage (3, "SwapImproveSurface "); + (*testout) << "\n" << "Start SwapImproveSurface" << endl; + + const char * savetask = multithread.task; + multithread.task = "Swap Improve Surface"; + + + + // find elements on node + for (ElementIndex ei = 0; ei < ne; ei++) + for (int j = 0; j < mesh[ei].GetNP(); j++) + elementsonnode.Add (mesh[ei][j], ei); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + for(int j=0; j edgeused(2 * ne + 5); + INDEX_2_CLOSED_HASHTABLE edgeused(12 * ne + 5); + + for (ElementIndex ei = 0; ei < ne; ei++) + { + if (multithread.terminate) + break; + + multithread.percent = 100.0 * (ei+1) / ne; + + if (mesh.ElementType(ei) == FIXEDELEMENT) + continue; + + if(working_elements && + ei < working_elements->Size() && + !working_elements->Test(ei)) + continue; + + if (mesh[ei].IsDeleted()) + continue; + + if ((goal == OPT_LEGAL) && + mesh.LegalTet (mesh[ei]) && + CalcBad (mesh.Points(), mesh[ei], 0) < 1e3) + continue; + + const Element & elemi = mesh[ei]; + //Element elemi = mesh[ei]; + if (elemi.IsDeleted()) continue; + + + mattype = elemi.GetIndex(); + + bool swapped = false; + + for (int j = 0; !swapped && j < 6; j++) + { + // loop over edges + + + static const int tetedges[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + pi1 = elemi[tetedges[j][0]]; + pi2 = elemi[tetedges[j][1]]; + + + if (pi2 < pi1) + Swap (pi1, pi2); + + + bool found = false; + for(int k=0; !found && kSize(); k++) + { + if(pi2 < (*used_idmaps)[k]->Size() + PointIndex::BASE) + { + pi1other = (*(*used_idmaps)[k])[pi1]; + pi2other = (*(*used_idmaps)[k])[pi2]; + found = (pi1other != 0 && pi2other != 0 && pi1other != pi1 && pi2other != pi2); + if(found) + idnum = k; + } + } + if(found) + periodic = true; + else + { + periodic = false; + pi1other = pi1; pi2other = pi2; + } + + + + if (!mesh.BoundaryEdge (pi1, pi2) || + mesh.IsSegment(pi1, pi2)) continue; + + othermattype = -1; + + + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + if (edgeused.Used(i2)) continue; + edgeused.Set (i2, 1); + if(periodic) + { + i2.I1() = pi1other; + i2.I2() = pi2other; + i2.Sort(); + edgeused.Set(i2,1); + } + + + hasbothpoints.SetSize (0); + hasbothpointsother.SetSize (0); + for (int k = 0; k < elementsonnode[pi1].Size(); k++) + { + bool has1 = false, has2 = false; + ElementIndex elnr = elementsonnode[pi1][k]; + const Element & elem = mesh[elnr]; + + if (elem.IsDeleted()) continue; + + for (int l = 0; l < elem.GetNP(); l++) + { + if (elem[l] == pi1) has1 = true; + if (elem[l] == pi2) has2 = true; + } + + if (has1 && has2) + { + if(othermattype == -1 && elem.GetIndex() != mattype) + othermattype = elem.GetIndex(); + + if(elem.GetIndex() == mattype) + { + // only once + for (int l = 0; l < hasbothpoints.Size(); l++) + if (hasbothpoints[l] == elnr) + has1 = 0; + + if (has1) + hasbothpoints.Append (elnr); + } + else if(elem.GetIndex() == othermattype) + { + // only once + for (int l = 0; l < hasbothpointsother.Size(); l++) + if (hasbothpointsother[l] == elnr) + has1 = 0; + + if (has1) + hasbothpointsother.Append (elnr); + } + else + { + cout << "problem with domain indices" << endl; + (*testout) << "problem: mattype = " << mattype << ", othermattype = " << othermattype + << " elem " << elem << " mt " << elem.GetIndex() << endl + << " pi1 " << pi1 << " pi2 " << pi2 << endl; + (*testout) << "hasbothpoints:" << endl; + for(int ii=0; ii < hasbothpoints.Size(); ii++) + (*testout) << mesh[hasbothpoints[ii]] << endl; + (*testout) << "hasbothpointsother:" << endl; + for(int ii=0; ii < hasbothpointsother.Size(); ii++) + (*testout) << mesh[hasbothpointsother[ii]] << endl; + } + } + } + + if(hasbothpointsother.Size() > 0 && periodic) + throw NgException("SwapImproveSurface: Assumption about interface/periodicity wrong!"); + + if(periodic) + { + for (int k = 0; k < elementsonnode[pi1other].Size(); k++) + { + bool has1 = false, has2 = false; + ElementIndex elnr = elementsonnode[pi1other][k]; + const Element & elem = mesh[elnr]; + + if (elem.IsDeleted()) continue; + + for (int l = 0; l < elem.GetNP(); l++) + { + if (elem[l] == pi1other) has1 = true; + if (elem[l] == pi2other) has2 = true; + } + + if (has1 && has2) + { + if(othermattype == -1) + othermattype = elem.GetIndex(); + + // only once + for (int l = 0; l < hasbothpointsother.Size(); l++) + if (hasbothpointsother[l] == elnr) + has1 = 0; + + if (has1) + hasbothpointsother.Append (elnr); + } + } + } + + + //for(k=0; k v1 = mesh[sp1]-mesh[pi1], + v2 = mesh[sp2]-mesh[pi1], + v3 = mesh[sp1]-mesh[pi2], + v4 = mesh[sp2]-mesh[pi2]; + double vol = 0.5*(Cross(v1,v2).Length() + Cross(v3,v4).Length()); + h = sqrt(vol); + h = 0; + + sbad = CalcTriangleBadness (mesh[pi1],mesh[pi2],mesh[sp1],0,0) + + CalcTriangleBadness (mesh[pi2],mesh[pi1],mesh[sp2],0,0); + + + + bool puretet = true; + for (int k = 0; puretet && k < hasbothpoints.Size(); k++) + if (mesh[hasbothpoints[k]].GetType () != TET) + puretet = false; + for (int k = 0; puretet && k < hasbothpointsother.Size(); k++) + if (mesh[hasbothpointsother[k]].GetType () != TET) + puretet = false; + if (!puretet) + continue; + + int nsuround = hasbothpoints.Size(); + int nsuroundother = hasbothpointsother.Size(); + + Array < int > outerpoints(nsuround+1); + outerpoints[0] = sp1; + + for(int i=0; i 0) + (*testout) << mesh[hasbothpoints[ii]][jj] << " between " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][0] << " and " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][1] << endl; + } + (*testout) << "outerpoints: " << outerpoints << endl; + (*testout) << "sel1 " << mesh[sel1] << endl + << "sel2 " << mesh[sel2] << endl; + for(int ii=0; ii<3; ii++) + { + if(mesh.mlbetweennodes[mesh[sel1][ii]][0] > 0) + (*testout) << mesh[sel1][ii] << " between " + << mesh.mlbetweennodes[mesh[sel1][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel1][ii]][1] << endl; + if(mesh.mlbetweennodes[mesh[sel2][ii]][0] > 0) + (*testout) << mesh[sel2][ii] << " between " + << mesh.mlbetweennodes[mesh[sel2][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel2][ii]][1] << endl; + } + } + + + Array < int > outerpointsother; + + if(nsuroundother > 0) + { + outerpointsother.SetSize(nsuroundother+1); + outerpointsother[0] = sp2other; + } + + for(int i=0; i 0 && outerpointsother[nsuroundother] != sp1other) + { + cerr << "OJE OJE OJE (other)" << endl; + (*testout) << "OJE OJE OJE (other)" << endl; + (*testout) << "pi1 " << pi1 << " pi2 " << pi2 << " sp1 " << sp1 << " sp2 " << sp2 << endl; + (*testout) << "hasbothpoints: " << endl; + for(int ii=0; ii < hasbothpoints.Size(); ii++) + { + (*testout) << mesh[hasbothpoints[ii]] << endl; + for(int jj=0; jj 0) + (*testout) << mesh[hasbothpoints[ii]][jj] << " between " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][0] << " and " + << mesh.mlbetweennodes[mesh[hasbothpoints[ii]][jj]][1] << endl; + } + (*testout) << "outerpoints: " << outerpoints << endl; + (*testout) << "sel1 " << mesh[sel1] << endl + << "sel2 " << mesh[sel2] << endl; + for(int ii=0; ii<3; ii++) + { + if(mesh.mlbetweennodes[mesh[sel1][ii]][0] > 0) + (*testout) << mesh[sel1][ii] << " between " + << mesh.mlbetweennodes[mesh[sel1][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel1][ii]][1] << endl; + if(mesh.mlbetweennodes[mesh[sel2][ii]][0] > 0) + (*testout) << mesh[sel2][ii] << " between " + << mesh.mlbetweennodes[mesh[sel2][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel2][ii]][1] << endl; + } + + (*testout) << "pi1other " << pi1other << " pi2other " << pi2other << " sp1other " << sp1other << " sp2other " << sp2other << endl; + (*testout) << "hasbothpointsother: " << endl; + for(int ii=0; ii < hasbothpointsother.Size(); ii++) + { + (*testout) << mesh[hasbothpointsother[ii]] << endl; + for(int jj=0; jj 0) + (*testout) << mesh[hasbothpointsother[ii]][jj] << " between " + << mesh.mlbetweennodes[mesh[hasbothpointsother[ii]][jj]][0] << " and " + << mesh.mlbetweennodes[mesh[hasbothpointsother[ii]][jj]][1] << endl; + } + (*testout) << "outerpoints: " << outerpointsother << endl; + (*testout) << "sel1other " << mesh[sel1other] << endl + << "sel2other " << mesh[sel2other] << endl; + for(int ii=0; ii<3; ii++) + { + if(mesh.mlbetweennodes[mesh[sel1other][ii]][0] > 0) + (*testout) << mesh[sel1other][ii] << " between " + << mesh.mlbetweennodes[mesh[sel1other][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel1other][ii]][1] << endl; + if(mesh.mlbetweennodes[mesh[sel2other][ii]][0] > 0) + (*testout) << mesh[sel2other][ii] << " between " + << mesh.mlbetweennodes[mesh[sel2other][ii]][0] << " and " + << mesh.mlbetweennodes[mesh[sel2other][ii]][1] << endl; + } + } + + bad1=0; + for(int i=0; i * > newelts(startpoints); + Array < Array < Element* > * > neweltsother(startpointsother); + + double minbad = 1e50, minbadother = 1e50, currbad; + int minpos = -1, minposother = -1; + + //(*testout) << "pi1 " << pi1 << " pi2 " << pi2 << " outerpoints " << outerpoints << endl; + + for(int i=0; i(2*(nsuround-1)); + + for(int jj=0; jjSize(); jj++) + wrongorientation = wrongorientation && WrongOrientation(mesh.Points(), *(*newelts[i])[jj]); + + currbad = 0; + + for(int jj=0; jjSize(); jj++) + { + if(wrongorientation) + Swap((*(*newelts[i])[jj])[2],(*(*newelts[i])[jj])[3]); + + + // not two new faces on same surface + Array face_index; + for(int k = 0; kSize()); + + + + if(currbad < minbad) + { + minbad = currbad; + minpos = i; + } + + } + + if(startpointsother == 0) + minbadother = 0; + + for(int i=0; i(2*(nsuroundother)); + + for(int jj=0; jjSize(); jj++) + wrongorientation = wrongorientation && WrongOrientation(mesh.Points(), *(*neweltsother[i])[jj]); + + currbad = 0; + + for(int jj=0; jjSize(); jj++) + { + if(wrongorientation) + Swap((*(*neweltsother[i])[jj])[2],(*(*neweltsother[i])[jj])[3]); + + currbad += CalcBad(mesh.Points(),*(*neweltsother[i])[jj],h); + } + + //currbad /= double(neweltsother[i]->Size()); + + + + if(currbad < minbadother) + { + minbadother = currbad; + minposother = i; + } + + } + + //(*testout) << "minbad " << minbad << " bad1 " << bad1 << endl; + + + double sbadnew = CalcTriangleBadness (mesh[pi1],mesh[sp2],mesh[sp1],0,0) + + CalcTriangleBadness (mesh[pi2],mesh[sp1],mesh[sp2],0,0); + + + int denom = newelts[minpos]->Size(); + if(minposother >= 0) + denom += neweltsother[minposother]->Size(); + + + if((minbad+minbadother)/double(denom) < bad1 && + sbadnew < sbad) + { + cnt++; + + swapped = true; + + + int start1 = -1; + for(int l=0; l<3; l++) + if(mesh[sel1][l] == pi1) + start1 = l; + if(mesh[sel1][(start1+1)%3] == pi2) + { + mesh[sel1][0] = pi1; + mesh[sel1][1] = sp2; + mesh[sel1][2] = sp1; + mesh[sel2][0] = pi2; + mesh[sel2][1] = sp1; + mesh[sel2][2] = sp2; + } + else + { + mesh[sel1][0] = pi2; + mesh[sel1][1] = sp2; + mesh[sel1][2] = sp1; + mesh[sel2][0] = pi1; + mesh[sel2][1] = sp1; + mesh[sel2][2] = sp2; + } + //(*testout) << "changed surface element " << sel1 << " to " << mesh[sel1] << ", " << sel2 << " to " << mesh[sel2] << endl; + + for(int l=0; l<3; l++) + { + surfaceelementsonnode.Add(mesh[sel1][l],sel1); + surfaceelementsonnode.Add(mesh[sel2][l],sel2); + } + + + + if(periodic) + { + start1 = -1; + for(int l=0; l<3; l++) + if(mesh[sel1other][l] == pi1other) + start1 = l; + + + + //(*testout) << "changed surface elements " << mesh[sel1other] << " and " << mesh[sel2other] << endl; + if(mesh[sel1other][(start1+1)%3] == pi2other) + { + mesh[sel1other][0] = pi1other; + mesh[sel1other][1] = sp2other; + mesh[sel1other][2] = sp1other; + mesh[sel2other][0] = pi2other; + mesh[sel2other][1] = sp1other; + mesh[sel2other][2] = sp2other; + //(*testout) << " with rule 1" << endl; + } + else + { + mesh[sel1other][0] = pi2other; + mesh[sel1other][1] = sp2other; + mesh[sel1other][2] = sp1other; + mesh[sel2other][0] = pi1other; + mesh[sel2other][1] = sp1other; + mesh[sel2other][2] = sp2other; + //(*testout) << " with rule 2" << endl; + } + //(*testout) << " to " << mesh[sel1other] << " and " << mesh[sel2other] << endl; + + //(*testout) << " and surface element " << sel1other << " to " << mesh[sel1other] << ", " << sel2other << " to " << mesh[sel2other] << endl; + + for(int l=0; l<3; l++) + { + surfaceelementsonnode.Add(mesh[sel1other][l],sel1other); + surfaceelementsonnode.Add(mesh[sel2other][l],sel2other); + } + } + + + + + for(int i=0; i 0) + { + for(int i=0; iSize(); jj++) + delete (*newelts[i])[jj]; + delete newelts[i]; + } + + for(int i=0; iSize(); jj++) + delete (*neweltsother[i])[jj]; + delete neweltsother[i]; + } + + } + } + + PrintMessage (5, cnt, " swaps performed"); + + + for(int i=0; i 3 conversion +*/ + + +void MeshOptimize3d :: SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal) +{ + PointIndex pi1(0), pi2(0), pi3(0), pi4(0), pi5(0); + Element el21(TET), el22(TET), el31(TET), el32(TET), el33(TET); + + int cnt = 0; + double bad1, bad2; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + + if (goal == OPT_CONFORM) return; + + // contains at least all elements at node + TABLE elementsonnode(np); + TABLE belementsonnode(np); + + PrintMessage (3, "SwapImprove2 "); + (*testout) << "\n" << "Start SwapImprove2" << "\n"; + // TestOk(); + + + /* + CalcSurfacesOfNode (); + for (i = 1; i <= GetNE(); i++) + if (volelements.Get(i)[0]) + if (!mesh.LegalTet (volelements.Get(i))) + { + cout << "detected illegal tet, 1" << endl; + (*testout) << "detected illegal tet1: " << i << endl; + } + */ + + + // Calculate total badness + + bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << bad1 << endl; + // cout << "tot bad = " << bad1 << endl; + + // find elements on node + + for (ElementIndex ei = 0; ei < ne; ei++) + for (int j = 0; j < mesh[ei].GetNP(); j++) + elementsonnode.Add (mesh[ei][j], ei); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + for (int j = 0; j < 3; j++) + belementsonnode.Add (mesh[sei][j], sei); + + for (ElementIndex eli1 = 0; eli1 < ne; eli1++) + { + if (multithread.terminate) + break; + + if (mesh.ElementType (eli1) == FIXEDELEMENT) + continue; + + if (mesh[eli1].GetType() != TET) + continue; + + if ((goal == OPT_LEGAL) && + mesh.LegalTet (mesh[eli1]) && + CalcBad (mesh.Points(), mesh[eli1], 0) < 1e3) + continue; + + // cout << "eli = " << eli1 << endl; + // (*testout) << "swapimp2, eli = " << eli1 << "; el = " << mesh[eli1] << endl; + + for (int j = 0; j < 4; j++) + { + // loop over faces + + Element & elem = mesh[eli1]; + // if (elem[0] < PointIndex::BASE) continue; + if (elem.IsDeleted()) continue; + + int mattyp = elem.GetIndex(); + + switch (j) + { + case 0: + pi1 = elem.PNum(1); pi2 = elem.PNum(2); + pi3 = elem.PNum(3); pi4 = elem.PNum(4); + break; + case 1: + pi1 = elem.PNum(1); pi2 = elem.PNum(4); + pi3 = elem.PNum(2); pi4 = elem.PNum(3); + break; + case 2: + pi1 = elem.PNum(1); pi2 = elem.PNum(3); + pi3 = elem.PNum(4); pi4 = elem.PNum(2); + break; + case 3: + pi1 = elem.PNum(2); pi2 = elem.PNum(4); + pi3 = elem.PNum(3); pi4 = elem.PNum(1); + break; + } + + + bool bface = 0; + for (int k = 0; k < belementsonnode[pi1].Size(); k++) + { + const Element2d & bel = + mesh[belementsonnode[pi1][k]]; + + bool bface1 = 1; + for (int l = 0; l < 3; l++) + if (bel[l] != pi1 && bel[l] != pi2 && bel[l] != pi3) + { + bface1 = 0; + break; + } + + if (bface1) + { + bface = 1; + break; + } + } + + if (bface) continue; + + + FlatArray row = elementsonnode[pi1]; + for (int k = 0; k < row.Size(); k++) + { + ElementIndex eli2 = row[k]; + + // cout << "\rei1 = " << eli1 << ", pi1 = " << pi1 << ", k = " << k << ", ei2 = " << eli2 + // << ", getne = " << mesh.GetNE(); + + if ( eli1 != eli2 ) + { + Element & elem2 = mesh[eli2]; + if (elem2.IsDeleted()) continue; + if (elem2.GetType() != TET) + continue; + + int comnodes=0; + for (int l = 1; l <= 4; l++) + if (elem2.PNum(l) == pi1 || elem2.PNum(l) == pi2 || + elem2.PNum(l) == pi3) + { + comnodes++; + } + else + { + pi5 = elem2.PNum(l); + } + + if (comnodes == 3) + { + bad1 = CalcBad (mesh.Points(), elem, 0) + + CalcBad (mesh.Points(), elem2, 0); + + if (!mesh.LegalTet(elem) || + !mesh.LegalTet(elem2)) + bad1 += 1e4; + + + el31.PNum(1) = pi1; + el31.PNum(2) = pi2; + el31.PNum(3) = pi5; + el31.PNum(4) = pi4; + el31.SetIndex (mattyp); + + el32.PNum(1) = pi2; + el32.PNum(2) = pi3; + el32.PNum(3) = pi5; + el32.PNum(4) = pi4; + el32.SetIndex (mattyp); + + el33.PNum(1) = pi3; + el33.PNum(2) = pi1; + el33.PNum(3) = pi5; + el33.PNum(4) = pi4; + el33.SetIndex (mattyp); + + bad2 = CalcBad (mesh.Points(), el31, 0) + + CalcBad (mesh.Points(), el32, 0) + + CalcBad (mesh.Points(), el33, 0); + + + el31.flags.illegal_valid = 0; + el32.flags.illegal_valid = 0; + el33.flags.illegal_valid = 0; + + if (!mesh.LegalTet(el31) || + !mesh.LegalTet(el32) || + !mesh.LegalTet(el33)) + bad2 += 1e4; + + + bool do_swap = (bad2 < bad1); + + if ( ((bad2 < 1e6) || (bad2 < 10 * bad1)) && + mesh.BoundaryEdge (pi4, pi5)) + do_swap = 1; + + if (do_swap) + { + // cout << "do swap, eli1 = " << eli1 << "; eli2 = " << eli2 << endl; + // (*mycout) << "2->3 " << flush; + cnt++; + + el31.flags.illegal_valid = 0; + el32.flags.illegal_valid = 0; + el33.flags.illegal_valid = 0; + + mesh[eli1] = el31; + mesh[eli2] = el32; + + ElementIndex neli = + mesh.AddVolumeElement (el33); + + /* + if (!LegalTet(el31) || !LegalTet(el32) || + !LegalTet(el33)) + { + cout << "Swap to illegal tets !!!" << endl; + } + */ + // cout << "neli = " << neli << endl; + for (int l = 0; l < 4; l++) + { + elementsonnode.Add (el31[l], eli1); + elementsonnode.Add (el32[l], eli2); + elementsonnode.Add (el33[l], neli); + } + + break; + } + } + } + } + } + } + + + PrintMessage (5, cnt, " swaps performed"); + + + + /* + CalcSurfacesOfNode (); + for (i = 1; i <= GetNE(); i++) + if (volelements.Get(i).PNum(1)) + if (!LegalTet (volelements.Get(i))) + { + cout << "detected illegal tet, 2" << endl; + (*testout) << "detected illegal tet2: " << i << endl; + } + */ + + + bad1 = CalcTotalBad (mesh.Points(), mesh.VolumeElements()); + (*testout) << "Total badness = " << bad1 << endl; + (*testout) << "swapimprove2 done" << "\n"; + // (*mycout) << "Vol = " << CalcVolume (points, volelements) << "\n"; +} + + +/* + void Mesh :: SwapImprove2 (OPTIMIZEGOAL goal) + { + int i, j; + int eli1, eli2; + int mattyp; + + Element el31(4), el32(4), el33(4); + double bad1, bad2; + + + INDEX_3_HASHTABLE elsonface (GetNE()); + + (*mycout) << "SwapImprove2 " << endl; + (*testout) << "\n" << "Start SwapImprove2" << "\n"; + + // Calculate total badness + + if (goal == OPT_QUALITY) + { + double bad1 = CalcTotalBad (points, volelements); + (*testout) << "Total badness = " << bad1 << endl; + } + + // find elements on node + + + Element2d face; + for (i = 1; i <= GetNE(); i++) + if ( (i > eltyps.Size()) || (eltyps.Get(i) != FIXEDELEMENT) ) + { + const Element & el = VolumeElement(i); + if (!el.PNum(1)) continue; + + for (j = 1; j <= 4; j++) + { + el.GetFace (j, face); + INDEX_3 i3 (face.PNum(1), face.PNum(2), face.PNum(3)); + i3.Sort(); + + + int bnr, posnr; + if (!elsonface.PositionCreate (i3, bnr, posnr)) + { + INDEX_2 i2; + elsonface.GetData (bnr, posnr, i3, i2); + i2.I2() = i; + elsonface.SetData (bnr, posnr, i3, i2); + } + else + { + INDEX_2 i2 (i, 0); + elsonface.SetData (bnr, posnr, i3, i2); + } + + // if (elsonface.Used (i3)) + // { + // INDEX_2 i2 = elsonface.Get(i3); + // i2.I2() = i; + // elsonface.Set (i3, i2); + // } + // else + // { + // INDEX_2 i2 (i, 0); + // elsonface.Set (i3, i2); + // } + + } + } + + BitArray original(GetNE()); + original.Set(); + + for (i = 1; i <= GetNSE(); i++) + { + const Element2d & sface = SurfaceElement(i); + INDEX_3 i3 (sface.PNum(1), sface.PNum(2), sface.PNum(3)); + i3.Sort(); + INDEX_2 i2(0,0); + elsonface.Set (i3, i2); + } + + + for (i = 1; i <= elsonface.GetNBags(); i++) + for (j = 1; j <= elsonface.GetBagSize(i); j++) + { + INDEX_3 i3; + INDEX_2 i2; + elsonface.GetData (i, j, i3, i2); + + + int eli1 = i2.I1(); + int eli2 = i2.I2(); + + if (eli1 && eli2 && original.Test(eli1) && original.Test(eli2) ) + { + Element & elem = volelements.Elem(eli1); + Element & elem2 = volelements.Elem(eli2); + + int pi1 = i3.I1(); + int pi2 = i3.I2(); + int pi3 = i3.I3(); + + int pi4 = elem.PNum(1) + elem.PNum(2) + elem.PNum(3) + elem.PNum(4) - pi1 - pi2 - pi3; + int pi5 = elem2.PNum(1) + elem2.PNum(2) + elem2.PNum(3) + elem2.PNum(4) - pi1 - pi2 - pi3; + + + + + + + el31.PNum(1) = pi1; + el31.PNum(2) = pi2; + el31.PNum(3) = pi3; + el31.PNum(4) = pi4; + el31.SetIndex (mattyp); + + if (WrongOrientation (points, el31)) + swap (pi1, pi2); + + + bad1 = CalcBad (points, elem, 0) + + CalcBad (points, elem2, 0); + + // if (!LegalTet(elem) || !LegalTet(elem2)) + // bad1 += 1e4; + + + el31.PNum(1) = pi1; + el31.PNum(2) = pi2; + el31.PNum(3) = pi5; + el31.PNum(4) = pi4; + el31.SetIndex (mattyp); + + el32.PNum(1) = pi2; + el32.PNum(2) = pi3; + el32.PNum(3) = pi5; + el32.PNum(4) = pi4; + el32.SetIndex (mattyp); + + el33.PNum(1) = pi3; + el33.PNum(2) = pi1; + el33.PNum(3) = pi5; + el33.PNum(4) = pi4; + el33.SetIndex (mattyp); + + bad2 = CalcBad (points, el31, 0) + + CalcBad (points, el32, 0) + + CalcBad (points, el33, 0); + + // if (!LegalTet(el31) || !LegalTet(el32) || + // !LegalTet(el33)) + // bad2 += 1e4; + + + int swap = (bad2 < bad1); + + INDEX_2 hi2b(pi4, pi5); + hi2b.Sort(); + + if ( ((bad2 < 1e6) || (bad2 < 10 * bad1)) && + boundaryedges->Used (hi2b) ) + swap = 1; + + if (swap) + { + (*mycout) << "2->3 " << flush; + + volelements.Elem(eli1) = el31; + volelements.Elem(eli2) = el32; + volelements.Append (el33); + + original.Clear (eli1); + original.Clear (eli2); + } + } + } + + (*mycout) << endl; + + if (goal == OPT_QUALITY) + { + bad1 = CalcTotalBad (points, volelements); + (*testout) << "Total badness = " << bad1 << endl; + } + + // FindOpenElements (); + + (*testout) << "swapimprove2 done" << "\n"; + } + +*/ +} diff --git a/libsrc/meshing/improve3.hpp b/libsrc/meshing/improve3.hpp new file mode 100644 index 00000000..41001e84 --- /dev/null +++ b/libsrc/meshing/improve3.hpp @@ -0,0 +1,125 @@ +#ifndef FILE_IMPROVE3 +#define FILE_IMPROVE3 + + +extern double CalcTotalBad (const Mesh::T_POINTS & points, + const Mesh::T_VOLELEMENTS & elements, + const MeshingParameters & mp); + + +/// +class MeshOptimize3d +{ + const MeshingParameters & mp; +public: + MeshOptimize3d (const MeshingParameters & amp) : mp(amp) { ; } + void CombineImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); + void SplitImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); + void SwapImprove (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY, + const BitArray * working_elements = NULL); + void SwapImproveSurface (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY, + const BitArray * working_elements = NULL, + const Array< Array* > * idmaps = NULL); + void SwapImprove2 (Mesh & mesh, OPTIMIZEGOAL goal = OPT_QUALITY); + + double + CalcBad (const Mesh::T_POINTS & points, const Element & elem, double h) + { + if (elem.GetType() == TET) + return CalcTetBadness (points[elem[0]], points[elem[1]], + points[elem[2]], points[elem[3]], h, mp); + return 0; + } + + + double CalcTotalBad (const Mesh::T_POINTS & points, + const Mesh::T_VOLELEMENTS & elements) + { + return netgen::CalcTotalBad (points, elements, mp); + } + +}; + + +inline double +CalcBad (const Mesh::T_POINTS & points, const Element & elem, double h, const MeshingParameters & mp) +{ + if (elem.GetType() == TET) + return CalcTetBadness (points[elem[0]], points[elem[1]], + points[elem[2]], points[elem[3]], h, mp); + return 0; +} + + + +extern int WrongOrientation (const Mesh::T_POINTS & points, const Element & el); + + +/* Functional depending of inner point inside triangular surface */ + + +class MinFunctionSum : public MinFunction +{ +protected: + Array functions; + +public: + + virtual double Func (const Vector & x) const; + virtual void Grad (const Vector & x, Vector & g) const; + virtual double FuncGrad (const Vector & x, Vector & g) const; + virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; + virtual double GradStopping (const Vector & x) const; + + void AddFunction(MinFunction & fun); + + const MinFunction & Function(int i) const; + MinFunction & Function(int i); +}; + + +class PointFunction1 : public MinFunction +{ + Mesh::T_POINTS & points; + const Array & faces; + const MeshingParameters & mp; + double h; +public: + PointFunction1 (Mesh::T_POINTS & apoints, + const Array & afaces, + const MeshingParameters & amp, + double ah); + + virtual double Func (const Vector & x) const; + virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; + virtual double FuncGrad (const Vector & x, Vector & g) const; + virtual double GradStopping (const Vector & x) const; +}; + +class JacobianPointFunction : public MinFunction +{ +public: + Mesh::T_POINTS & points; + const Mesh::T_VOLELEMENTS & elements; + TABLE elementsonpoint; + PointIndex actpind; + + bool onplane; + Vec<3> nv; + +public: + JacobianPointFunction (Mesh::T_POINTS & apoints, + const Mesh::T_VOLELEMENTS & aelements); + + virtual void SetPointIndex (PointIndex aactpind); + virtual double Func (const Vector & x) const; + virtual double FuncGrad (const Vector & x, Vector & g) const; + virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; + + inline void SetNV(const Vec<3> & anv) {nv = anv; onplane = true;} + inline void UnSetNV(void) {onplane = false;} +}; + + + +#endif diff --git a/libsrc/meshing/localh.cpp b/libsrc/meshing/localh.cpp new file mode 100644 index 00000000..99767360 --- /dev/null +++ b/libsrc/meshing/localh.cpp @@ -0,0 +1,708 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + + GradingBox :: GradingBox (const double * ax1, const double * ax2) + { + h2 = 0.5 * (ax2[0] - ax1[0]); + for (int i = 0; i < 3; i++) + xmid[i] = 0.5 * (ax1[i] + ax2[i]); + + for (int i = 0; i < 8; i++) + childs[i] = NULL; + father = NULL; + + flags.cutboundary = 0; + flags.isinner = 0; + flags.oldcell = 0; + flags.pinner = 0; + + hopt = 2 * h2; + } + + + BlockAllocator GradingBox :: ball(sizeof (GradingBox)); + + void * GradingBox :: operator new(size_t) + { + return ball.Alloc(); + } + + void GradingBox :: operator delete (void * p) + { + ball.Free (p); + } + + + + + + void GradingBox :: DeleteChilds() + { + for (int i = 0; i < 8; i++) + if (childs[i]) + { + childs[i]->DeleteChilds(); + delete childs[i]; + childs[i] = NULL; + } + } + + + LocalH :: LocalH (const Point3d & pmin, const Point3d & pmax, double agrading) + { + double x1[3], x2[3]; + double hmax; + + boundingbox = Box3d (pmin, pmax); + grading = agrading; + + // a small enlargement, non-regular points + double val = 0.0879; + for (int i = 1; i <= 3; i++) + { + x1[i-1] = (1 + val * i) * pmin.X(i) - val * i * pmax.X(i); + x2[i-1] = 1.1 * pmax.X(i) - 0.1 * pmin.X(i); + } + + hmax = x2[0] - x1[0]; + for (int i = 1; i <= 2; i++) + if (x2[i] - x1[i] > hmax) + hmax = x2[i] - x1[i]; + + for (int i = 0; i <= 2; i++) + x2[i] = x1[i] + hmax; + + root = new GradingBox (x1, x2); + boxes.Append (root); + } + + + LocalH :: LocalH (const Box<3> & box, double agrading) + { + Point3d pmin = box.PMin(); + Point3d pmax = box.PMax(); + + double x1[3], x2[3]; + double hmax; + + boundingbox = Box3d (pmin, pmax); + grading = agrading; + + // a small enlargement, non-regular points + double val = 0.0879; + for (int i = 1; i <= 3; i++) + { + x1[i-1] = (1 + val * i) * pmin.X(i) - val * i * pmax.X(i); + x2[i-1] = 1.1 * pmax.X(i) - 0.1 * pmin.X(i); + } + + hmax = x2[0] - x1[0]; + for (int i = 1; i <= 2; i++) + if (x2[i] - x1[i] > hmax) + hmax = x2[i] - x1[i]; + + for (int i = 0; i <= 2; i++) + x2[i] = x1[i] + hmax; + + root = new GradingBox (x1, x2); + boxes.Append (root); + } + + + + + LocalH :: ~LocalH () + { + root->DeleteChilds(); + delete root; + } + + void LocalH :: Delete () + { + root->DeleteChilds(); + } + + void LocalH :: SetH (const Point3d & p, double h) + { + /* + (*testout) << "Set h at " << p << " to " << h << endl; + if (h < 1e-8) + { + cout << "do not set h to " << h << endl; + return; + } + */ + + if (fabs (p.X() - root->xmid[0]) > root->h2 || + fabs (p.Y() - root->xmid[1]) > root->h2 || + fabs (p.Z() - root->xmid[2]) > root->h2) + return; + + /* + if (p.X() < root->x1[0] || p.X() > root->x2[0] || + p.Y() < root->x1[1] || p.Y() > root->x2[1] || + p.Z() < root->x1[2] || p.Z() > root->x2[2]) + return; + */ + + + if (GetH(p) <= 1.2 * h) return; + + + GradingBox * box = root; + GradingBox * nbox = root; + GradingBox * ngb; + int childnr; + double x1[3], x2[3]; + + while (nbox) + { + box = nbox; + childnr = 0; + if (p.X() > box->xmid[0]) childnr += 1; + if (p.Y() > box->xmid[1]) childnr += 2; + if (p.Z() > box->xmid[2]) childnr += 4; + nbox = box->childs[childnr]; + }; + + + while (2 * box->h2 > h) + { + childnr = 0; + if (p.X() > box->xmid[0]) childnr += 1; + if (p.Y() > box->xmid[1]) childnr += 2; + if (p.Z() > box->xmid[2]) childnr += 4; + + double h2 = box->h2; + if (childnr & 1) + { + x1[0] = box->xmid[0]; + x2[0] = x1[0]+h2; // box->x2[0]; + } + else + { + x2[0] = box->xmid[0]; + x1[0] = x2[0]-h2; // box->x1[0]; + } + + if (childnr & 2) + { + x1[1] = box->xmid[1]; + x2[1] = x1[1]+h2; // box->x2[1]; + } + else + { + x2[1] = box->xmid[1]; + x1[1] = x2[1]-h2; // box->x1[1]; + } + + if (childnr & 4) + { + x1[2] = box->xmid[2]; + x2[2] = x1[2]+h2; // box->x2[2]; + } + else + { + x2[2] = box->xmid[2]; + x1[2] = x2[2]-h2; // box->x1[2]; + } + + ngb = new GradingBox (x1, x2); + box->childs[childnr] = ngb; + ngb->father = box; + + boxes.Append (ngb); + box = box->childs[childnr]; + } + + box->hopt = h; + + + double hbox = 2 * box->h2; // box->x2[0] - box->x1[0]; + double hnp = h + grading * hbox; + + Point3d np; + for (int i = 1; i <= 3; i++) + { + np = p; + np.X(i) = p.X(i) + hbox; + SetH (np, hnp); + + np.X(i) = p.X(i) - hbox; + SetH (np, hnp); + } + } + + + + double LocalH :: GetH (const Point3d & x) const + { + const GradingBox * box = root; + + while (1) + { + int childnr = 0; + if (x.X() > box->xmid[0]) childnr += 1; + if (x.Y() > box->xmid[1]) childnr += 2; + if (x.Z() > box->xmid[2]) childnr += 4; + + if (box->childs[childnr]) + box = box->childs[childnr]; + else + return box->hopt; + } + } + + + /// minimal h in box (pmin, pmax) + double LocalH :: GetMinH (const Point3d & pmin, const Point3d & pmax) const + { + Point3d pmin2, pmax2; + for (int j = 1; j <= 3; j++) + if (pmin.X(j) < pmax.X(j)) + { pmin2.X(j) = pmin.X(j); pmax2.X(j) = pmax.X(j); } + else + { pmin2.X(j) = pmax.X(j); pmax2.X(j) = pmin.X(j); } + + return GetMinHRec (pmin2, pmax2, root); + } + + + double LocalH :: GetMinHRec (const Point3d & pmin, const Point3d & pmax, + const GradingBox * box) const + { + double h2 = box->h2; + if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 || + pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 || + pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2) + return 1e8; + + double hmin = 2 * box->h2; // box->x2[0] - box->x1[0]; + + for (int i = 0; i < 8; i++) + if (box->childs[i]) + hmin = min2 (hmin, GetMinHRec (pmin, pmax, box->childs[i])); + + return hmin; + } + + + void LocalH :: CutBoundaryRec (const Point3d & pmin, const Point3d & pmax, + GradingBox * box) + { + double h2 = box->h2; + if (pmax.X() < box->xmid[0]-h2 || pmin.X() > box->xmid[0]+h2 || + pmax.Y() < box->xmid[1]-h2 || pmin.Y() > box->xmid[1]+h2 || + pmax.Z() < box->xmid[2]-h2 || pmin.Z() > box->xmid[2]+h2) + return; + + + box->flags.cutboundary = 1; + for (int i = 0; i < 8; i++) + if (box->childs[i]) + CutBoundaryRec (pmin, pmax, box->childs[i]); + } + + + + + void LocalH :: FindInnerBoxes (AdFront3 * adfront, + int (*testinner)(const Point3d & p1)) + { + int nf = adfront->GetNF(); + + for (int i = 0; i < boxes.Size(); i++) + boxes[i] -> flags.isinner = 0; + + root->flags.isinner = 0; + + Point3d rpmid(root->xmid[0], root->xmid[1], root->xmid[2]); + Vec3d rv(root->h2, root->h2, root->h2); + Point3d rx2 = rpmid + rv; + // Point3d rx1 = rpmid - rv; + + + root->flags.pinner = !adfront->SameSide (rpmid, rx2); + + if (testinner) + (*testout) << "inner = " << root->flags.pinner << " =?= " + << testinner(Point3d(root->xmid[0], root->xmid[1], root->xmid[2])) << endl; + + Array faceinds(nf); + Array faceboxes(nf); + + for (int i = 1; i <= nf; i++) + { + faceinds.Elem(i) = i; + adfront->GetFaceBoundingBox(i, faceboxes.Elem(i)); + } + + for (int i = 0; i < 8; i++) + FindInnerBoxesRec2 (root->childs[i], adfront, faceboxes, faceinds, nf); + } + + + void LocalH :: + FindInnerBoxesRec2 (GradingBox * box, + class AdFront3 * adfront, + Array & faceboxes, + Array & faceinds, int nfinbox) + { + if (!box) return; + + GradingBox * father = box -> father; + + Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); + Vec3d v(box->h2, box->h2, box->h2); + Box3d boxc(c-v, c+v); + + Point3d fc(father->xmid[0], father->xmid[1], father->xmid[2]); + Vec3d fv(father->h2, father->h2, father->h2); + Box3d fboxc(fc-fv, fc+fv); + + Box3d boxcfc(c,fc); + + ArrayMem faceused; + ArrayMem faceused2; + ArrayMem facenotused; + + /* + faceused.SetSize(0); + facenotused.SetSize(0); + faceused2.SetSize(0); + */ + + for (int j = 1; j <= nfinbox; j++) + { + // adfront->GetFaceBoundingBox (faceinds.Get(j), facebox); + const Box3d & facebox = faceboxes.Get(faceinds.Get(j)); + + if (boxc.Intersect (facebox)) + faceused.Append(faceinds.Get(j)); + else + facenotused.Append(faceinds.Get(j)); + + if (boxcfc.Intersect (facebox)) + faceused2.Append (faceinds.Get(j)); + } + + for (int j = 1; j <= faceused.Size(); j++) + faceinds.Elem(j) = faceused.Get(j); + for (int j = 1; j <= facenotused.Size(); j++) + faceinds.Elem(j+faceused.Size()) = facenotused.Get(j); + + + if (!father->flags.cutboundary) + { + box->flags.isinner = father->flags.isinner; + box->flags.pinner = father->flags.pinner; + } + else + { + Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]); + + if (father->flags.isinner) + box->flags.pinner = 1; + else + { + if (adfront->SameSide (c, cf, &faceused2)) + box->flags.pinner = father->flags.pinner; + else + box->flags.pinner = 1 - father->flags.pinner; + } + + if (box->flags.cutboundary) + box->flags.isinner = 0; + else + box->flags.isinner = box->flags.pinner; + } + + // cout << "faceused: " << faceused.Size() << ", " << faceused2.Size() << ", " << facenotused.Size() << endl; + + int nf = faceused.Size(); + for (int i = 0; i < 8; i++) + FindInnerBoxesRec2 (box->childs[i], adfront, faceboxes, faceinds, nf); + } + + + + void LocalH :: FindInnerBoxesRec ( int (*inner)(const Point3d & p), + GradingBox * box) + { + if (box->flags.cutboundary) + { + for (int i = 0; i < 8; i++) + if (box->childs[i]) + FindInnerBoxesRec (inner, box->childs[i]); + } + else + { + if (inner (box->PMid())) + SetInnerBoxesRec (box); + } + } + + + + + + + + + + + + + + + + + + + + void LocalH :: FindInnerBoxes (AdFront2 * adfront, + int (*testinner)(const Point<2> & p1)) + { + int nf = adfront->GetNFL(); + + for (int i = 0; i < boxes.Size(); i++) + boxes[i] -> flags.isinner = 0; + + root->flags.isinner = 0; + + Point<2> rpmid(root->xmid[0], root->xmid[1], root->xmid[2]); + Vec<2> rv(root->h2, root->h2); + Point<2> rx2 = rpmid + rv; + // Point<2> rx1 = rpmid - rv; + + + root->flags.pinner = !adfront->SameSide (rpmid, rx2); + + if (testinner) + (*testout) << "inner = " << root->flags.pinner << " =?= " + << testinner(rpmid) << endl; + + Array faceinds(nf); + Array > faceboxes(nf); + + for (int i = 0; i < nf; i++) + { + faceinds[i] = i; + // adfront->GetFaceBoundingBox(i, faceboxes.Elem(i)); + + const FrontLine & line = adfront->GetLine(i); + faceboxes[i].Set (adfront->GetPoint (line.L().I1())); + faceboxes[i].Add (adfront->GetPoint (line.L().I2())); + + } + + for (int i = 0; i < 8; i++) + FindInnerBoxesRec2 (root->childs[i], adfront, faceboxes, faceinds, nf); + } + + + void LocalH :: + FindInnerBoxesRec2 (GradingBox * box, + class AdFront2 * adfront, + Array > & faceboxes, + Array & faceinds, int nfinbox) + { + if (!box) return; + + GradingBox * father = box -> father; + + Point3d c(box->xmid[0], box->xmid[1], box->xmid[2]); + Vec3d v(box->h2, box->h2, box->h2); + Box3d boxc(c-v, c+v); + + Point3d fc(father->xmid[0], father->xmid[1], father->xmid[2]); + Vec3d fv(father->h2, father->h2, father->h2); + Box3d fboxc(fc-fv, fc+fv); + + Box3d boxcfc(c,fc); + + ArrayMem faceused; + ArrayMem faceused2; + ArrayMem facenotused; + + + for (int j = 1; j <= nfinbox; j++) + { + // adfront->GetFaceBoundingBox (faceinds.Get(j), facebox); + const Box3d & facebox = faceboxes.Get(faceinds.Get(j)); + + if (boxc.Intersect (facebox)) + faceused.Append(faceinds.Get(j)); + else + facenotused.Append(faceinds.Get(j)); + + if (boxcfc.Intersect (facebox)) + faceused2.Append (faceinds.Get(j)); + } + + for (int j = 1; j <= faceused.Size(); j++) + faceinds.Elem(j) = faceused.Get(j); + for (int j = 1; j <= facenotused.Size(); j++) + faceinds.Elem(j+faceused.Size()) = facenotused.Get(j); + + + if (!father->flags.cutboundary) + { + box->flags.isinner = father->flags.isinner; + box->flags.pinner = father->flags.pinner; + } + else + { + Point3d cf(father->xmid[0], father->xmid[1], father->xmid[2]); + + if (father->flags.isinner) + box->flags.pinner = 1; + else + { + Point<2> c2d (c.X(), c.Y()); + Point<2> cf2d (cf.X(), cf.Y()); + if (adfront->SameSide (c2d, cf2d, &faceused2)) + box->flags.pinner = father->flags.pinner; + else + box->flags.pinner = 1 - father->flags.pinner; + } + + if (box->flags.cutboundary) + box->flags.isinner = 0; + else + box->flags.isinner = box->flags.pinner; + } + + // cout << "faceused: " << faceused.Size() << ", " << faceused2.Size() << ", " << facenotused.Size() << endl; + + int nf = faceused.Size(); + for (int i = 0; i < 8; i++) + FindInnerBoxesRec2 (box->childs[i], adfront, faceboxes, faceinds, nf); + } + + + + void LocalH :: FindInnerBoxesRec ( int (*inner)(const Point<2> & p), + GradingBox * box) + { + if (box->flags.cutboundary) + { + for (int i = 0; i < 8; i++) + if (box->childs[i]) + FindInnerBoxesRec (inner, box->childs[i]); + } + else + { + Point<2> p2d(box->PMid()(0), box->PMid()(1)); + if (inner (p2d)) + SetInnerBoxesRec (box); + } + } + + + + + + + + + + + + + + + + + + void LocalH :: SetInnerBoxesRec (GradingBox * box) + { + box->flags.isinner = 1; + for (int i = 0; i < 8; i++) + if (box->childs[i]) + ClearFlagsRec (box->childs[i]); + } + + void LocalH :: ClearFlagsRec (GradingBox * box) + { + box->flags.cutboundary = 0; + box->flags.isinner = 0; + for (int i = 0; i < 8; i++) + if (box->childs[i]) + ClearFlagsRec (box->childs[i]); + } + + + void LocalH :: WidenRefinement () + { + for (int i = 0; i < boxes.Size(); i++) + { + double h = boxes[i]->hopt; + Point3d c = boxes[i]->PMid(); + + for (int i1 = -1; i1 <= 1; i1++) + for (int i2 = -1; i2 <= 1; i2++) + for (int i3 = -1; i3 <= 1; i3++) + SetH (Point3d (c.X() + i1 * h, + c.Y() + i2 * h, + c.Z() + i3 * h), 1.001 * h); + } + } + + void LocalH :: GetInnerPoints (Array > & points) + { + for (int i = 0; i < boxes.Size(); i++) + if (boxes[i] -> flags.isinner) + points.Append ( boxes[i] -> PMid() ); + } + + + void LocalH :: GetOuterPoints (Array > & points) + { + for (int i = 0; i < boxes.Size(); i++) + if (!boxes[i]->flags.isinner && !boxes[i]->flags.cutboundary) + points.Append ( boxes[i] -> PMid()); + } + + + void LocalH :: Convexify () + { + ConvexifyRec (root); + } + + void LocalH :: ConvexifyRec (GradingBox * box) + { + Point<3> center = box -> PMid(); + + double size = 2 * box->h2; // box->x2[0] - box->x1[0]; + double dx = 0.6 * size; + + double maxh = box->hopt; + + for (int i = 0; i < 3; i++) + { + Point<3> hp = center; + hp(i) += dx; + maxh = max2 (maxh, GetH(hp)); + hp(i) = center(i)-dx; + maxh = max2 (maxh, GetH(hp)); + } + + if (maxh < 0.95 * box->hopt) + SetH (center, maxh); + + for (int i = 0; i < 8; i++) + if (box->childs[i]) + ConvexifyRec (box->childs[i]); + } + + void LocalH :: PrintMemInfo (ostream & ost) const + { + ost << "LocalH: " << boxes.Size() << " boxes of " << sizeof(GradingBox) + << " bytes = " << boxes.Size()*sizeof(GradingBox) << " bytes" << endl; + } +} diff --git a/libsrc/meshing/localh.hpp b/libsrc/meshing/localh.hpp new file mode 100644 index 00000000..ee279c86 --- /dev/null +++ b/libsrc/meshing/localh.hpp @@ -0,0 +1,187 @@ +#ifndef LOCALH +#define LOCALH + +/**************************************************************************/ +/* File: localh.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 29. Jan. 97 */ +/**************************************************************************/ + + +namespace netgen +{ + + + /// box for grading + class GradingBox + { + /// xmid + float xmid[3]; + /// half edgelength + float h2; + /// + GradingBox * childs[8]; + /// + GradingBox * father; + /// + double hopt; + /// + public: + + struct + { + unsigned int cutboundary:1; + unsigned int isinner:1; + unsigned int oldcell:1; + unsigned int pinner:1; + } flags; + + /// + GradingBox (const double * ax1, const double * ax2); + /// + void DeleteChilds(); + /// + + Point<3> PMid() const { return Point<3> (xmid[0], xmid[1], xmid[2]); } + double H2() const { return h2; } + + friend class LocalH; + + static BlockAllocator ball; + void * operator new(size_t); + void operator delete (void *); + }; + + + + + /** + Control of 3D mesh grading + */ + class LocalH + { + /// + GradingBox * root; + /// + double grading; + /// + Array boxes; + /// + Box3d boundingbox; + public: + /// + LocalH (const Point3d & pmin, const Point3d & pmax, double grading); + /// + LocalH (const Box<3> & box, double grading); + /// + ~LocalH(); + /// + void Delete(); + /// + void SetGrading (double agrading) { grading = agrading; } + /// + void SetH (const Point3d & x, double h); + /// + double GetH (const Point3d & x) const; + /// minimal h in box (pmin, pmax) + double GetMinH (const Point3d & pmin, const Point3d & pmax) const; + + /// mark boxes intersecting with boundary-box + // void CutBoundary (const Point3d & pmin, const Point3d & pmax) + // { CutBoundaryRec (pmin, pmax, root); } + void CutBoundary (const Box<3> & box) + { CutBoundaryRec (box.PMin(), box.PMax(), root); } + + /// find inner boxes + void FindInnerBoxes (class AdFront3 * adfront, + int (*testinner)(const Point3d & p1)); + + void FindInnerBoxes (class AdFront2 * adfront, + int (*testinner)(const Point<2> & p1)); + + + /// clears all flags + void ClearFlags () + { ClearFlagsRec(root); } + + /// widen refinement zone + void WidenRefinement (); + + /// get points in inner elements + void GetInnerPoints (Array > & points); + + /// get points in outer closure + void GetOuterPoints (Array > & points); + + /// + void Convexify (); + /// + int GetNBoxes () { return boxes.Size(); } + const Box3d & GetBoundingBox () const + { return boundingbox; } + /// + void PrintMemInfo (ostream & ost) const; + private: + /// + double GetMinHRec (const Point3d & pmin, const Point3d & pmax, + const GradingBox * box) const; + /// + void CutBoundaryRec (const Point3d & pmin, const Point3d & pmax, + GradingBox * box); + + /// + void FindInnerBoxesRec ( int (*inner)(const Point3d & p), + GradingBox * box); + + /// + void FindInnerBoxesRec2 (GradingBox * box, + class AdFront3 * adfront, + Array & faceboxes, + Array & finds, int nfinbox); + + + + void FindInnerBoxesRec ( int (*inner)(const Point<2> & p), + GradingBox * box); + + /// + void FindInnerBoxesRec2 (GradingBox * box, + class AdFront2 * adfront, + Array > & faceboxes, + Array & finds, int nfinbox); + + + + /// + void SetInnerBoxesRec (GradingBox * box); + + /// + void ClearFlagsRec (GradingBox * box); + + /// + void ConvexifyRec (GradingBox * box); + + friend ostream & operator<< (ostream & ost, const LocalH & loch); + }; + + + + + inline ostream & operator<< (ostream & ost, const GradingBox & box) + { + ost << "gradbox, pmid = " << box.PMid() << ", h2 = " << box.H2() + << " cutbound = " << box.flags.cutboundary << " isinner = " << box.flags.isinner + << endl; + return ost; + } + + inline ostream & operator<< (ostream & ost, const LocalH & loch) + { + for (int i = 0; i < loch.boxes.Size(); i++) + ost << "box[" << i << "] = " << *(loch.boxes[i]); + return ost; + } + +} + +#endif diff --git a/libsrc/meshing/meshclass.cpp b/libsrc/meshing/meshclass.cpp new file mode 100644 index 00000000..70e85eee --- /dev/null +++ b/libsrc/meshing/meshclass.cpp @@ -0,0 +1,5635 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + + Mesh :: Mesh () + : surfarea(*this) + { + // volelements.SetName ("vol elements"); + // surfelements.SetName ("surf elements"); + // points.SetName ("meshpoints"); + + boundaryedges = NULL; + surfelementht = NULL; + segmentht = NULL; + + lochfunc = NULL; + mglevels = 1; + elementsearchtree = NULL; + elementsearchtreets = NextTimeStamp(); + majortimestamp = timestamp = NextTimeStamp(); + hglob = 1e10; + hmin = 0; + numvertices = -1; + dimension = 3; + + topology = new MeshTopology (*this); + curvedelems = new CurvedElements (*this); + clusters = new AnisotropicClusters (*this); + ident = new Identifications (*this); + + hpelements = NULL; + coarsemesh = NULL; + + ps_startelement = 0; + + geomtype = NO_GEOM; + + bcnames.SetSize(0); + +#ifdef PARALLEL + paralleltop = new ParallelMeshTopology (*this); +#endif + } + + + Mesh :: ~Mesh() + { + delete lochfunc; + delete boundaryedges; + delete surfelementht; + delete segmentht; + delete curvedelems; + delete clusters; + delete topology; + delete ident; + delete elementsearchtree; + delete coarsemesh; + delete hpelements; + + for (int i = 0; i < materials.Size(); i++) + delete [] materials[i]; + + for(int i = 0; i < userdata_int.Size(); i++) + delete userdata_int[i]; + for(int i = 0; i < userdata_double.Size(); i++) + delete userdata_double[i]; + + for (int i = 0; i < bcnames.Size(); i++ ) + if ( bcnames[i] ) delete bcnames[i]; + +#ifdef PARALLEL + delete paralleltop; +#endif + } + + + Mesh & Mesh :: operator= (const Mesh & mesh2) + { + points = mesh2.points; + // eltyps = mesh2.eltyps; + segments = mesh2.segments; + surfelements = mesh2.surfelements; + volelements = mesh2.volelements; + lockedpoints = mesh2.lockedpoints; + facedecoding = mesh2.facedecoding; + dimension = mesh2.dimension; + + bcnames.SetSize( mesh2.bcnames.Size() ); + for ( int i = 0; i < mesh2.bcnames.Size(); i++ ) + if ( mesh2.bcnames[i] ) bcnames[i] = new string ( *mesh2.bcnames[i] ); + else bcnames[i] = 0; + + return *this; + } + + + void Mesh :: DeleteMesh() + { + NgLock lock(mutex); + lock.Lock(); + + points.SetSize(0); + segments.SetSize(0); + surfelements.SetSize(0); + volelements.SetSize(0); + lockedpoints.SetSize(0); + surfacesonnode.SetSize(0); + + delete boundaryedges; + boundaryedges = NULL; + + openelements.SetSize(0); + facedecoding.SetSize(0); + + delete ident; + ident = new Identifications (*this); + delete topology; + topology = new MeshTopology (*this); + delete curvedelems; + curvedelems = new CurvedElements (*this); + delete clusters; + clusters = new AnisotropicClusters (*this); + + for ( int i = 0; i < bcnames.Size(); i++ ) + if ( bcnames[i] ) delete bcnames[i]; + +#ifdef PARALLEL + delete paralleltop; + paralleltop = new ParallelMeshTopology (*this); +#endif + + lock.UnLock(); + + timestamp = NextTimeStamp(); + } + + + void Mesh :: ClearSurfaceElements() + { + surfelements.SetSize(0); + for (int i = 0; i < facedecoding.Size(); i++) + facedecoding[i].firstelement = -1; + + timestamp = NextTimeStamp(); + } + + + + PointIndex Mesh :: AddPoint (const Point3d & p, int layer) + { + return AddPoint (p, layer, INNERPOINT); + /* + NgLock lock(mutex); + lock.Lock(); + + timestamp = NextTimeStamp(); + + PointIndex pi = points.End(); + points.Append ( MeshPoint (p, layer, INNERPOINT) ); + + lock.UnLock(); + + return pi; + */ + } + + PointIndex Mesh :: AddPoint (const Point3d & p, int layer, POINTTYPE type) + { + NgLock lock(mutex); + lock.Lock(); + + timestamp = NextTimeStamp(); + + PointIndex pi = points.End(); + points.Append ( MeshPoint (p, layer, type) ); + + lock.UnLock(); + + return pi; + } + + /* +#ifdef PARALLEL + PointIndex Mesh :: AddPoint (const Point3d & p, bool isghost, int layer) + { + NgLock lock(mutex); + lock.Lock(); + + timestamp = NextTimeStamp(); + + PointIndex pi = points.Size() + PointIndex::BASE; + points.Append ( MeshPoint (p, layer, INNERPOINT) ); + + lock.UnLock(); + + return pi; + } + + PointIndex Mesh :: AddPoint (const Point3d & p, bool isghost, int layer, POINTTYPE type) + { + NgLock lock(mutex); + lock.Lock(); + + timestamp = NextTimeStamp(); + + PointIndex pi = points.Size() + PointIndex::BASE; + points.Append ( MeshPoint (p, layer, type) ); + + lock.UnLock(); + + return pi; + } + +#endif + */ + + + SegmentIndex Mesh :: AddSegment (const Segment & s) + { + NgLock lock(mutex); + lock.Lock(); + timestamp = NextTimeStamp(); + + int maxn = max2 (s[0], s[1]); + maxn += 1-PointIndex::BASE; + + /* + if (maxn > ptyps.Size()) + { + int maxo = ptyps.Size(); + ptyps.SetSize (maxn); + for (int i = maxo; i < maxn; i++) + ptyps[i] = INNERPOINT; + } + + if (ptyps[s[0]] > EDGEPOINT) ptyps[s[0]] = EDGEPOINT; + if (ptyps[s[1]] > EDGEPOINT) ptyps[s[1]] = EDGEPOINT; + */ + + if (maxn <= points.Size()) + { + if (points[s[0]].Type() > EDGEPOINT) + points[s[0]].SetType (EDGEPOINT); + if (points[s[1]].Type() > EDGEPOINT) + points[s[1]].SetType (EDGEPOINT); + } + /* + else + { + cerr << "edge points nrs > points.Size" << endl; + } + */ + + SegmentIndex si = segments.Size(); + segments.Append (s); + + lock.UnLock(); + return si; + } + + SurfaceElementIndex Mesh :: AddSurfaceElement (const Element2d & el) + { + NgLock lock(mutex); + lock.Lock(); + timestamp = NextTimeStamp(); + + int maxn = el[0]; + for (int i = 1; i < el.GetNP(); i++) + if (el[i] > maxn) maxn = el[i]; + + maxn += 1-PointIndex::BASE; + + /* + if (maxn > ptyps.Size()) + { + int maxo = ptyps.Size(); + ptyps.SetSize (maxn); + for (i = maxo+PointIndex::BASE; + i < maxn+PointIndex::BASE; i++) + ptyps[i] = INNERPOINT; + + } + */ + if (maxn <= points.Size()) + { + for (int i = 0; i < el.GetNP(); i++) + if (points[el[i]].Type() > SURFACEPOINT) + points[el[i]].SetType(SURFACEPOINT); + } + /* + else + { + cerr << "surf points nrs > points.Size" << endl; + } + */ + + SurfaceElementIndex si = surfelements.Size(); + surfelements.Append (el); + + if (el.index > facedecoding.Size()) + cerr << "has no facedecoding: fd.size = " << facedecoding.Size() << ", ind = " << el.index << endl; + + surfelements.Last().next = facedecoding[el.index-1].firstelement; + facedecoding[el.index-1].firstelement = si; + + if (SurfaceArea().Valid()) + SurfaceArea().Add (el); + + lock.UnLock(); + return si; + } + + + ElementIndex Mesh :: AddVolumeElement (const Element & el) + { + NgLock lock(mutex); + lock.Lock(); + + int maxn = el[0]; + for (int i = 1; i < el.GetNP(); i++) + if (el[i] > maxn) maxn = el[i]; + + maxn += 1-PointIndex::BASE; + + /* + if (maxn > ptyps.Size()) + { + int maxo = ptyps.Size(); + ptyps.SetSize (maxn); + for (i = maxo+PointIndex::BASE; + i < maxn+PointIndex::BASE; i++) + ptyps[i] = INNERPOINT; + } + */ + /* + if (maxn > points.Size()) + { + cerr << "add vol element before point" << endl; + } + */ + + int ve = volelements.Size(); + + volelements.Append (el); + volelements.Last().flags.illegal_valid = 0; + + // while (volelements.Size() > eltyps.Size()) + // eltyps.Append (FREEELEMENT); + + timestamp = NextTimeStamp(); + + lock.UnLock(); + return ve; + } + + + + + + + void Mesh :: Save (const string & filename) const + { + + ofstream outfile(filename.c_str()); + // ogzstream outfile( (filename+".gz") .c_str()); + + Save(outfile); + } + + + + void Mesh :: Save (ostream & outfile) const + { + int i, j; + + double scale = 1; // globflags.GetNumFlag ("scale", 1); + int inverttets = 0; // globflags.GetDefineFlag ("inverttets"); + int invertsurf = 0; // globflags.GetDefineFlag ("invertsurfacemesh"); + + + + outfile << "mesh3d" << "\n"; + + outfile << "dimension\n" << GetDimension() << "\n"; + + outfile << "geomtype\n" << int(geomtype) << "\n"; + + + outfile << "\n"; + outfile << "# surfnr bcnr domin domout np p1 p2 p3" + << "\n"; + + + switch (geomtype) + { + case GEOM_STL: + outfile << "surfaceelementsgi" << "\n"; + break; + case GEOM_OCC: case GEOM_ACIS: + outfile << "surfaceelementsuv" << "\n"; + break; + default: + outfile << "surfaceelements" << "\n"; + } + + outfile << GetNSE() << "\n"; + + SurfaceElementIndex sei; + for (sei = 0; sei < GetNSE(); sei++) + { + if ((*this)[sei].GetIndex()) + { + outfile << " " << GetFaceDescriptor((*this)[sei].GetIndex ()).SurfNr()+1; + outfile << " " << GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); + outfile << " " << GetFaceDescriptor((*this)[sei].GetIndex ()).DomainIn(); + outfile << " " << GetFaceDescriptor((*this)[sei].GetIndex ()).DomainOut(); + } + else + outfile << " 0 0 0"; + + Element2d sel = (*this)[sei]; + if (invertsurf) + sel.Invert(); + + outfile << " " << sel.GetNP(); + for (j = 0; j < sel.GetNP(); j++) + outfile << " " << sel[j]; + + switch (geomtype) + { + case GEOM_STL: + for (j = 1; j <= sel.GetNP(); j++) + outfile << " " << sel.GeomInfoPi(j).trignum; + break; + case GEOM_OCC: case GEOM_ACIS: + for (j = 1; j <= sel.GetNP(); j++) + { + outfile << " " << sel.GeomInfoPi(j).u; + outfile << " " << sel.GeomInfoPi(j).v; + } + break; + default: + ; + } + outfile << "\n"; + } + + outfile << "\n" << "\n"; + outfile << "# matnr np p1 p2 p3 p4" << "\n"; + outfile << "volumeelements" << "\n"; + outfile << GetNE() << "\n"; + + for (ElementIndex ei = 0; ei < GetNE(); ei++) + { + outfile << (*this)[ei].GetIndex(); + outfile << " " << (*this)[ei].GetNP(); + + Element el = (*this)[ei]; + if (inverttets) el.Invert(); + + for (j = 0; j < el.GetNP(); j++) + outfile << " " << el[j]; + outfile << "\n"; + } + + + outfile << "\n" << "\n"; + // outfile << " surf1 surf2 p1 p2" << "\n"; + outfile << "# surfid 0 p1 p2 trignum1 trignum2 domin/surfnr1 domout/surfnr2 ednr1 dist1 ednr2 dist2 \n"; + outfile << "edgesegmentsgi2" << "\n"; + outfile << GetNSeg() << "\n"; + + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + outfile.width(8); + outfile << seg.si; // 2D: bc number, 3D: wievielte Kante + outfile.width(8); + outfile << 0; + outfile.width(8); + outfile << seg[0]; + outfile.width(8); + outfile << seg[1]; + outfile << " "; + outfile.width(8); + outfile << seg.geominfo[0].trignum; // stl dreiecke + outfile << " "; + outfile.width(8); + outfile << seg.geominfo[1].trignum; // << endl; // stl dreieck + + if (dimension == 3) + { + outfile << " "; + outfile.width(8); + outfile << seg.surfnr1+1; + outfile << " "; + outfile.width(8); + outfile << seg.surfnr2+1; + } + else + { + outfile << " "; + outfile.width(8); + outfile << seg.domin; + outfile << " "; + outfile.width(8); + outfile << seg.domout; + } + + outfile << " "; + outfile.width(8); + outfile << seg.edgenr; + outfile << " "; + outfile.width(12); + outfile.precision(16); + outfile << seg.epgeominfo[0].dist; // splineparameter (2D) + outfile << " "; + outfile.width(8); + outfile.precision(16); + outfile << seg.epgeominfo[1].edgenr; // geometry dependent + outfile << " "; + outfile.width(12); + outfile << seg.epgeominfo[1].dist; + + outfile << "\n"; + } + + + outfile << "\n" << "\n"; + outfile << "# X Y Z" << "\n"; + outfile << "points" << "\n"; + outfile << GetNP() << "\n"; + outfile.precision(16); + outfile.setf (ios::fixed, ios::floatfield); + outfile.setf (ios::showpoint); + + PointIndex pi; + for (pi = PointIndex::BASE; + pi < GetNP()+PointIndex::BASE; pi++) + { + outfile.width(22); + outfile << (*this)[pi](0)/scale << " "; + outfile.width(22); + outfile << (*this)[pi](1)/scale << " "; + outfile.width(22); + outfile << (*this)[pi](2)/scale << "\n"; + } + + if (ident -> GetMaxNr() > 0) + { + outfile << "identifications\n"; + Array identpairs; + int cnt = 0; + for (i = 1; i <= ident -> GetMaxNr(); i++) + { + ident -> GetPairs (i, identpairs); + cnt += identpairs.Size(); + } + outfile << cnt << "\n"; + for (i = 1; i <= ident -> GetMaxNr(); i++) + { + ident -> GetPairs (i, identpairs); + for (j = 1; j <= identpairs.Size(); j++) + { + outfile.width (8); + outfile << identpairs.Get(j).I1(); + outfile.width (8); + outfile << identpairs.Get(j).I2(); + outfile.width (8); + outfile << i << "\n"; + } + } + + outfile << "identificationtypes\n"; + outfile << ident -> GetMaxNr() << "\n"; + for (i = 1; i <= ident -> GetMaxNr(); i++) + { + int type = ident -> GetType(i); + outfile << " " << type; + } + outfile << "\n"; + } + + int cntmat = 0; + for (i = 1; i <= materials.Size(); i++) + if (materials.Get(i) && strlen (materials.Get(i))) + cntmat++; + + if (cntmat) + { + outfile << "materials" << endl; + outfile << cntmat << endl; + for (i = 1; i <= materials.Size(); i++) + if (materials.Get(i) && strlen (materials.Get(i))) + outfile << i << " " << materials.Get(i) << endl; + } + + + int cntbcnames = 0; + for ( int ii = 0; ii < bcnames.Size(); ii++ ) + if ( bcnames[ii] ) cntbcnames++; + + if ( cntbcnames ) + { + outfile << "\n\nbcnames" << endl << bcnames.Size() << endl; + for ( i = 0; i < bcnames.Size(); i++ ) + outfile << i+1 << "\t" << GetBCName(i) << endl; + outfile << endl << endl; + } + + /* + if ( GetDimension() == 2 ) + { + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + if ( ! bcprops.Contains(seg.si) && seg.GetBCName() != "" ) + { + bcprops.Append(seg.si); + cntbcnames++; + } + } + } + else + { + for (sei = 0; sei < GetNSE(); sei++) + { + if ((*this)[sei].GetIndex()) + { + int bcp = GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); + string name = GetFaceDescriptor((*this)[sei].GetIndex ()).BCName(); + if ( !bcprops.Contains(bcp) && + name != "" ) + { + bcprops.Append(bcp); + cntbcnames++; + } + } + } + } + + bcprops.SetSize(0); + if ( cntbcnames ) + { + outfile << "\nbcnames" << endl << cntbcnames << endl; + if ( GetDimension() == 2 ) + { + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + if ( ! bcprops.Contains(seg.si) && seg.GetBCName() != "" ) + { + bcprops.Append(seg.si); + outfile << seg.si << "\t" << seg.GetBCName() << endl; + } + } + } + else + { + for (sei = 0; sei < GetNSE(); sei++) + { + if ((*this)[sei].GetIndex()) + { + int bcp = GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); + string name = GetFaceDescriptor((*this)[sei].GetIndex ()).BCName(); + if ( !bcprops.Contains(bcp) && + name != "" ) + { + bcprops.Append(bcp); + outfile << bcp << "\t" << name << endl; + } + } + } + } + outfile << endl << endl; + } + */ + + int cnt_sing = 0; + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + if ((*this)[pi].Singularity()>=1.) cnt_sing++; + + if (cnt_sing) + { + outfile << "singular_points" << endl << cnt_sing << endl; + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + if ((*this)[pi].Singularity()>=1.) + outfile << int(pi) << "\t" << (*this)[pi].Singularity() << endl; + } + + cnt_sing = 0; + for (SegmentIndex si = 0; si < GetNSeg(); si++) + if ( segments[si].singedge_left ) cnt_sing++; + if (cnt_sing) + { + outfile << "singular_edge_left" << endl << cnt_sing << endl; + for (SegmentIndex si = 0; si < GetNSeg(); si++) + if ( segments[si].singedge_left ) + outfile << int(si) << "\t" << segments[si].singedge_left << endl; + } + + cnt_sing = 0; + for (SegmentIndex si = 0; si < GetNSeg(); si++) + if ( segments[si].singedge_right ) cnt_sing++; + if (cnt_sing) + { + outfile << "singular_edge_right" << endl << cnt_sing << endl; + for (SegmentIndex si = 0; si < GetNSeg(); si++) + if ( segments[si].singedge_right ) + outfile << int(si) << "\t" << segments[si].singedge_right << endl; + } + + + cnt_sing = 0; + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domin_singular) + cnt_sing++; + + if (cnt_sing) + { + outfile << "singular_face_inside" << endl << cnt_sing << endl; + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domin_singular) + outfile << int(sei) << "\t" << + GetFaceDescriptor ((*this)[sei].GetIndex()).domin_singular << endl; + } + + cnt_sing = 0; + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domout_singular) cnt_sing++; + if (cnt_sing) + { + outfile << "singular_face_outside" << endl << cnt_sing << endl; + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + if ( GetFaceDescriptor ((*this)[sei].GetIndex()).domout_singular) + outfile << int(sei) << "\t" + << GetFaceDescriptor ((*this)[sei].GetIndex()).domout_singular << endl; + } + + + // Philippose - 09/07/2009 + // Add mesh face colours to Netgen Vol file format + // The colours are saved in RGB triplets + int cnt_facedesc = GetNFD(); + if (cnt_facedesc) + { + outfile << endl << endl << "# Surfnr Red Green Blue" << endl; + outfile << "face_colours" << endl << cnt_facedesc << endl; + + outfile.precision(8); + outfile.setf(ios::fixed, ios::floatfield); + outfile.setf(ios::showpoint); + + for(i = 1; i <= cnt_facedesc; i++) + { + outfile.width(8); + outfile << GetFaceDescriptor(i).SurfNr()+1 << " "; + outfile.width(12); + outfile << GetFaceDescriptor(i).SurfColour().X() << " "; + outfile.width(12); + outfile << GetFaceDescriptor(i).SurfColour().Y() << " "; + outfile.width(12); + outfile << GetFaceDescriptor(i).SurfColour().Z(); + outfile << endl; + } + } + + } + + + + void Mesh :: Load (const string & filename) + { + + ifstream infile(filename.c_str()); + if (!infile.good()) + throw NgException ("mesh file not found"); + + Load(infile); + } + + + + + void Mesh :: Load (istream & infile) + { + + char str[100]; + int i, n; + + double scale = 1; // globflags.GetNumFlag ("scale", 1); + int inverttets = 0; // globflags.GetDefineFlag ("inverttets"); + int invertsurf = 0; // globflags.GetDefineFlag ("invertsurfacemesh"); + + + facedecoding.SetSize(0); + + bool endmesh = false; + + while (infile.good() && !endmesh) + { + infile >> str; + + if (strcmp (str, "dimension") == 0) + { + infile >> dimension; + } + + if (strcmp (str, "geomtype") == 0) + { + int hi; + infile >> hi; + geomtype = GEOM_TYPE(hi); + } + + + if (strcmp (str, "surfaceelements") == 0 || strcmp (str, "surfaceelementsgi")==0 || strcmp (str, "surfaceelementsuv") == 0) + { + infile >> n; + PrintMessage (3, n, " surface elements"); + + bool geominfo = strcmp (str, "surfaceelementsgi") == 0; + bool uv = strcmp (str, "surfaceelementsuv") == 0; + + + for (i = 1; i <= n; i++) + { + int surfnr, bcp, domin, domout, nep, faceind = 0; + + infile >> surfnr >> bcp >> domin >> domout; + surfnr--; + + bool invert_el = false; + /* + if (domin == 0) + { + invert_el = true; + Swap (domin, domout); + } + */ + + for (int j = 1; j <= facedecoding.Size(); j++) + if (GetFaceDescriptor(j).SurfNr() == surfnr && + GetFaceDescriptor(j).BCProperty() == bcp && + GetFaceDescriptor(j).DomainIn() == domin && + GetFaceDescriptor(j).DomainOut() == domout) + faceind = j; + + // if (facedecoding.Size()) faceind = 1; // for timing + + if (!faceind) + { + faceind = AddFaceDescriptor (FaceDescriptor(surfnr, domin, domout, 0)); + GetFaceDescriptor(faceind).SetBCProperty (bcp); + } + + infile >> nep; + if (!nep) nep = 3; + + Element2d tri(nep); + tri.SetIndex(faceind); + + for (int j = 1; j <= nep; j++) + infile >> tri.PNum(j); + + if (geominfo) + for (int j = 1; j <= nep; j++) + infile >> tri.GeomInfoPi(j).trignum; + + if (uv) + for (int j = 1; j <= nep; j++) + infile >> tri.GeomInfoPi(j).u >> tri.GeomInfoPi(j).v; + + if (invertsurf) tri.Invert(); + if (invert_el) tri.Invert(); + + AddSurfaceElement (tri); + } + } + + if (strcmp (str, "volumeelements") == 0) + { + infile >> n; + PrintMessage (3, n, " volume elements"); + for (i = 1; i <= n; i++) + { + Element el; + int hi, nep; + infile >> hi; + if (hi == 0) hi = 1; + el.SetIndex(hi); + infile >> nep; + el.SetNP(nep); + + for (int j = 0; j < nep; j++) + infile >> (int&)(el[j]); + + if (inverttets) + el.Invert(); + + AddVolumeElement (el); + } + } + + + if (strcmp (str, "edgesegments") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + Segment seg; + int hi; + infile >> seg.si >> hi >> seg[0] >> seg[1]; + AddSegment (seg); + } + } + + + + if (strcmp (str, "edgesegmentsgi") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + Segment seg; + int hi; + infile >> seg.si >> hi >> seg[0] >> seg[1] + >> seg.geominfo[0].trignum + >> seg.geominfo[1].trignum; + AddSegment (seg); + } + } + + if (strcmp (str, "edgesegmentsgi2") == 0) + { + int a; + infile >> a; + n=a; + + PrintMessage (3, n, " curve elements"); + + for (i = 1; i <= n; i++) + { + Segment seg; + int hi; + infile >> seg.si >> hi >> seg[0] >> seg[1] + >> seg.geominfo[0].trignum + >> seg.geominfo[1].trignum + >> seg.surfnr1 >> seg.surfnr2 + >> seg.edgenr + >> seg.epgeominfo[0].dist + >> seg.epgeominfo[1].edgenr + >> seg.epgeominfo[1].dist; + + seg.epgeominfo[0].edgenr = seg.epgeominfo[1].edgenr; + + seg.domin = seg.surfnr1; + seg.domout = seg.surfnr2; + + seg.surfnr1--; + seg.surfnr2--; + + AddSegment (seg); + } + } + + if (strcmp (str, "points") == 0) + { + infile >> n; + PrintMessage (3, n, " points"); + for (i = 1; i <= n; i++) + { + Point3d p; + infile >> p.X() >> p.Y() >> p.Z(); + p.X() *= scale; + p.Y() *= scale; + p.Z() *= scale; + AddPoint (p); + } + PrintMessage (3, n, " points done"); + } + + if (strcmp (str, "identifications") == 0) + { + infile >> n; + PrintMessage (3, n, " identifications"); + for (i = 1; i <= n; i++) + { + PointIndex pi1, pi2; + int ind; + infile >> pi1 >> pi2 >> ind; + ident -> Add (pi1, pi2, ind); + } + } + + if (strcmp (str, "identificationtypes") == 0) + { + infile >> n; + PrintMessage (3, n, " identificationtypes"); + for (i = 1; i <= n; i++) + { + int type; + infile >> type; + ident -> SetType(i,Identifications::ID_TYPE(type)); + } + } + + if (strcmp (str, "materials") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + int nr; + string mat; + infile >> nr >> mat; + SetMaterial (nr, mat.c_str()); + } + } + + if ( strcmp (str, "bcnames" ) == 0 ) + { + infile >> n; + Array bcnrs(n); + SetNBCNames(n); + for ( i = 1; i <= n; i++ ) + { + string nextbcname; + infile >> bcnrs[i-1] >> nextbcname; + bcnames[bcnrs[i-1]-1] = new string(nextbcname); + } + + if ( GetDimension() == 2 ) + { + for (i = 1; i <= GetNSeg(); i++) + { + Segment & seg = LineSegment (i); + if ( seg.si <= n ) + seg.SetBCName (bcnames[seg.si-1]); + else + seg.SetBCName(0); + } + } + else + { + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + if ((*this)[sei].GetIndex()) + { + int bcp = GetFaceDescriptor((*this)[sei].GetIndex ()).BCProperty(); + if ( bcp <= n ) + GetFaceDescriptor((*this)[sei].GetIndex ()).SetBCName(bcnames[bcp-1]); + else + GetFaceDescriptor((*this)[sei].GetIndex ()).SetBCName(0); + + } + } + + } + + + } + + if (strcmp (str, "singular_points") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + PointIndex pi; + double s; + infile >> pi; + infile >> s; + (*this)[pi].Singularity (s); + } + } + + if (strcmp (str, "singular_edge_left") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SegmentIndex si; + double s; + infile >> si; + infile >> s; + (*this)[si].singedge_left = s; + } + } + if (strcmp (str, "singular_edge_right") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SegmentIndex si; + double s; + infile >> si; + infile >> s; + (*this)[si].singedge_right = s; + } + } + + if (strcmp (str, "singular_face_inside") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SurfaceElementIndex sei; + double s; + infile >> sei; + infile >> s; + GetFaceDescriptor((*this)[sei].GetIndex()).domin_singular = s; + } + } + + if (strcmp (str, "singular_face_outside") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + SurfaceElementIndex sei; + double s; + infile >> sei; + infile >> s; + GetFaceDescriptor((*this)[sei].GetIndex()).domout_singular = s; + } + } + + // Philippose - 09/07/2009 + // Add mesh face colours to Netgen Vol file format + // The colours are read in as RGB triplets + if (strcmp (str, "face_colours") == 0) + { + int cnt_facedesc = GetNFD(); + infile >> n; + if(n == cnt_facedesc) + { + for(i = 1; i <= n; i++) + { + int surfnr = 0; + Vec3d surfcolour(0.0,1.0,0.0); + + infile >> surfnr + >> surfcolour.X() + >> surfcolour.Y() + >> surfcolour.Z(); + + surfnr--; + + if(surfnr > 0) + { + for(int facedesc = 1; facedesc <= cnt_facedesc; facedesc++) + { + if(surfnr == GetFaceDescriptor(facedesc).SurfNr()) + { + GetFaceDescriptor(facedesc).SetSurfColour(surfcolour); + } + } + } + } + } + } + + if (strcmp (str, "endmesh") == 0) + endmesh = true; + + + + strcpy (str, ""); + } + + + + + CalcSurfacesOfNode (); + + if (ntasks == 1) // sequential run only + { + topology -> Update(); + clusters -> Update(); + } + + SetNextMajorTimeStamp(); + // PrintMemInfo (cout); + } + + + + + + void Mesh :: Merge (const string & filename, const int surfindex_offset) + { + ifstream infile(filename.c_str()); + if (!infile.good()) + throw NgException ("mesh file not found"); + + Merge(infile,surfindex_offset); + + } + + + + void Mesh :: Merge (istream & infile, const int surfindex_offset) + { + char str[100]; + int i, n; + + + int inverttets = 0; // globflags.GetDefineFlag ("inverttets"); + + int oldnp = GetNP(); + int oldne = GetNSeg(); + int oldnd = GetNDomains(); + + for(SurfaceElementIndex si = 0; si < GetNSE(); si++) + for(int j=1; j<=(*this)[si].GetNP(); j++) (*this)[si].GeomInfoPi(j).trignum = -1; + + int max_surfnr = 0; + for (i = 1; i <= GetNFD(); i++) + max_surfnr = max2 (max_surfnr, GetFaceDescriptor(i).SurfNr()); + max_surfnr++; + + if(max_surfnr < surfindex_offset) max_surfnr = surfindex_offset; + + + bool endmesh = false; + + while (infile.good() && !endmesh) + { + infile >> str; + + if (strcmp (str, "surfaceelementsgi") == 0 || strcmp (str, "surfaceelements") == 0) + { + infile >> n; + PrintMessage (3, n, " surface elements"); + for (i = 1; i <= n; i++) + { + int j; + int surfnr, bcp, domin, domout, nep, faceind = 0; + infile >> surfnr >> bcp >> domin >> domout; + + surfnr--; + + if(domin > 0) domin += oldnd; + if(domout > 0) domout += oldnd; + surfnr += max_surfnr; + + + for (j = 1; j <= facedecoding.Size(); j++) + if (GetFaceDescriptor(j).SurfNr() == surfnr && + GetFaceDescriptor(j).BCProperty() == bcp && + GetFaceDescriptor(j).DomainIn() == domin && + GetFaceDescriptor(j).DomainOut() == domout) + faceind = j; + + if (!faceind) + { + faceind = AddFaceDescriptor (FaceDescriptor(surfnr, domin, domout, 0)); + if(GetDimension() == 2) bcp++; + GetFaceDescriptor(faceind).SetBCProperty (bcp); + } + + infile >> nep; + if (!nep) nep = 3; + + Element2d tri(nep); + tri.SetIndex(faceind); + + for (j = 1; j <= nep; j++) + { + infile >> tri.PNum(j); + tri.PNum(j) = tri.PNum(j) + oldnp; + } + + + if (strcmp (str, "surfaceelementsgi") == 0) + for (j = 1; j <= nep; j++) + { + infile >> tri.GeomInfoPi(j).trignum; + tri.GeomInfoPi(j).trignum = -1; + } + + AddSurfaceElement (tri); + } + } + + + if (strcmp (str, "edgesegments") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + Segment seg; + int hi; + infile >> seg.si >> hi >> seg[0] >> seg[1]; + seg[0] = seg[0] + oldnp; + seg[1] = seg[1] + oldnp; + AddSegment (seg); + } + } + + + + if (strcmp (str, "edgesegmentsgi") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + Segment seg; + int hi; + infile >> seg.si >> hi >> seg[0] >> seg[1] + >> seg.geominfo[0].trignum + >> seg.geominfo[1].trignum; + seg[0] = seg[0] + oldnp; + seg[1] = seg[1] + oldnp; + AddSegment (seg); + } + } + if (strcmp (str, "edgesegmentsgi2") == 0) + { + infile >> n; + PrintMessage (3, n, " curve elements"); + + for (i = 1; i <= n; i++) + { + Segment seg; + int hi; + infile >> seg.si >> hi >> seg[0] >> seg[1] + >> seg.geominfo[0].trignum + >> seg.geominfo[1].trignum + >> seg.surfnr1 >> seg.surfnr2 + >> seg.edgenr + >> seg.epgeominfo[0].dist + >> seg.epgeominfo[1].edgenr + >> seg.epgeominfo[1].dist; + seg.epgeominfo[0].edgenr = seg.epgeominfo[1].edgenr; + + seg.surfnr1--; + seg.surfnr2--; + + if(seg.surfnr1 >= 0) seg.surfnr1 = seg.surfnr1 + max_surfnr; + if(seg.surfnr2 >= 0) seg.surfnr2 = seg.surfnr2 + max_surfnr; + seg[0] = seg[0] +oldnp; + seg[1] = seg[1] +oldnp; + seg.edgenr = seg.edgenr + oldne; + seg.epgeominfo[1].edgenr = seg.epgeominfo[1].edgenr + oldne; + + AddSegment (seg); + } + } + + if (strcmp (str, "volumeelements") == 0) + { + infile >> n; + PrintMessage (3, n, " volume elements"); + for (i = 1; i <= n; i++) + { + Element el; + int hi, nep; + infile >> hi; + if (hi == 0) hi = 1; + el.SetIndex(hi+oldnd); + infile >> nep; + el.SetNP(nep); + + for (int j = 0; j < nep; j++) + { + infile >> (int&)(el[j]); + el[j] = el[j]+oldnp; + } + + if (inverttets) + el.Invert(); + + AddVolumeElement (el); + } + } + + + if (strcmp (str, "points") == 0) + { + infile >> n; + PrintMessage (3, n, " points"); + for (i = 1; i <= n; i++) + { + Point3d p; + infile >> p.X() >> p.Y() >> p.Z(); + AddPoint (p); + } + } + + + if (strcmp (str, "endmesh") == 0) + { + endmesh = true; + } + + + if (strcmp (str, "materials") == 0) + { + infile >> n; + for (i = 1; i <= n; i++) + { + int nr; + string mat; + infile >> nr >> mat; + SetMaterial (nr+oldnd, mat.c_str()); + } + } + + + strcpy (str, ""); + } + + CalcSurfacesOfNode (); + + topology -> Update(); + clusters -> Update(); + + SetNextMajorTimeStamp(); + } + + + + + + + + + + + bool Mesh :: TestOk () const + { + for (ElementIndex ei = 0; ei < volelements.Size(); ei++) + { + for (int j = 0; j < 4; j++) + if ( (*this)[ei][j] <= PointIndex::BASE-1) + { + (*testout) << "El " << ei << " has 0 nodes: "; + for (int k = 0; k < 4; k++) + (*testout) << (*this)[ei][k]; + break; + } + } + CheckMesh3D (*this); + return 1; + } + + void Mesh :: SetAllocSize(int nnodes, int nsegs, int nsel, int nel) + { + points.SetAllocSize(nnodes); + segments.SetAllocSize(nsegs); + surfelements.SetAllocSize(nsel); + volelements.SetAllocSize(nel); + } + + + void Mesh :: BuildBoundaryEdges(void) + { + delete boundaryedges; + + boundaryedges = new INDEX_2_CLOSED_HASHTABLE + (3 * (GetNSE() + GetNOpenElements()) + GetNSeg() + 1); + + + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + const Element2d & sel = surfelements[sei]; + if (sel.IsDeleted()) continue; + + // int si = sel.GetIndex(); + + for (int j = 0; j < sel.GetNP(); j++) + { + INDEX_2 i2; + i2.I1() = sel.PNumMod(j+1); + i2.I2() = sel.PNumMod(j+2); + i2.Sort(); + if (sel.GetNP() <= 4) + boundaryedges->Set (i2, 1); + } + } + + + for (int i = 0; i < openelements.Size(); i++) + { + const Element2d & sel = openelements[i]; + for (int j = 0; j < sel.GetNP(); j++) + { + INDEX_2 i2; + i2.I1() = sel.PNumMod(j+1); + i2.I2() = sel.PNumMod(j+2); + i2.Sort(); + boundaryedges->Set (i2, 1); + + points[sel[j]].SetType(FIXEDPOINT); + } + } + + for (int i = 0; i < GetNSeg(); i++) + { + const Segment & seg = segments[i]; + INDEX_2 i2(seg[0], seg[1]); + i2.Sort(); + + boundaryedges -> Set (i2, 2); + //segmentht -> Set (i2, i); + } + + + } + + void Mesh :: CalcSurfacesOfNode () + { + surfacesonnode.SetSize (GetNP()); + + delete boundaryedges; + boundaryedges = NULL; + + delete surfelementht; + delete segmentht; + + /* + surfelementht = new INDEX_3_HASHTABLE (GetNSE()/4 + 1); + segmentht = new INDEX_2_HASHTABLE (GetNSeg() + 1); + */ + + surfelementht = new INDEX_3_CLOSED_HASHTABLE (3*GetNSE() + 1); + segmentht = new INDEX_2_CLOSED_HASHTABLE (3*GetNSeg() + 1); + + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + const Element2d & sel = surfelements[sei]; + if (sel.IsDeleted()) continue; + + int si = sel.GetIndex(); + + for (int j = 0; j < sel.GetNP(); j++) + { + PointIndex pi = sel[j]; + bool found = 0; + for (int k = 0; k < surfacesonnode[pi].Size(); k++) + if (surfacesonnode[pi][k] == si) + { + found = 1; + break; + } + + if (!found) + surfacesonnode.Add (pi, si); + } + } + /* + for (sei = 0; sei < GetNSE(); sei++) + { + const Element2d & sel = surfelements[sei]; + if (sel.IsDeleted()) continue; + + INDEX_3 i3; + i3.I1() = sel.PNum(1); + i3.I2() = sel.PNum(2); + i3.I3() = sel.PNum(3); + i3.Sort(); + surfelementht -> PrepareSet (i3); + } + + surfelementht -> AllocateElements(); + */ + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + const Element2d & sel = surfelements[sei]; + if (sel.IsDeleted()) continue; + + INDEX_3 i3; + i3.I1() = sel.PNum(1); + i3.I2() = sel.PNum(2); + i3.I3() = sel.PNum(3); + i3.Sort(); + surfelementht -> Set (i3, sei); // war das wichtig ??? sel.GetIndex()); + } + + int np = GetNP(); + + if (dimension == 3) + { + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + points[pi].SetType (INNERPOINT); + + if (GetNFD() == 0) + { + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + const Element2d & sel = surfelements[sei]; + if (sel.IsDeleted()) continue; + for (int j = 0; j < sel.GetNP(); j++) + { + PointIndex pi = SurfaceElement(sei)[j]; + points[pi].SetType(FIXEDPOINT); + } + } + } + else + { + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + const Element2d & sel = surfelements[sei]; + if (sel.IsDeleted()) continue; + for (int j = 0; j < sel.GetNP(); j++) + { + PointIndex pi = sel[j]; + int ns = surfacesonnode[pi].Size(); + if (ns == 1) + points[pi].SetType(SURFACEPOINT); + if (ns == 2) + points[pi].SetType(EDGEPOINT); + if (ns >= 3) + points[pi].SetType(FIXEDPOINT); + } + } + } + } + + for (int i = 0; i < segments.Size(); i++) + { + const Segment & seg = segments[i]; + for (int j = 1; j <= 2; j++) + { + PointIndex hi = (j == 1) ? seg[0] : seg[1]; + if (points[hi].Type() == INNERPOINT || + points[hi].Type() == SURFACEPOINT) + points[hi].SetType(EDGEPOINT); + } + } + + for (int i = 0; i < lockedpoints.Size(); i++) + points[lockedpoints[i]].SetType(FIXEDPOINT); + + + /* + for (i = 0; i < openelements.Size(); i++) + { + const Element2d & sel = openelements[i]; + for (j = 0; j < sel.GetNP(); j++) + { + INDEX_2 i2; + i2.I1() = sel.PNumMod(j+1); + i2.I2() = sel.PNumMod(j+2); + i2.Sort(); + boundaryedges->Set (i2, 1); + + points[sel[j]].SetType(FIXEDPOINT); + } + } + */ + + // eltyps.SetSize (GetNE()); + // eltyps = FREEELEMENT; + + for (int i = 0; i < GetNSeg(); i++) + { + const Segment & seg = segments[i]; + INDEX_2 i2(seg[0], seg[1]); + i2.Sort(); + + //boundaryedges -> Set (i2, 2); + segmentht -> Set (i2, i); + } + } + + + void Mesh :: FixPoints (const BitArray & fixpoints) + { + if (fixpoints.Size() != GetNP()) + { + cerr << "Mesh::FixPoints: sizes don't fit" << endl; + return; + } + int np = GetNP(); + for (int i = 1; i <= np; i++) + if (fixpoints.Test(i)) + { + points.Elem(i).SetType (FIXEDPOINT); + } + } + + + void Mesh :: FindOpenElements (int dom) + { + static int timer = NgProfiler::CreateTimer ("Mesh::FindOpenElements"); + NgProfiler::RegionTimer reg (timer); + + int np = GetNP(); + int ne = GetNE(); + int nse = GetNSE(); + + Array numonpoint(np); + + numonpoint = 0; + + for (ElementIndex ei = 0; ei < ne; ei++) + { + const Element & el = (*this)[ei]; + if (dom == 0 || dom == el.GetIndex()) + { + if (el.GetNP() == 4) + { + INDEX_4 i4(el[0], el[1], el[2], el[3]); + i4.Sort(); + numonpoint[i4.I1()]++; + numonpoint[i4.I2()]++; + } + else + for (int j = 0; j < el.GetNP(); j++) + numonpoint[el[j]]++; + } + } + + TABLE elsonpoint(numonpoint); + for (ElementIndex ei = 0; ei < ne; ei++) + { + const Element & el = (*this)[ei]; + if (dom == 0 || dom == el.GetIndex()) + { + if (el.GetNP() == 4) + { + INDEX_4 i4(el[0], el[1], el[2], el[3]); + i4.Sort(); + elsonpoint.Add (i4.I1(), ei); + elsonpoint.Add (i4.I2(), ei); + } + else + for (int j = 0; j < el.GetNP(); j++) + elsonpoint.Add (el[j], ei); + } + } + + + Array hasface(GetNFD()); + + int i; + for (i = 1; i <= GetNFD(); i++) + { + int domin = GetFaceDescriptor(i).DomainIn(); + int domout = GetFaceDescriptor(i).DomainOut(); + hasface[i] = + ( dom == 0 && (domin != 0 || domout != 0) ) || + ( dom != 0 && (domin == dom || domout == dom) ); + } + + numonpoint = 0; + for (SurfaceElementIndex sii = 0; sii < nse; sii++) + { + int ind = surfelements[sii].GetIndex(); + /* + if ( + GetFaceDescriptor(ind).DomainIn() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) + || + GetFaceDescriptor(ind).DomainOut() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) + ) + */ + if (hasface[ind]) + { + /* + Element2d hel = surfelements[i]; + hel.NormalizeNumbering(); + numonpoint[hel[0]]++; + */ + const Element2d & hel = surfelements[sii]; + int mini = 0; + for (int j = 1; j < hel.GetNP(); j++) + if (hel[j] < hel[mini]) + mini = j; + numonpoint[hel[mini]]++; + } + } + + TABLE selsonpoint(numonpoint); + for (SurfaceElementIndex sii = 0; sii < nse; sii++) + { + int ind = surfelements[sii].GetIndex(); + + /* + if ( + GetFaceDescriptor(ind).DomainIn() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) + || + GetFaceDescriptor(ind).DomainOut() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) + ) + */ + if (hasface[ind]) + { + /* + Element2d hel = surfelements[i]; + hel.NormalizeNumbering(); + selsonpoint.Add (hel[0], i); + */ + const Element2d & hel = surfelements[sii]; + int mini = 0; + for (int j = 1; j < hel.GetNP(); j++) + if (hel[j] < hel[mini]) + mini = j; + selsonpoint.Add (hel[mini], sii); + } + } + + + int ii; + PointIndex pi; + SurfaceElementIndex sei; + Element2d hel; + + + INDEX_3_CLOSED_HASHTABLE faceht(100); + openelements.SetSize(0); + + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + if (selsonpoint[pi].Size()+elsonpoint[pi].Size()) + { + faceht.SetSize (2 * selsonpoint[pi].Size() + 4 * elsonpoint[pi].Size()); + + FlatArray row = selsonpoint[pi]; + for (ii = 0; ii < row.Size(); ii++) + { + hel = SurfaceElement(row[ii]); + int ind = hel.GetIndex(); + + if (GetFaceDescriptor(ind).DomainIn() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainIn()) ) + { + hel.NormalizeNumbering(); + if (hel.PNum(1) == pi) + { + INDEX_3 i3(hel[0], hel[1], hel[2]); + INDEX_2 i2 (GetFaceDescriptor(ind).DomainIn(), + (hel.GetNP() == 3) + ? PointIndex (PointIndex::BASE-1) + : hel.PNum(4)); + faceht.Set (i3, i2); + } + } + if (GetFaceDescriptor(ind).DomainOut() && + (dom == 0 || dom == GetFaceDescriptor(ind).DomainOut()) ) + { + hel.Invert(); + hel.NormalizeNumbering(); + if (hel.PNum(1) == pi) + { + INDEX_3 i3(hel[0], hel[1], hel[2]); + INDEX_2 i2 (GetFaceDescriptor(ind).DomainOut(), + (hel.GetNP() == 3) + ? PointIndex (PointIndex::BASE-1) + : hel.PNum(4)); + faceht.Set (i3, i2); + } + } + } + + + FlatArray rowel = elsonpoint[pi]; + for (ii = 0; ii < rowel.Size(); ii++) + { + const Element & el = VolumeElement(rowel[ii]); + + if (dom == 0 || el.GetIndex() == dom) + { + for (int j = 1; j <= el.GetNFaces(); j++) + { + el.GetFace (j, hel); + hel.Invert(); + hel.NormalizeNumbering(); + + if (hel[0] == pi) + { + INDEX_3 i3(hel[0], hel[1], hel[2]); + + if (faceht.Used (i3)) + { + INDEX_2 i2 = faceht.Get(i3); + if (i2.I1() == el.GetIndex()) + { + i2.I1() = PointIndex::BASE-1; + faceht.Set (i3, i2); + } + else + { + if (i2.I1() == 0) + { + PrintSysError ("more elements on face"); + (*testout) << "more elements on face!!!" << endl; + (*testout) << "el = " << el << endl; + (*testout) << "hel = " << hel << endl; + (*testout) << "face = " << i3 << endl; + (*testout) << "points = " << endl; + for (int jj = 1; jj <= 3; jj++) + (*testout) << "p = " << Point(i3.I(jj)) << endl; + } + } + } + else + { + hel.Invert(); + hel.NormalizeNumbering(); + INDEX_3 i3(hel[0], hel[1], hel[2]); + INDEX_2 i2(el.GetIndex(), + (hel.GetNP() == 3) + ? PointIndex (PointIndex::BASE-1) + : hel[3]); + faceht.Set (i3, i2); + } + } + } + } + } + for (int i = 0; i < faceht.Size(); i++) + if (faceht.UsedPos (i)) + { + INDEX_3 i3; + INDEX_2 i2; + faceht.GetData (i, i3, i2); + if (i2.I1() != PointIndex::BASE-1) + { + Element2d tri; + tri.SetType ( (i2.I2() == PointIndex::BASE-1) ? TRIG : QUAD); + for (int l = 0; l < 3; l++) + tri[l] = i3.I(l+1); + tri.PNum(4) = i2.I2(); + tri.SetIndex (i2.I1()); + + // tri.Invert(); + + openelements.Append (tri); + } + } + } + + int cnt3 = 0; + for (i = 0; i < openelements.Size(); i++) + if (openelements[i].GetNP() == 3) + cnt3++; + + int cnt4 = openelements.Size() - cnt3; + + + MyStr treequad; + if (cnt4) + treequad = MyStr(" (") + MyStr(cnt3) + MyStr (" + ") + + MyStr(cnt4) + MyStr(")"); + + PrintMessage (5, openelements.Size(), treequad, " open elements"); + + BuildBoundaryEdges(); + + + for (int i = 1; i <= openelements.Size(); i++) + { + const Element2d & sel = openelements.Get(i); + + if (boundaryedges) + for (int j = 1; j <= sel.GetNP(); j++) + { + INDEX_2 i2; + i2.I1() = sel.PNumMod(j); + i2.I2() = sel.PNumMod(j+1); + i2.Sort(); + boundaryedges->Set (i2, 1); + } + + for (int j = 1; j <= 3; j++) + { + PointIndex pi = sel.PNum(j); + if (pi < points.End()) + points[pi].SetType (FIXEDPOINT); + } + } + + + + /* + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment(i); + INDEX_2 i2(seg[0], seg[1]); + i2.Sort(); + + if (!boundaryedges->Used (i2)) + cerr << "WARNING: no boundedge, but seg edge: " << i2 << endl; + + boundaryedges -> Set (i2, 2); + segmentht -> Set (i2, i-1); + } + */ + } + + bool Mesh :: HasOpenQuads () const + { + int no = GetNOpenElements(); + for (int i = 0; i < no; i++) + if (openelements[i].GetNP() == 4) + return true; + return false; + } + + + + + + void Mesh :: FindOpenSegments (int surfnr) + { + // int i, j, k; + + // new version, general elements + // hash index: pnum1-2 + // hash data : surfnr, surfel-nr (pos) or segment nr(neg) + INDEX_2_HASHTABLE faceht(4 * GetNSE()+GetNSeg()+1); + + PrintMessage (5, "Test Opensegments"); + for (int i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + + if (surfnr == 0 || seg.si == surfnr) + { + INDEX_2 key(seg[0], seg[1]); + INDEX_2 data(seg.si, -i); + + if (faceht.Used (key)) + { + cerr << "ERROR: Segment " << seg << " already used" << endl; + (*testout) << "ERROR: Segment " << seg << " already used" << endl; + } + + faceht.Set (key, data); + } + } + + + for (int i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + + if (surfnr == 0 || seg.si == surfnr) + { + INDEX_2 key(seg[1], seg[0]); + if (!faceht.Used(key)) + { + cerr << "ERROR: Segment " << seg << " brother not used" << endl; + (*testout) << "ERROR: Segment " << seg << " brother not used" << endl; + } + } + } + + // bool buggy = false; + // ofstream bout("buggy.out"); + + for (int i = 1; i <= GetNSE(); i++) + { + const Element2d & el = SurfaceElement(i); + if (el.IsDeleted()) continue; + + if (surfnr == 0 || el.GetIndex() == surfnr) + { + for (int j = 1; j <= el.GetNP(); j++) + { + INDEX_2 seg (el.PNumMod(j), el.PNumMod(j+1)); + INDEX_2 data; + + if (seg.I1() <= 0 || seg.I2() <= 0) + cerr << "seg = " << seg << endl; + + if (faceht.Used(seg)) + { + data = faceht.Get(seg); + if (data.I1() == el.GetIndex()) + { + data.I1() = 0; + faceht.Set (seg, data); + } + else + { + // buggy = true; + PrintWarning ("hash table si not fitting for segment: ", + seg.I1(), "-", seg.I2(), " other = ", + data.I2()); + // cout << "me: index = " << el.GetIndex() << ", el = " << el << endl; + + /* + bout << "has index = " << seg << endl; + bout << "hash value = " << faceht.HashValue (seg) << endl; + + if (data.I2() > 0) + { + int io = data.I2(); + cout << "other trig: index = " << SurfaceElement(io).GetIndex() + << ", el = " << SurfaceElement(io) << endl; + } + else + { + cout << "other seg " << -data.I2() << ", si = " << data.I1() << endl; + } + + + bout << "me: index = " << el.GetIndex() << ", el = " << el << endl; + if (data.I2() > 0) + { + int io = data.I2(); + bout << "other trig: index = " << SurfaceElement(io).GetIndex() + << ", el = " << SurfaceElement(io) << endl; + } + else + { + bout << "other seg " << -data.I2() << ", si = " << data.I1() << endl; + } + */ + } + } + else + { + Swap (seg.I1(), seg.I2()); + data.I1() = el.GetIndex(); + data.I2() = i; + + faceht.Set (seg, data); + } + } + } + } + + /* + if (buggy) + { + for (int i = 1; i <= GetNSeg(); i++) + bout << "seg" << i << " " << LineSegment(i) << endl; + + for (int i = 1; i <= GetNSE(); i++) + bout << "sel" << i << " " << SurfaceElement(i) << " ind = " + << SurfaceElement(i).GetIndex() << endl; + + bout << "hashtable: " << endl; + for (int j = 1; j <= faceht.GetNBags(); j++) + { + bout << "bag " << j << ":" << endl; + for (int k = 1; k <= faceht.GetBagSize(j); k++) + { + INDEX_2 i2, data; + faceht.GetData (j, k, i2, data); + bout << "key = " << i2 << ", data = " << data << endl; + } + } + exit(1); + } + */ + + (*testout) << "open segments: " << endl; + opensegments.SetSize(0); + for (int i = 1; i <= faceht.GetNBags(); i++) + for (int j = 1; j <= faceht.GetBagSize(i); j++) + { + INDEX_2 i2; + INDEX_2 data; + faceht.GetData (i, j, i2, data); + if (data.I1()) // surfnr + { + Segment seg; + seg[0] = i2.I1(); + seg[1] = i2.I2(); + seg.si = data.I1(); + + // find geomdata: + if (data.I2() > 0) + { + // segment due to triangle + const Element2d & el = SurfaceElement (data.I2()); + for (int k = 1; k <= el.GetNP(); k++) + { + if (seg[0] == el.PNum(k)) + seg.geominfo[0] = el.GeomInfoPi(k); + if (seg[1] == el.PNum(k)) + seg.geominfo[1] = el.GeomInfoPi(k); + } + + (*testout) << "trig seg: "; + } + else + { + // segment due to line + const Segment & lseg = LineSegment (-data.I2()); + seg.geominfo[0] = lseg.geominfo[0]; + seg.geominfo[1] = lseg.geominfo[1]; + + (*testout) << "line seg: "; + } + + (*testout) << seg[0] << " - " << seg[1] + << " len = " << Dist (Point(seg[0]), Point(seg[1])) + << endl; + + opensegments.Append (seg); + if (seg.geominfo[0].trignum <= 0 || seg.geominfo[1].trignum <= 0) + { + (*testout) << "Problem with open segment: " << seg << endl; + } + + } + } + + PrintMessage (3, opensegments.Size(), " open segments found"); + (*testout) << opensegments.Size() << " open segments found" << endl; + + /* + ptyps.SetSize (GetNP()); + for (i = 1; i <= ptyps.Size(); i++) + ptyps.Elem(i) = SURFACEPOINT; + + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + ptyps.Elem(seg[0]) = EDGEPOINT; + ptyps.Elem(seg[1]) = EDGEPOINT; + } + for (i = 1; i <= GetNOpenSegments(); i++) + { + const Segment & seg = GetOpenSegment (i); + ptyps.Elem(seg[0]) = EDGEPOINT; + ptyps.Elem(seg[1]) = EDGEPOINT; + } + */ + for (int i = 1; i <= points.Size(); i++) + points.Elem(i).SetType(SURFACEPOINT); + + for (int i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment (i); + points[seg[0]].SetType(EDGEPOINT); + points[seg[1]].SetType(EDGEPOINT); + } + for (int i = 1; i <= GetNOpenSegments(); i++) + { + const Segment & seg = GetOpenSegment (i); + points[seg[0]].SetType (EDGEPOINT); + points[seg[1]].SetType (EDGEPOINT); + } + + + + /* + + for (i = 1; i <= openelements.Size(); i++) + { + const Element2d & sel = openelements.Get(i); + + if (boundaryedges) + for (j = 1; j <= sel.GetNP(); j++) + { + INDEX_2 i2; + i2.I1() = sel.PNumMod(j); + i2.I2() = sel.PNumMod(j+1); + i2.Sort(); + boundaryedges->Set (i2, 1); + } + + for (j = 1; j <= 3; j++) + { + int pi = sel.PNum(j); + if (pi <= ptyps.Size()) + ptyps.Elem(pi) = FIXEDPOINT; + } + } + */ + } + + + void Mesh :: RemoveOneLayerSurfaceElements () + { + int i, j; + int np = GetNP(); + + FindOpenSegments(); + BitArray frontpoints(np); + + frontpoints.Clear(); + for (i = 1; i <= GetNOpenSegments(); i++) + { + const Segment & seg = GetOpenSegment(i); + frontpoints.Set (seg[0]); + frontpoints.Set (seg[1]); + } + + for (i = 1; i <= GetNSE(); i++) + { + Element2d & sel = surfelements.Elem(i); + int remove = 0; + for (j = 1; j <= sel.GetNP(); j++) + if (frontpoints.Test(sel.PNum(j))) + remove = 1; + if (remove) + sel.PNum(1) = 0; + } + + for (i = surfelements.Size(); i >= 1; i--) + { + if (surfelements.Elem(i).PNum(1) == 0) + { + surfelements.Elem(i) = surfelements.Last(); + surfelements.DeleteLast(); + } + } + + RebuildSurfaceElementLists (); + /* + for (int i = 0; i < facedecoding.Size(); i++) + facedecoding[i].firstelement = -1; + for (int i = surfelements.Size()-1; i >= 0; i--) + { + int ind = surfelements[i].GetIndex(); + surfelements[i].next = facedecoding[ind-1].firstelement; + facedecoding[ind-1].firstelement = i; + } + */ + + timestamp = NextTimeStamp(); + // Compress(); + } + + + + + + void Mesh :: FreeOpenElementsEnvironment (int layers) + { + int i, j, k; + PointIndex pi; + const int large = 9999; + Array dist(GetNP()); + + dist = large; + + for (int i = 1; i <= GetNOpenElements(); i++) + { + const Element2d & face = OpenElement(i); + for (j = 0; j < face.GetNP(); j++) + dist[face[j]] = 1; + } + + for (k = 1; k <= layers; k++) + for (i = 1; i <= GetNE(); i++) + { + const Element & el = VolumeElement(i); + if (el[0] == -1 || el.IsDeleted()) continue; + + int elmin = large; + for (j = 0; j < el.GetNP(); j++) + if (dist[el[j]] < elmin) + elmin = dist[el[j]]; + + if (elmin < large) + { + for (j = 0; j < el.GetNP(); j++) + if (dist[el[j]] > elmin+1) + dist[el[j]] = elmin+1; + } + } + + int cntfree = 0; + for (i = 1; i <= GetNE(); i++) + { + Element & el = VolumeElement(i); + if (el[0] == -1 || el.IsDeleted()) continue; + + int elmin = large; + for (j = 0; j < el.GetNP(); j++) + if (dist[el[j]] < elmin) + elmin = dist[el[j]]; + + el.flags.fixed = elmin > layers; + // eltyps.Elem(i) = (elmin <= layers) ? + // FREEELEMENT : FIXEDELEMENT; + if (elmin <= layers) + cntfree++; + } + + PrintMessage (5, "free: ", cntfree, ", fixed: ", GetNE()-cntfree); + (*testout) << "free: " << cntfree << ", fixed: " << GetNE()-cntfree << endl; + + for (pi = PointIndex::BASE; + pi < GetNP()+PointIndex::BASE; pi++) + { + if (dist[pi] > layers+1) + points[pi].SetType(FIXEDPOINT); + } + } + + + + void Mesh :: SetLocalH (const Point3d & pmin, const Point3d & pmax, double grading) + { + Point3d c = Center (pmin, pmax); + double d = max3 (pmax.X()-pmin.X(), + pmax.Y()-pmin.Y(), + pmax.Z()-pmin.Z()); + d /= 2; + Point3d pmin2 = c - Vec3d (d, d, d); + Point3d pmax2 = c + Vec3d (d, d, d); + + + delete lochfunc; + lochfunc = new LocalH (pmin2, pmax2, grading); + } + + void Mesh :: RestrictLocalH (const Point3d & p, double hloc) + { + if(hloc < hmin) + hloc = hmin; + + //cout << "restrict h in " << p << " to " << hloc << endl; + if (!lochfunc) + { + PrintWarning("RestrictLocalH called, creating mesh-size tree"); + + Point3d boxmin, boxmax; + GetBox (boxmin, boxmax); + SetLocalH (boxmin, boxmax, 0.8); + } + + lochfunc -> SetH (p, hloc); + } + + void Mesh :: RestrictLocalHLine (const Point3d & p1, + const Point3d & p2, + double hloc) + { + if(hloc < hmin) + hloc = hmin; + + // cout << "restrict h along " << p1 << " - " << p2 << " to " << hloc << endl; + int i; + int steps = int (Dist (p1, p2) / hloc) + 2; + Vec3d v(p1, p2); + + for (i = 0; i <= steps; i++) + { + Point3d p = p1 + (double(i)/double(steps) * v); + RestrictLocalH (p, hloc); + } + } + + + void Mesh :: SetMinimalH (double h) + { + hmin = h; + } + + + void Mesh :: SetGlobalH (double h) + { + hglob = h; + } + + double Mesh :: MaxHDomain (int dom) const + { + if (maxhdomain.Size()) + return maxhdomain.Get(dom); + else + return 1e10; + } + + void Mesh :: SetMaxHDomain (const Array & mhd) + { + maxhdomain.SetSize(mhd.Size()); + for (int i = 1; i <= mhd.Size(); i++) + maxhdomain.Elem(i) = mhd.Get(i); + } + + + double Mesh :: GetH (const Point3d & p) const + { + double hmin = hglob; + if (lochfunc) + { + double hl = lochfunc->GetH (p); + if (hl < hglob) + hmin = hl; + } + return hmin; + } + + double Mesh :: GetMinH (const Point3d & pmin, const Point3d & pmax) + { + double hmin = hglob; + if (lochfunc) + { + double hl = lochfunc->GetMinH (pmin, pmax); + if (hl < hmin) + hmin = hl; + } + return hmin; + } + + + + + + double Mesh :: AverageH (int surfnr) const + { + int i, j, n; + double hi, hsum; + double maxh = 0, minh = 1e10; + + hsum = 0; + n = 0; + for (i = 1; i <= GetNSE(); i++) + { + const Element2d & el = SurfaceElement(i); + if (surfnr == 0 || el.GetIndex() == surfnr) + { + for (j = 1; j <= 3; j++) + { + hi = Dist (Point (el.PNumMod(j)), + Point (el.PNumMod(j+1))); + + hsum += hi; + + if (hi > maxh) maxh = hi; + if (hi < minh) minh = hi; + n++; + } + } + } + + PrintMessage (5, "minh = ", minh, " avh = ", (hsum/n), " maxh = ", maxh); + return (hsum / n); + } + + + + void Mesh :: CalcLocalH (double grading) + { + if (!lochfunc) + { + Point3d pmin, pmax; + GetBox (pmin, pmax); + // SetLocalH (pmin, pmax, mparam.grading); + SetLocalH (pmin, pmax, grading); + } + + PrintMessage (3, + "CalcLocalH: ", + GetNP(), " Points ", + GetNE(), " Elements ", + GetNSE(), " Surface Elements"); + + + for (int i = 0; i < GetNSE(); i++) + { + const Element2d & el = surfelements[i]; + int j; + + if (el.GetNP() == 3) + { + double hel = -1; + for (j = 1; j <= 3; j++) + { + const Point3d & p1 = points[el.PNumMod(j)]; + const Point3d & p2 = points[el.PNumMod(j+1)]; + + /* + INDEX_2 i21(el.PNumMod(j), el.PNumMod(j+1)); + INDEX_2 i22(el.PNumMod(j+1), el.PNumMod(j)); + if (! identifiedpoints->Used (i21) && + ! identifiedpoints->Used (i22) ) + */ + if (!ident -> UsedSymmetric (el.PNumMod(j), + el.PNumMod(j+1))) + { + double hedge = Dist (p1, p2); + if (hedge > hel) + hel = hedge; + // lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); + // (*testout) << "trigseth, p1,2 = " << el.PNumMod(j) << ", " << el.PNumMod(j+1) + // << " h = " << (2 * Dist(p1, p2)) << endl; + } + } + + if (hel > 0) + { + const Point3d & p1 = points[el.PNum(1)]; + const Point3d & p2 = points[el.PNum(2)]; + const Point3d & p3 = points[el.PNum(3)]; + lochfunc->SetH (Center (p1, p2, p3), hel); + } + } + else + { + { + const Point3d & p1 = points[el.PNum(1)]; + const Point3d & p2 = points[el.PNum(2)]; + lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); + } + { + const Point3d & p1 = points[el.PNum(3)]; + const Point3d & p2 = points[el.PNum(4)]; + lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); + } + } + } + + for (int i = 0; i < GetNSeg(); i++) + { + const Segment & seg = segments[i]; + const Point3d & p1 = points[seg[0]]; + const Point3d & p2 = points[seg[1]]; + /* + INDEX_2 i21(seg[0], seg[1]); + INDEX_2 i22(seg[1], seg[0]); + if (identifiedpoints) + if (!identifiedpoints->Used (i21) && !identifiedpoints->Used (i22)) + */ + if (!ident -> UsedSymmetric (seg[0], seg[1])) + { + lochfunc->SetH (Center (p1, p2), Dist (p1, p2)); + } + } + /* + cerr << "do vol" << endl; + for (i = 1; i <= GetNE(); i++) + { + const Element & el = VolumeElement(i); + if (el.GetType() == TET) + { + int j, k; + for (j = 2; j <= 4; j++) + for (k = 1; k < j; k++) + { + const Point3d & p1 = Point (el.PNum(j)); + const Point3d & p2 = Point (el.PNum(k)); + lochfunc->SetH (Center (p1, p2), 2 * Dist (p1, p2)); + (*testout) << "set vol h to " << (2 * Dist (p1, p2)) << endl; + + } + } + } + */ + + /* + const char * meshsizefilename = + globflags.GetStringFlag ("meshsize", NULL); + if (meshsizefilename) + { + ifstream msf(meshsizefilename); + if (msf) + { + int nmsp; + msf >> nmsp; + for (i = 1; i <= nmsp; i++) + { + Point3d pi; + double hi; + msf >> pi.X() >> pi.Y() >> pi.Z(); + msf >> hi; + lochfunc->SetH (pi, hi); + } + } + } + */ + // lochfunc -> Convexify(); + // lochfunc -> PrintMemInfo (cout); + } + + + void Mesh :: CalcLocalHFromPointDistances(double grading) + { + PrintMessage (3, "Calculating local h from point distances"); + + if (!lochfunc) + { + Point3d pmin, pmax; + GetBox (pmin, pmax); + + // SetLocalH (pmin, pmax, mparam.grading); + SetLocalH (pmin, pmax, grading); + } + + PointIndex i,j; + double hl; + + + for (i = PointIndex::BASE; + i < GetNP()+PointIndex::BASE; i++) + { + for(j=i+1; j edges(3 * GetNP() + 2); + INDEX_2_HASHTABLE bedges(GetNSeg() + 2); + int i, j; + + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment(i); + INDEX_2 i2(seg[0], seg[1]); + i2.Sort(); + bedges.Set (i2, 1); + } + for (i = 1; i <= GetNSE(); i++) + { + const Element2d & sel = SurfaceElement(i); + if (!sel.PNum(1)) + continue; + for (j = 1; j <= 3; j++) + { + INDEX_2 i2(sel.PNumMod(j), sel.PNumMod(j+1)); + i2.Sort(); + if (bedges.Used(i2)) continue; + + if (edges.Used(i2)) + { + int other = edges.Get(i2); + + const Element2d & elother = SurfaceElement(other); + + int pi3 = 1; + while ( (sel.PNum(pi3) == i2.I1()) || + (sel.PNum(pi3) == i2.I2())) + pi3++; + pi3 = sel.PNum(pi3); + + int pi4 = 1; + while ( (elother.PNum(pi4) == i2.I1()) || + (elother.PNum(pi4) == i2.I2())) + pi4++; + pi4 = elother.PNum(pi4); + + double rad = ComputeCylinderRadius (Point (i2.I1()), + Point (i2.I2()), + Point (pi3), + Point (pi4)); + + RestrictLocalHLine (Point(i2.I1()), Point(i2.I2()), rad/elperr); + + + /* + (*testout) << "pi1,2, 3, 4 = " << i2.I1() << ", " << i2.I2() << ", " << pi3 << ", " << pi4 + << " p1 = " << Point(i2.I1()) + << ", p2 = " << Point(i2.I2()) + // << ", p3 = " << Point(pi3) + // << ", p4 = " << Point(pi4) + << ", rad = " << rad << endl; + */ + } + else + edges.Set (i2, i); + } + } + + + // Restrict h due to line segments + + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment(i); + const Point3d & p1 = Point(seg[0]); + const Point3d & p2 = Point(seg[1]); + RestrictLocalH (Center (p1, p2), Dist (p1, p2)); + } + + + + /* + + + int i, j; + int np = GetNP(); + int nseg = GetNSeg(); + int nse = GetNSE(); + + Array normals(np); + BitArray linepoint(np); + + linepoint.Clear(); + for (i = 1; i <= nseg; i++) + { + linepoint.Set (LineSegment(i)[0]); + linepoint.Set (LineSegment(i)[1]); + } + + for (i = 1; i <= np; i++) + normals.Elem(i) = Vec3d(0,0,0); + + for (i = 1; i <= nse; i++) + { + Element2d & el = SurfaceElement(i); + Vec3d nf = Cross (Vec3d (Point (el.PNum(1)), Point(el.PNum(2))), + Vec3d (Point (el.PNum(1)), Point(el.PNum(3)))); + for (j = 1; j <= 3; j++) + normals.Elem(el.PNum(j)) += nf; + } + + for (i = 1; i <= np; i++) + normals.Elem(i) /= (1e-12 + normals.Elem(i).Length()); + + for (i = 1; i <= nse; i++) + { + Element2d & el = SurfaceElement(i); + Vec3d nf = Cross (Vec3d (Point (el.PNum(1)), Point(el.PNum(2))), + Vec3d (Point (el.PNum(1)), Point(el.PNum(3)))); + nf /= nf.Length(); + Point3d c = Center (Point(el.PNum(1)), + Point(el.PNum(2)), + Point(el.PNum(3))); + + for (j = 1; j <= 3; j++) + { + if (!linepoint.Test (el.PNum(j))) + { + double dist = Dist (c, Point(el.PNum(j))); + double dn = (nf - normals.Get(el.PNum(j))).Length(); + + RestrictLocalH (Point(el.PNum(j)), dist / (dn+1e-12) /elperr); + } + } + } + */ + } + + + void Mesh :: RestrictLocalH (resthtype rht, int nr, double loch) + { + int i; + switch (rht) + { + case RESTRICTH_FACE: + { + for (i = 1; i <= GetNSE(); i++) + { + const Element2d & sel = SurfaceElement(i); + if (sel.GetIndex() == nr) + RestrictLocalH (RESTRICTH_SURFACEELEMENT, i, loch); + } + break; + } + case RESTRICTH_EDGE: + { + for (i = 1; i <= GetNSeg(); i++) + { + const Segment & seg = LineSegment(i); + if (seg.edgenr == nr) + RestrictLocalH (RESTRICTH_SEGMENT, i, loch); + } + break; + } + case RESTRICTH_POINT: + { + RestrictLocalH (Point (nr), loch); + break; + } + + case RESTRICTH_SURFACEELEMENT: + { + const Element2d & sel = SurfaceElement(nr); + Point3d p = Center (Point(sel.PNum(1)), + Point(sel.PNum(2)), + Point(sel.PNum(3))); + RestrictLocalH (p, loch); + break; + } + case RESTRICTH_SEGMENT: + { + const Segment & seg = LineSegment(nr); + RestrictLocalHLine (Point (seg[0]), Point(seg[1]), loch); + break; + } + } + } + + + void Mesh :: LoadLocalMeshSize (const char * meshsizefilename) + { + // Philippose - 10/03/2009 + // Improve error checking when loading and reading + // the local mesh size file + + if (!meshsizefilename) return; + + ifstream msf(meshsizefilename); + + // Philippose - 09/03/2009 + // Adding print message information in case the specified + // does not exist, or does not load successfully due to + // other reasons such as access rights, etc... + if (!msf) + { + PrintMessage(3, "Error loading mesh size file: ", meshsizefilename, "....","Skipping!"); + return; + } + + PrintMessage (3, "Load local mesh-size file: ", meshsizefilename); + + int nmsp = 0; + int nmsl = 0; + + msf >> nmsp; + if(!msf.good()) + throw NgException ("Mesh-size file error: No points found\n"); + + if(nmsp > 0) + PrintMessage (4, "Number of mesh-size restriction points: ", nmsp); + + for (int i = 0; i < nmsp; i++) + { + Point3d pi; + double hi; + msf >> pi.X() >> pi.Y() >> pi.Z(); + msf >> hi; + if (!msf.good()) + throw NgException ("Mesh-size file error: Number of points don't match specified list size\n"); + RestrictLocalH (pi, hi); + } + + msf >> nmsl; + if(!msf.good()) + throw NgException ("Mesh-size file error: No line definitions found\n"); + + if(nmsl > 0) + PrintMessage (4, "Number of mesh-size restriction lines: ", nmsl); + + for (int i = 0; i < nmsl; i++) + { + Point3d p1, p2; + double hi; + msf >> p1.X() >> p1.Y() >> p1.Z(); + msf >> p2.X() >> p2.Y() >> p2.Z(); + msf >> hi; + if (!msf.good()) + throw NgException ("Mesh-size file error: Number of line definitions don't match specified list size\n"); + RestrictLocalHLine (p1, p2, hi); + } + + msf.close(); + } + + + + void Mesh :: GetBox (Point3d & pmin, Point3d & pmax, int dom) const + { + if (points.Size() == 0) + { + pmin = pmax = Point3d(0,0,0); + return; + } + + if (dom <= 0) + { + pmin = Point3d (1e10, 1e10, 1e10); + pmax = Point3d (-1e10, -1e10, -1e10); + + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + { + pmin.SetToMin ( (*this) [pi] ); + pmax.SetToMax ( (*this) [pi] ); + } + } + else + { + int j, nse = GetNSE(); + SurfaceElementIndex sei; + + pmin = Point3d (1e10, 1e10, 1e10); + pmax = Point3d (-1e10, -1e10, -1e10); + for (sei = 0; sei < nse; sei++) + { + const Element2d & el = (*this)[sei]; + if (el.IsDeleted() ) continue; + + if (dom == -1 || el.GetIndex() == dom) + { + for (j = 0; j < 3; j++) + { + pmin.SetToMin ( (*this) [el[j]] ); + pmax.SetToMax ( (*this) [el[j]] ); + } + } + } + } + + if (pmin.X() > 0.5e10) + { + pmin = pmax = Point3d(0,0,0); + } + } + + + + + void Mesh :: GetBox (Point3d & pmin, Point3d & pmax, POINTTYPE ptyp) const + { + if (points.Size() == 0) + { + pmin = pmax = Point3d(0,0,0); + return; + } + + pmin = Point3d (1e10, 1e10, 1e10); + pmax = Point3d (-1e10, -1e10, -1e10); + + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + if (points[pi].Type() <= ptyp) + { + pmin.SetToMin ( (*this) [pi] ); + pmax.SetToMax ( (*this) [pi] ); + } + } + + + + + double Mesh :: ElementError (int eli, const MeshingParameters & mp) const + { + const Element & el = volelements.Get(eli); + return CalcTetBadness (points.Get(el[0]), points.Get(el[1]), + points.Get(el[2]), points.Get(el[3]), -1, mp); + } + + void Mesh :: AddLockedPoint (PointIndex pi) + { + lockedpoints.Append (pi); + } + + void Mesh :: ClearLockedPoints () + { + lockedpoints.SetSize (0); + } + + + + void Mesh :: Compress () + { + Array op2np(GetNP()); + Array hpoints; + BitArrayChar pused(GetNP()); + + /* + (*testout) << "volels: " << endl; + for (i = 1; i <= volelements.Size(); i++) + { + for (j = 1; j <= volelements.Get(i).GetNP(); j++) + (*testout) << volelements.Get(i).PNum(j) << " "; + (*testout) << endl; + } + (*testout) << "np: " << GetNP() << endl; + */ + + for (int i = 0; i < volelements.Size(); i++) + if (volelements[i][0] <= PointIndex::BASE-1 || + volelements[i].IsDeleted()) + { + volelements.Delete(i); + i--; + } + + + for (int i = 0; i < surfelements.Size(); i++) + if (surfelements[i].IsDeleted()) + { + surfelements.Delete(i); + i--; + } + + for (int i = 0; i < segments.Size(); i++) + if (segments[i][0] <= PointIndex::BASE-1) + { + segments.Delete(i); + i--; + } + + pused.Clear(); + for (int i = 0; i < volelements.Size(); i++) + { + const Element & el = volelements[i]; + for (int j = 0; j < el.GetNP(); j++) + pused.Set (el[j]); + } + + for (int i = 0; i < surfelements.Size(); i++) + { + const Element2d & el = surfelements[i]; + for (int j = 0; j < el.GetNP(); j++) + pused.Set (el[j]); + } + + for (int i = 0; i < segments.Size(); i++) + { + const Segment & seg = segments[i]; + pused.Set (seg[0]); + pused.Set (seg[1]); + } + + for (int i = 0; i < openelements.Size(); i++) + { + const Element2d & el = openelements[i]; + for (int j = 0; j < el.GetNP(); j++) + pused.Set(el[j]); + } + + for (int i = 0; i < lockedpoints.Size(); i++) + pused.Set (lockedpoints[i]); + + + /* + // compress points doesnt work for identified points ! + if (identifiedpoints) + { + for (i = 1; i <= identifiedpoints->GetNBags(); i++) + if (identifiedpoints->GetBagSize(i)) + { + pused.Set (); + break; + } + } + */ + // pused.Set(); + + + int npi = PointIndex::BASE-1; + + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + if (pused.Test(pi)) + { + npi++; + op2np[pi] = npi; + hpoints.Append (points[pi]); + } + else + op2np[pi] = -1; + + + + points.SetSize(0); + for (int i = 0; i < hpoints.Size(); i++) + points.Append (hpoints[i]); + + for (int i = 1; i <= volelements.Size(); i++) + { + Element & el = VolumeElement(i); + for (int j = 0; j < el.GetNP(); j++) + el[j] = op2np[el[j]]; + } + + for (int i = 1; i <= surfelements.Size(); i++) + { + Element2d & el = SurfaceElement(i); + for (int j = 0; j < el.GetNP(); j++) + el[j] = op2np[el[j]]; + } + + for (int i = 0; i < segments.Size(); i++) + { + Segment & seg = segments[i]; + seg[0] = op2np[seg[0]]; + seg[1] = op2np[seg[1]]; + } + + for (int i = 1; i <= openelements.Size(); i++) + { + Element2d & el = openelements.Elem(i); + for (int j = 0; j < el.GetNP(); j++) + el[j] = op2np[el[j]]; + } + + + for (int i = 0; i < lockedpoints.Size(); i++) + lockedpoints[i] = op2np[lockedpoints[i]]; + + for (int i = 0; i < facedecoding.Size(); i++) + facedecoding[i].firstelement = -1; + for (int i = surfelements.Size()-1; i >= 0; i--) + { + int ind = surfelements[i].GetIndex(); + surfelements[i].next = facedecoding[ind-1].firstelement; + facedecoding[ind-1].firstelement = i; + } + + CalcSurfacesOfNode(); + + + // FindOpenElements(); + timestamp = NextTimeStamp(); + } + + + int Mesh :: CheckConsistentBoundary () const + { + int nf = GetNOpenElements(); + INDEX_2_HASHTABLE edges(nf+2); + INDEX_2 i2, i2s, edge; + int err = 0; + + for (int i = 1; i <= nf; i++) + { + const Element2d & sel = OpenElement(i); + + for (int j = 1; j <= sel.GetNP(); j++) + { + i2.I1() = sel.PNumMod(j); + i2.I2() = sel.PNumMod(j+1); + + int sign = (i2.I2() > i2.I1()) ? 1 : -1; + i2.Sort(); + if (!edges.Used (i2)) + edges.Set (i2, 0); + edges.Set (i2, edges.Get(i2) + sign); + } + } + + for (int i = 1; i <= edges.GetNBags(); i++) + for (int j = 1; j <= edges.GetBagSize(i); j++) + { + int cnt = 0; + edges.GetData (i, j, i2, cnt); + if (cnt) + { + PrintError ("Edge ", i2.I1() , " - ", i2.I2(), " multiple times in surface mesh"); + + (*testout) << "Edge " << i2 << " multiple times in surface mesh" << endl; + i2s = i2; + i2s.Sort(); + for (int k = 1; k <= nf; k++) + { + const Element2d & sel = OpenElement(k); + for (int l = 1; l <= sel.GetNP(); l++) + { + edge.I1() = sel.PNumMod(l); + edge.I2() = sel.PNumMod(l+1); + edge.Sort(); + + if (edge == i2s) + (*testout) << "edge of element " << sel << endl; + } + } + + + err = 2; + } + } + + return err; + } + + + + int Mesh :: CheckOverlappingBoundary () + { + int i, j, k; + + Point3d pmin, pmax; + GetBox (pmin, pmax); + Box3dTree setree(pmin, pmax); + Array inters; + + bool overlap = 0; + bool incons_layers = 0; + + + for (i = 1; i <= GetNSE(); i++) + SurfaceElement(i).badel = 0; + + + for (i = 1; i <= GetNSE(); i++) + { + const Element2d & tri = SurfaceElement(i); + + Point3d tpmin (Point(tri[0])); + Point3d tpmax (tpmin); + + for (k = 1; k < tri.GetNP(); k++) + { + tpmin.SetToMin (Point (tri[k])); + tpmax.SetToMax (Point (tri[k])); + } + Vec3d diag(tpmin, tpmax); + + tpmax = tpmax + 0.1 * diag; + tpmin = tpmin - 0.1 * diag; + + setree.Insert (tpmin, tpmax, i); + } + + for (i = 1; i <= GetNSE(); i++) + { + const Element2d & tri = SurfaceElement(i); + + Point3d tpmin (Point(tri[0])); + Point3d tpmax (tpmin); + + for (k = 1; k < tri.GetNP(); k++) + { + tpmin.SetToMin (Point (tri[k])); + tpmax.SetToMax (Point (tri[k])); + } + + setree.GetIntersecting (tpmin, tpmax, inters); + + for (j = 1; j <= inters.Size(); j++) + { + const Element2d & tri2 = SurfaceElement(inters.Get(j)); + + if ( (*this)[tri[0]].GetLayer() != (*this)[tri2[0]].GetLayer()) + continue; + + if ( (*this)[tri[0]].GetLayer() != (*this)[tri[1]].GetLayer() || + (*this)[tri[0]].GetLayer() != (*this)[tri[2]].GetLayer()) + { + incons_layers = 1; + cout << "inconsistent layers in triangle" << endl; + } + + + const netgen::Point<3> *trip1[3], *trip2[3]; + for (k = 1; k <= 3; k++) + { + trip1[k-1] = &Point (tri.PNum(k)); + trip2[k-1] = &Point (tri2.PNum(k)); + } + + if (IntersectTriangleTriangle (&trip1[0], &trip2[0])) + { + overlap = 1; + PrintWarning ("Intersecting elements " + ,i, " and ", inters.Get(j)); + + (*testout) << "Intersecting: " << endl; + (*testout) << "openelement " << i << " with open element " << inters.Get(j) << endl; + + cout << "el1 = " << tri << endl; + cout << "el2 = " << tri2 << endl; + cout << "layer1 = " << (*this)[tri[0]].GetLayer() << endl; + cout << "layer2 = " << (*this)[tri2[0]].GetLayer() << endl; + + + for (k = 1; k <= 3; k++) + (*testout) << tri.PNum(k) << " "; + (*testout) << endl; + for (k = 1; k <= 3; k++) + (*testout) << tri2.PNum(k) << " "; + (*testout) << endl; + + for (k = 0; k <= 2; k++) + (*testout) << *trip1[k] << " "; + (*testout) << endl; + for (k = 0; k <= 2; k++) + (*testout) << *trip2[k] << " "; + (*testout) << endl; + + (*testout) << "Face1 = " << GetFaceDescriptor(tri.GetIndex()) << endl; + (*testout) << "Face1 = " << GetFaceDescriptor(tri2.GetIndex()) << endl; + + /* + INDEX_3 i3(tri.PNum(1), tri.PNum(2), tri.PNum(3)); + i3.Sort(); + for (k = 1; k <= GetNSE(); k++) + { + const Element2d & el2 = SurfaceElement(k); + INDEX_3 i3b(el2.PNum(1), el2.PNum(2), el2.PNum(3)); + i3b.Sort(); + if (i3 == i3b) + { + SurfaceElement(k).badel = 1; + } + } + */ + SurfaceElement(i).badel = 1; + SurfaceElement(inters.Get(j)).badel = 1; + } + } + } + + // bug 'fix' + if (incons_layers) overlap = 0; + + return overlap; + } + + + int Mesh :: CheckVolumeMesh () const + { + PrintMessage (3, "Checking volume mesh"); + + int ne = GetNE(); + DenseMatrix dtrans(3,3); + int i, j; + + PrintMessage (5, "elements: ", ne); + for (i = 1; i <= ne; i++) + { + Element & el = (Element&) VolumeElement(i); + el.flags.badel = 0; + int nip = el.GetNIP(); + for (j = 1; j <= nip; j++) + { + el.GetTransformation (j, Points(), dtrans); + double det = dtrans.Det(); + if (det > 0) + { + PrintError ("Element ", i , " has wrong orientation"); + el.flags.badel = 1; + } + } + } + + return 0; + } + + + bool Mesh :: LegalTrig (const Element2d & el) const + { + return 1; + if ( /* hp */ 1) // needed for old, simple hp-refinement + { + // trigs with 2 or more segments are illegal + int i; + int nseg = 0; + + if (!segmentht) + { + cerr << "no segmentht allocated" << endl; + return 0; + } + + // Point3d cp(0.5, 0.5, 0.5); + for (i = 1; i <= 3; i++) + { + INDEX_2 i2(el.PNumMod (i), el.PNumMod (i+1)); + i2.Sort(); + if (segmentht -> Used (i2)) + nseg++; + } + if (nseg >= 2) + return 0; + } + return 1; + } + + + + + /// + bool Mesh :: LegalTet2 (Element & el) const + { + // static int timer1 = NgProfiler::CreateTimer ("Legaltet2"); + + // Test, whether 4 points have a common surface plus + // at least 4 edges at the boundary + + if(!boundaryedges) + const_cast(this)->BuildBoundaryEdges(); + + + // non-tets are always legal + if (el.GetType() != TET) + { + el.SetLegal (1); + return 1; + } + + POINTTYPE pointtype[4]; + for(int i = 0; i < 4; i++) + pointtype[i] = (*this)[el[i]].Type(); + + + + // element has at least 2 inner points ---> legal + int cnti = 0; + for (int j = 0; j < 4; j++) + if ( pointtype[j] == INNERPOINT) + { + cnti++; + if (cnti >= 2) + { + el.SetLegal (1); + return 1; + } + } + + + + // which faces are boundary faces ? + int bface[4]; + for (int i = 0; i < 4; i++) + { + bface[i] = surfelementht->Used (INDEX_3::Sort(el[gftetfacesa[i][0]], + el[gftetfacesa[i][1]], + el[gftetfacesa[i][2]])); + } + + int bedge[4][4]; + int segedge[4][4]; + static const int pi3map[4][4] = { { -1, 2, 1, 1 }, + { 2, -1, 0, 0 }, + { 1, 0, -1, 0 }, + { 1, 0, 0, -1 } }; + + static const int pi4map[4][4] = { { -1, 3, 3, 2 }, + { 3, -1, 3, 2 }, + { 3, 3, -1, 1 }, + { 2, 2, 1, -1 } }; + + + for (int i = 0; i < 4; i++) + for (int j = 0; j < i; j++) + { + bool sege = false, be = false; + + int pos = boundaryedges -> Position(INDEX_2::Sort(el[i], el[j])); + if (pos) + { + be = true; + if (boundaryedges -> GetData(pos) == 2) + sege = true; + } + + segedge[j][i] = segedge[i][j] = sege; + bedge[j][i] = bedge[i][j] = be; + } + + // two boundary faces and no edge is illegal + for (int i = 0; i < 3; i++) + for (int j = i+1; j < 4; j++) + { + if (bface[i] && bface[j]) + if (!segedge[pi3map[i][j]][pi4map[i][j]]) + { + // 2 boundary faces withoud edge in between + el.SetLegal (0); + return 0; + } + } + + // three boundary edges meeting in a Surface point + for (int i = 0; i < 4; i++) + { + if ( pointtype[i] == SURFACEPOINT) + { + bool alledges = 1; + for (int j = 0; j < 4; j++) + if (j != i && !bedge[i][j]) + { + alledges = 0; + break; + } + if (alledges) + { + // cout << "tet illegal due to unmarked node" << endl; + el.SetLegal (0); + return 0; + } + } + } + + + + for (int fnr = 0; fnr < 4; fnr++) + if (!bface[fnr]) + for (int i = 0; i < 4; i++) + if (i != fnr) + { + int pi1 = pi3map[i][fnr]; + int pi2 = pi4map[i][fnr]; + + if ( pointtype[i] == SURFACEPOINT) + { + // two connected edges on surface, but no face + if (bedge[i][pi1] && bedge[i][pi2]) + { + el.SetLegal (0); + return 0; + } + } + + if ( pointtype[i] == EDGEPOINT) + { + // connected surface edge and edge edge, but no face + if ( (bedge[i][pi1] && segedge[i][pi2]) || + (bedge[i][pi2] && segedge[i][pi1]) ) + { + el.SetLegal (0); + return 0; + } + } + + } + + + el.SetLegal (1); + return 1; + + } + + + + int Mesh :: GetNDomains() const + { + int ndom = 0; + + for (int k = 0; k < facedecoding.Size(); k++) + { + if (facedecoding[k].DomainIn() > ndom) + ndom = facedecoding[k].DomainIn(); + if (facedecoding[k].DomainOut() > ndom) + ndom = facedecoding[k].DomainOut(); + } + + return ndom; + } + + + + void Mesh :: SurfaceMeshOrientation () + { + int i, j; + int nse = GetNSE(); + + BitArray used(nse); + used.Clear(); + INDEX_2_HASHTABLE edges(nse+1); + + bool haschanged = 0; + + + const Element2d & tri = SurfaceElement(1); + for (j = 1; j <= 3; j++) + { + INDEX_2 i2(tri.PNumMod(j), tri.PNumMod(j+1)); + edges.Set (i2, 1); + } + used.Set(1); + + bool unused; + do + { + bool changed; + do + { + changed = 0; + for (i = 1; i <= nse; i++) + if (!used.Test(i)) + { + Element2d & el = surfelements.Elem(i); + int found = 0, foundrev = 0; + for (j = 1; j <= 3; j++) + { + INDEX_2 i2(el.PNumMod(j), el.PNumMod(j+1)); + if (edges.Used(i2)) + foundrev = 1; + swap (i2.I1(), i2.I2()); + if (edges.Used(i2)) + found = 1; + } + + if (found || foundrev) + { + if (foundrev) + swap (el.PNum(2), el.PNum(3)); + + changed = 1; + for (j = 1; j <= 3; j++) + { + INDEX_2 i2(el.PNumMod(j), el.PNumMod(j+1)); + edges.Set (i2, 1); + } + used.Set (i); + } + } + if (changed) + haschanged = 1; + } + while (changed); + + + unused = 0; + for (i = 1; i <= nse; i++) + if (!used.Test(i)) + { + unused = 1; + const Element2d & tri = SurfaceElement(i); + for (j = 1; j <= 3; j++) + { + INDEX_2 i2(tri.PNumMod(j), tri.PNumMod(j+1)); + edges.Set (i2, 1); + } + used.Set(i); + break; + } + } + while (unused); + + if (haschanged) + timestamp = NextTimeStamp(); + } + + + void Mesh :: Split2Tets() + { + PrintMessage (1, "Split To Tets"); + bool has_prisms = 0; + + int oldne = GetNE(); + for (int i = 1; i <= oldne; i++) + { + Element el = VolumeElement(i); + + if (el.GetType() == PRISM) + { + // prism, to 3 tets + + // make minimal node to node 1 + int minpi=0; + PointIndex minpnum; + minpnum = GetNP() + 1; + + for (int j = 1; j <= 6; j++) + { + if (el.PNum(j) < minpnum) + { + minpnum = el.PNum(j); + minpi = j; + } + } + + if (minpi >= 4) + { + for (int j = 1; j <= 3; j++) + swap (el.PNum(j), el.PNum(j+3)); + minpi -= 3; + } + + while (minpi > 1) + { + int hi = 0; + for (int j = 0; j <= 3; j+= 3) + { + hi = el.PNum(1+j); + el.PNum(1+j) = el.PNum(2+j); + el.PNum(2+j) = el.PNum(3+j); + el.PNum(3+j) = hi; + } + minpi--; + } + + /* + version 1: edge from pi2 to pi6, + version 2: edge from pi3 to pi5, + */ + + static const int ntets[2][12] = + { { 1, 4, 5, 6, 1, 2, 3, 6, 1, 2, 5, 6 }, + { 1, 4, 5, 6, 1, 2, 3, 5, 3, 1, 5, 6 } }; + + const int * min2pi; + + if (min2 (el.PNum(2), el.PNum(6)) < + min2 (el.PNum(3), el.PNum(5))) + { + min2pi = &ntets[0][0]; + // (*testout) << "version 1 "; + } + else + { + min2pi = &ntets[1][0]; + // (*testout) << "version 2 "; + } + + + int firsttet = 1; + for (int j = 1; j <= 3; j++) + { + Element nel(TET); + for (int k = 1; k <= 4; k++) + nel.PNum(k) = el.PNum(min2pi[4 * j + k - 5]); + nel.SetIndex (el.GetIndex()); + + int legal = 1; + for (int k = 1; k <= 3; k++) + for (int l = k+1; l <= 4; l++) + if (nel.PNum(k) == nel.PNum(l)) + legal = 0; + + // (*testout) << nel << " "; + if (legal) + { + if (firsttet) + { + VolumeElement(i) = nel; + firsttet = 0; + } + else + { + AddVolumeElement(nel); + } + } + } + if (firsttet) cout << "no legal"; + (*testout) << endl; + } + + + + else if (el.GetType() == HEX) + { + // hex to A) 2 prisms or B) to 5 tets + + // make minimal node to node 1 + int minpi=0; + PointIndex minpnum; + minpnum = GetNP() + 1; + + for (int j = 1; j <= 8; j++) + { + if (el.PNum(j) < minpnum) + { + minpnum = el.PNum(j); + minpi = j; + } + } + + if (minpi >= 5) + { + for (int j = 1; j <= 4; j++) + swap (el.PNum(j), el.PNum(j+4)); + minpi -= 4; + } + + while (minpi > 1) + { + int hi = 0; + for (int j = 0; j <= 4; j+= 4) + { + hi = el.PNum(1+j); + el.PNum(1+j) = el.PNum(2+j); + el.PNum(2+j) = el.PNum(3+j); + el.PNum(3+j) = el.PNum(4+j); + el.PNum(4+j) = hi; + } + minpi--; + } + + + + static const int to_prisms[3][12] = + { { 0, 1, 2, 4, 5, 6, 0, 2, 3, 4, 6, 7 }, + { 0, 1, 5, 3, 2, 6, 0, 5, 4, 3, 6, 7 }, + { 0, 7, 4, 1, 6, 5, 0, 3, 7, 1, 2, 6 }, + }; + + const int * min2pi = 0; + if (min2 (el[4], el[6]) < min2 (el[5], el[7])) + min2pi = &to_prisms[0][0]; + else if (min2 (el[3], el[6]) < min2 (el[2], el[7])) + min2pi = &to_prisms[1][0]; + else if (min2 (el[1], el[6]) < min2 (el[2], el[5])) + min2pi = &to_prisms[2][0]; + + if (min2pi) + { + has_prisms = 1; + for (int j = 0; j < 2; j++) + { + Element nel(PRISM); + for (int k = 0; k < 6; k++) + nel[k] = el[min2pi[6*j + k]]; + nel.SetIndex (el.GetIndex()); + + if (j == 0) + VolumeElement(i) = nel; + else + AddVolumeElement(nel); + } + } + else + { + // split to 5 tets + + static const int to_tets[20] = + { + 1, 2, 0, 5, + 3, 0, 2, 7, + 4, 5, 7, 0, + 6, 7, 5, 2, + 0, 2, 7, 5 + }; + + for (int j = 0; j < 5; j++) + { + Element nel(TET); + for (int k = 0; k < 4; k++) + nel[k] = el[to_tets[4*j + k]]; + nel.SetIndex (el.GetIndex()); + + if (j == 0) + VolumeElement(i) = nel; + else + AddVolumeElement(nel); + } + + } + } + + + + + + else if (el.GetType() == PYRAMID) + { + // pyramid, to 2 tets + + // cout << "pyramid: " << el << endl; + + static const int ntets[2][8] = + { { 1, 2, 3, 5, 1, 3, 4, 5 }, + { 1, 2, 4, 5, 4, 2, 3, 5 }}; + + const int * min2pi; + + if (min2 (el[0], el[2]) < min2 (el[1], el[3])) + min2pi = &ntets[0][0]; + else + min2pi = &ntets[1][0]; + + bool firsttet = 1; + for (int j = 0; j < 2; j++) + { + Element nel(TET); + for (int k = 0; k < 4; k++) + nel[k] = el[min2pi[4*j + k]-1]; + nel.SetIndex (el.GetIndex()); + + // cout << "pyramid-tet: " << nel << endl; + + bool legal = 1; + for (int k = 0; k < 3; k++) + for (int l = k+1; l < 4; l++) + if (nel[k] == nel[l]) + legal = 0; + + if (legal) + { + (*testout) << nel << " "; + if (firsttet) + VolumeElement(i) = nel; + else + AddVolumeElement(nel); + + firsttet = 0; + } + } + if (firsttet) cout << "no legal"; + (*testout) << endl; + } + } + + + int oldnse = GetNSE(); + for (int i = 1; i <= oldnse; i++) + { + Element2d el = SurfaceElement(i); + if (el.GetNP() == 4) + { + (*testout) << "split el: " << el << " to "; + + static const int ntris[2][6] = + { { 1, 2, 3, 1, 3, 4 }, + { 1, 2, 4, 4, 2, 3 }}; + + const int * min2pi; + + if (min2 (el.PNum(1), el.PNum(3)) < + min2 (el.PNum(2), el.PNum(4))) + min2pi = &ntris[0][0]; + else + min2pi = &ntris[1][0]; + + for (int j = 0; j <6; j++) + (*testout) << min2pi[j] << " "; + + + int firsttri = 1; + for (int j = 1; j <= 2; j++) + { + Element2d nel(3); + for (int k = 1; k <= 3; k++) + nel.PNum(k) = el.PNum(min2pi[3 * j + k - 4]); + nel.SetIndex (el.GetIndex()); + + int legal = 1; + for (int k = 1; k <= 2; k++) + for (int l = k+1; l <= 3; l++) + if (nel.PNum(k) == nel.PNum(l)) + legal = 0; + + if (legal) + { + (*testout) << nel << " "; + if (firsttri) + { + SurfaceElement(i) = nel; + firsttri = 0; + } + else + { + AddSurfaceElement(nel); + } + } + } + (*testout) << endl; + + } + } + + + if (has_prisms) + + Split2Tets(); + + else + { + for (int i = 1; i <= GetNE(); i++) + { + Element & el = VolumeElement(i); + const Point3d & p1 = Point (el.PNum(1)); + const Point3d & p2 = Point (el.PNum(2)); + const Point3d & p3 = Point (el.PNum(3)); + const Point3d & p4 = Point (el.PNum(4)); + + double vol = (Vec3d (p1, p2) * + Cross (Vec3d (p1, p3), Vec3d(p1, p4))); + if (vol > 0) + swap (el.PNum(3), el.PNum(4)); + } + + + + UpdateTopology(); + timestamp = NextTimeStamp(); + } + } + + void Mesh :: BuildElementSearchTree () + { + if (elementsearchtreets == GetTimeStamp()) return; + +#pragma omp critical (buildsearchtree) + { + if (elementsearchtreets != GetTimeStamp()) + { + NgLock lock(mutex); + lock.Lock(); + + PrintMessage (4, "Rebuild element searchtree"); + + delete elementsearchtree; + elementsearchtree = NULL; + + int ne = (dimension == 2) ? GetNSE() : GetNE(); + + if (ne) + { + if (dimension == 2) + { + Box<3> box (Box<3>::EMPTY_BOX); + for (SurfaceElementIndex sei = 0; sei < ne; sei++) + box.Add (points[surfelements[sei].PNums()]); + + box.Increase (1.01 * box.Diam()); + elementsearchtree = new Box3dTree (box); + + for (SurfaceElementIndex sei = 0; sei < ne; sei++) + { + box.Set (points[surfelements[sei].PNums()]); + elementsearchtree -> Insert (box, sei+1); + } + } + else + { + Box<3> box (Box<3>::EMPTY_BOX); + for (ElementIndex ei = 0; ei < ne; ei++) + box.Add (points[volelements[ei].PNums()]); + + box.Increase (1.01 * box.Diam()); + elementsearchtree = new Box3dTree (box); + + for (ElementIndex ei = 0; ei < ne; ei++) + { + box.Set (points[volelements[ei].PNums()]); + elementsearchtree -> Insert (box, ei+1); + } + } + + elementsearchtreets = GetTimeStamp(); + } + } + } + } + + + + bool Mesh :: PointContainedIn2DElement(const Point3d & p, + double lami[3], + const int element, + bool consider3D) const + { + Vec3d col1, col2, col3; + Vec3d rhs, sol; + const double eps = 1e-6; + + Array loctrigs; + + + //SZ + if(SurfaceElement(element).GetType()==QUAD) + { + const Element2d & el = SurfaceElement(element); + + const Point3d & p1 = Point(el.PNum(1)); + const Point3d & p2 = Point(el.PNum(2)); + const Point3d & p3 = Point(el.PNum(3)); + const Point3d & p4 = Point(el.PNum(4)); + + // Coefficients of Bilinear Mapping from Ref-Elem to global Elem + // X = a + b x + c y + d x y + Vec3d a = p1; + Vec3d b = p2 - a; + Vec3d c = p4 - a; + Vec3d d = p3 - a - b - c; + + double dxb = d.X()*b.Y()-d.Y()*b.X(); + double dxc = d.X()*c.Y()-d.Y()*c.X(); + double dxa = d.X()*a.Y()-d.Y()*a.X(); + double dxp = d.X()*p.Y()-d.Y()*p.X(); + + double c0,c1,c2; // ,rt; + lami[2]=0.; + double eps = 1.E-12; + + if(fabs(d.X()) <= eps && fabs(d.Y())<= eps) + { + //Solve Linear System + lami[0]=(c.Y()*(p.X()-a.X())-c.X()*(p.Y()-a.Y()))/ + (b.X()*c.Y() -b.Y()*c.X()); + lami[1]=(-b.Y()*(p.X()-a.X())+b.X()*(p.Y()-a.Y()))/ + (b.X()*c.Y() -b.Y()*c.X()); + } + else + if(fabs(dxb) <= eps) + { + lami[1] = (dxp-dxa)/dxc; + if(fabs(b.X()-d.X()*lami[1])>=eps) + lami[0] = (p.X()-a.X() - c.X()*lami[1])/(b.X()+d.X()*lami[1]); + else + lami[0] = (p.Y()-a.Y() - c.Y()*lami[1])/(b.Y()+d.Y()*lami[1]); + } + else + if(fabs(dxc) <= eps) + { + lami[0] = (dxp-dxa)/dxb; + if(fabs(c.X()-d.X()*lami[0])>=eps) + lami[1] = (p.X()-a.X() - b.X()*lami[0])/(c.X()+d.X()*lami[0]); + else + lami[1] = (p.Y()-a.Y() - b.Y()*lami[0])/(c.Y()+d.Y()*lami[0]); + } + else //Solve quadratic equation + { + if(fabs(d.X()) >= eps) + { + c2 = d.X()*dxc; + c1 = d.X()*dxc - c.X()*dxb - d.X()*(dxp-dxa); + c0 = -b.X()*(dxp -dxa) - (a.X()-p.X())*dxb; + } + else + { + c2 = d.Y()*dxc; + c1 = d.Y()*dxc - c.Y()*dxb - d.Y()*(dxp-dxa); + c0 = -b.Y()*(dxp -dxa) - (a.Y()-p.Y())*dxb; + } + + double rt = c1*c1 - 4*c2*c0; + if (rt < 0.) return false; + lami[1] = (-c1 + sqrt(rt))/2/c2; + if(lami[1]<=1. && lami[1]>=0.) + { + lami[0] = (dxp - dxa -dxc*lami[1])/dxb; + if(lami[0]<=1. && lami[0]>=0.) + return true; + } + + lami[1] = (-c1 - sqrt(rt))/2/c2; + lami[0] = (dxp - dxa -dxc*lami[1])/dxb; + } + + if( lami[0] <= 1.+eps && lami[0] >= -eps && lami[1]<=1.+eps && lami[1]>=-eps) + { + if(consider3D) + { + Vec3d n = Cross(b,c); + lami[2] = 0; + for(int i=1; i<=3; i++) + lami[2] +=(p.X(i)-a.X(i)-lami[0]*b.X(i)-lami[1]*c.X(i)) * n.X(i); + if(lami[2] >= -eps && lami[2] <= eps) + return true; + } + else + return true; + } + + return false; + + } + else + { + // SurfaceElement(element).GetTets (loctets); + loctrigs.SetSize(1); + loctrigs.Elem(1) = SurfaceElement(element); + + + + for (int j = 1; j <= loctrigs.Size(); j++) + { + const Element2d & el = loctrigs.Get(j); + + + const Point3d & p1 = Point(el.PNum(1)); + const Point3d & p2 = Point(el.PNum(2)); + const Point3d & p3 = Point(el.PNum(3)); + /* + Box3d box; + box.SetPoint (p1); + box.AddPoint (p2); + box.AddPoint (p3); + box.AddPoint (p4); + if (!box.IsIn (p)) + continue; + */ + col1 = p2-p1; + col2 = p3-p1; + col3 = Cross(col1,col2); + //col3 = Vec3d(0, 0, 1); + rhs = p - p1; + + // int retval = + SolveLinearSystem (col1, col2, col3, rhs, sol); + + //(*testout) << "retval " << retval << endl; + + //(*testout) << "col1 " << col1 << " col2 " << col2 << " col3 " << col3 << " rhs " << rhs << endl; + //(*testout) << "sol " << sol << endl; + + if (sol.X() >= -eps && sol.Y() >= -eps && + sol.X() + sol.Y() <= 1+eps) + { + if(!consider3D || (sol.Z() >= -eps && sol.Z() <= eps)) + { + lami[0] = sol.X(); + lami[1] = sol.Y(); + lami[2] = sol.Z(); + + return true; + } + } + } + } + + return false; + + } + + + + + bool Mesh :: PointContainedIn3DElement(const Point3d & p, + double lami[3], + const int element) const + { + //bool oldresult = PointContainedIn3DElementOld(p,lami,element); + //(*testout) << "old result: " << oldresult + // << " lam " << lami[0] << " " << lami[1] << " " << lami[2] << endl; + + //if(!curvedelems->IsElementCurved(element-1)) + // return PointContainedIn3DElementOld(p,lami,element); + + + const double eps = 1.e-4; + const Element & el = VolumeElement(element); + + netgen::Point<3> lam = 0.0; + + if (el.GetType() == TET || el.GetType() == TET10) + { + lam = 0.25; + } + else if (el.GetType() == PRISM) + { + lam(0) = 0.33; lam(1) = 0.33; lam(2) = 0.5; + } + else if (el.GetType() == PYRAMID) + { + lam(0) = 0.4; lam(1) = 0.4; lam(2) = 0.2; + } + else if (el.GetType() == HEX) + { + lam = 0.5; + } + + + Vec<3> deltalam,rhs; + netgen::Point<3> x; + Mat<3,3> Jac,Jact; + + double delta=1; + + bool retval; + + int i = 0; + + const int maxits = 30; + + while(delta > 1e-16 && iCalcElementTransformation(lam,element-1,x,Jac); + + rhs = p-x; + Jac.Solve(rhs,deltalam); + + lam += deltalam; + + delta = deltalam.Length2(); + + i++; + //(*testout) << "pcie i " << i << " delta " << delta << " p " << p << " x " << x << " lam " << lam << endl; + //<< "Jac " << Jac << endl; + } + + if(i==maxits) + return false; + + + for(i=0; i<3; i++) + lami[i] = lam(i); + + + + if (el.GetType() == TET || el.GetType() == TET10) + { + retval = (lam(0) > -eps && + lam(1) > -eps && + lam(2) > -eps && + lam(0) + lam(1) + lam(2) < 1+eps); + } + else if (el.GetType() == PRISM) + { + retval = (lam(0) > -eps && + lam(1) > -eps && + lam(2) > -eps && + lam(2) < 1+eps && + lam(0) + lam(1) < 1+eps); + } + else if (el.GetType() == PYRAMID) + { + retval = (lam(0) > -eps && + lam(1) > -eps && + lam(2) > -eps && + lam(0) + lam(2) < 1+eps && + lam(1) + lam(2) < 1+eps); + } + else if (el.GetType() == HEX) + { + retval = (lam(0) > -eps && lam(0) < 1+eps && + lam(1) > -eps && lam(1) < 1+eps && + lam(2) > -eps && lam(2) < 1+eps); + } + else + throw NgException("Da haun i wos vagessn"); + + return retval; + } + + + + bool Mesh :: PointContainedIn3DElementOld(const Point3d & p, + double lami[3], + const int element) const + { + Vec3d col1, col2, col3; + Vec3d rhs, sol; + const double eps = 1.e-4; + + Array loctets; + + VolumeElement(element).GetTets (loctets); + + for (int j = 1; j <= loctets.Size(); j++) + { + const Element & el = loctets.Get(j); + + const Point3d & p1 = Point(el.PNum(1)); + const Point3d & p2 = Point(el.PNum(2)); + const Point3d & p3 = Point(el.PNum(3)); + const Point3d & p4 = Point(el.PNum(4)); + + Box3d box; + box.SetPoint (p1); + box.AddPoint (p2); + box.AddPoint (p3); + box.AddPoint (p4); + if (!box.IsIn (p)) + continue; + + col1 = p2-p1; + col2 = p3-p1; + col3 = p4-p1; + rhs = p - p1; + + SolveLinearSystem (col1, col2, col3, rhs, sol); + + if (sol.X() >= -eps && sol.Y() >= -eps && sol.Z() >= -eps && + sol.X() + sol.Y() + sol.Z() <= 1+eps) + { + Array loctetsloc; + Array > pointsloc; + + VolumeElement(element).GetTetsLocal (loctetsloc); + VolumeElement(element).GetNodesLocalNew (pointsloc); + + const Element & le = loctetsloc.Get(j); + + + Point3d pp = + pointsloc.Get(le.PNum(1)) + + sol.X() * Vec3d (pointsloc.Get(le.PNum(1)), pointsloc.Get(le.PNum(2))) + + sol.Y() * Vec3d (pointsloc.Get(le.PNum(1)), pointsloc.Get(le.PNum(3))) + + sol.Z() * Vec3d (pointsloc.Get(le.PNum(1)), pointsloc.Get(le.PNum(4))) ; + + lami[0] = pp.X(); + lami[1] = pp.Y(); + lami[2] = pp.Z(); + return true; + } + } + return false; + } + + + int Mesh :: GetElementOfPoint (const netgen::Point<3> & p, + double lami[3], + bool build_searchtree, + const int index, + const bool allowindex) const + { + if(index != -1) + { + Array dummy(1); + dummy[0] = index; + return GetElementOfPoint(p,lami,&dummy,build_searchtree,allowindex); + } + else + return GetElementOfPoint(p,lami,NULL,build_searchtree,allowindex); + } + + + + + int Mesh :: GetElementOfPoint (const netgen::Point<3> & p, + double lami[3], + const Array * const indices, + bool build_searchtree, + const bool allowindex) const + { + if (dimension == 2) + { + int ne; + + + if(ps_startelement != 0 && ps_startelement <= GetNSE() && PointContainedIn2DElement(p,lami,ps_startelement)) + return ps_startelement; + + Array locels; + if (elementsearchtree || build_searchtree) + { + // update if necessary: + const_cast(*this).BuildElementSearchTree (); + elementsearchtree->GetIntersecting (p, p, locels); + ne = locels.Size(); + } + else + ne = GetNSE(); + + for (int i = 1; i <= ne; i++) + { + int ii; + + if (elementsearchtree) + ii = locels.Get(i); + else + ii = i; + + if(ii == ps_startelement) continue; + + if(indices != NULL && indices->Size() > 0) + { + bool contained = indices->Contains(SurfaceElement(ii).GetIndex()); + if((allowindex && !contained) || (!allowindex && contained)) continue; + } + + if(PointContainedIn2DElement(p,lami,ii)) return ii; + + } + return 0; + } + else + + { + // int i, j; + int ne; + + if(ps_startelement != 0 && PointContainedIn3DElement(p,lami,ps_startelement)) + return ps_startelement; + + Array locels; + if (elementsearchtree || build_searchtree) + { + // update if necessary: + const_cast(*this).BuildElementSearchTree (); + elementsearchtree->GetIntersecting (p, p, locels); + ne = locels.Size(); + } + else + ne = GetNE(); + + for (int i = 1; i <= ne; i++) + { + int ii; + + if (elementsearchtree) + ii = locels.Get(i); + else + ii = i; + + if(ii == ps_startelement) continue; + + if(indices != NULL && indices->Size() > 0) + { + bool contained = indices->Contains(VolumeElement(ii).GetIndex()); + if((allowindex && !contained) || (!allowindex && contained)) continue; + } + + if(PointContainedIn3DElement(p,lami,ii)) + { + ps_startelement = ii; + return ii; + } + } + + // Not found, try uncurved variant: + for (int i = 1; i <= ne; i++) + { + int ii; + + if (elementsearchtree) + ii = locels.Get(i); + else + ii = i; + + if(indices != NULL && indices->Size() > 0) + { + bool contained = indices->Contains(VolumeElement(ii).GetIndex()); + if((allowindex && !contained) || (!allowindex && contained)) continue; + } + + + if(PointContainedIn3DElementOld(p,lami,ii)) + { + ps_startelement = ii; + (*testout) << "WARNING: found element of point " << p <<" only for uncurved mesh" << endl; + return ii; + } + } + + + return 0; + } + } + + + + int Mesh :: GetSurfaceElementOfPoint (const netgen::Point<3> & p, + double lami[3], + bool build_searchtree, + const int index, + const bool allowindex) const + { + if(index != -1) + { + Array dummy(1); + dummy[0] = index; + return GetSurfaceElementOfPoint(p,lami,&dummy,build_searchtree,allowindex); + } + else + return GetSurfaceElementOfPoint(p,lami,NULL,build_searchtree,allowindex); + } + + + + + int Mesh :: GetSurfaceElementOfPoint (const netgen::Point<3> & p, + double lami[3], + const Array * const indices, + bool build_searchtree, + const bool allowindex) const + { + if (dimension == 2) + { + throw NgException("GetSurfaceElementOfPoint not yet implemented for 2D meshes"); + } + else + { + double vlam[3]; + int velement = GetElementOfPoint(p,vlam,NULL,build_searchtree,allowindex); + + //(*testout) << "p " << p << endl; + //(*testout) << "velement " << velement << endl; + + Array faces; + topology->GetElementFaces(velement,faces); + + //(*testout) << "faces " << faces << endl; + + for(int i=0; iGetFace2SurfaceElement(faces[i]); + + //(*testout) << "surfel " << faces << endl; + + for(int i=0; iSize() != 0) + { + if(indices->Contains(SurfaceElement(faces[i]).GetIndex()) && + PointContainedIn2DElement(p,lami,faces[i],true)) + return faces[i]; + } + else + { + if(PointContainedIn2DElement(p,lami,faces[i],true)) + { + //(*testout) << "found point " << p << " in sel " << faces[i] + // << ", lam " << lami[0] << ", " << lami[1] << ", " << lami[2] << endl; + return faces[i]; + } + } + } + + } + + return 0; + } + + + void Mesh::GetIntersectingVolEls(const Point3d& p1, const Point3d& p2, + Array & locels) const + { + elementsearchtree->GetIntersecting (p1, p2, locels); + } + + void Mesh :: SplitIntoParts() + { + int i, j, dom; + int ne = GetNE(); + int np = GetNP(); + int nse = GetNSE(); + + BitArray surfused(nse); + BitArray pused (np); + + surfused.Clear(); + + dom = 0; + + while (1) + { + int cntd = 1; + + dom++; + + pused.Clear(); + + int found = 0; + for (i = 1; i <= nse; i++) + if (!surfused.Test(i)) + { + SurfaceElement(i).SetIndex (dom); + for (j = 1; j <= 3; j++) + pused.Set (SurfaceElement(i).PNum(j)); + found = 1; + cntd = 1; + surfused.Set(i); + break; + } + + if (!found) + break; + + int change; + do + { + change = 0; + for (i = 1; i <= nse; i++) + { + int is = 0, isnot = 0; + for (j = 1; j <= 3; j++) + if (pused.Test(SurfaceElement(i).PNum(j))) + is = 1; + else + isnot = 1; + + if (is && isnot) + { + change = 1; + for (j = 1; j <= 3; j++) + pused.Set (SurfaceElement(i).PNum(j)); + } + + if (is) + { + if (!surfused.Test(i)) + { + surfused.Set(i); + SurfaceElement(i).SetIndex (dom); + cntd++; + } + } + } + + + for (i = 1; i <= ne; i++) + { + int is = 0, isnot = 0; + for (j = 1; j <= 4; j++) + if (pused.Test(VolumeElement(i).PNum(j))) + is = 1; + else + isnot = 1; + + if (is && isnot) + { + change = 1; + for (j = 1; j <= 4; j++) + pused.Set (VolumeElement(i).PNum(j)); + } + + if (is) + { + VolumeElement(i).SetIndex (dom); + } + } + } + while (change); + + PrintMessage (3, "domain ", dom, " has ", cntd, " surfaceelements"); + } + + /* + facedecoding.SetSize (dom); + for (i = 1; i <= dom; i++) + { + facedecoding.Elem(i).surfnr = 0; + facedecoding.Elem(i).domin = i; + facedecoding.Elem(i).domout = 0; + } + */ + ClearFaceDescriptors(); + for (i = 1; i <= dom; i++) + AddFaceDescriptor (FaceDescriptor (0, i, 0, 0)); + CalcSurfacesOfNode(); + timestamp = NextTimeStamp(); + } + + void Mesh :: SplitSeparatedFaces () + { + PrintMessage (3, "SplitSeparateFaces"); + int fdi; + int np = GetNP(); + + BitArray usedp(np); + Array els_of_face; + + fdi = 1; + while (fdi <= GetNFD()) + { + GetSurfaceElementsOfFace (fdi, els_of_face); + + if (els_of_face.Size() == 0) continue; + + SurfaceElementIndex firstel = els_of_face[0]; + + usedp.Clear(); + for (int j = 1; j <= SurfaceElement(firstel).GetNP(); j++) + usedp.Set (SurfaceElement(firstel).PNum(j)); + + bool changed; + do + { + changed = false; + + for (int i = 0; i < els_of_face.Size(); i++) + { + const Element2d & el = SurfaceElement(els_of_face[i]); + + bool has = 0; + bool hasno = 0; + for (int j = 0; j < el.GetNP(); j++) + { + if (usedp.Test(el[j])) + has = true; + else + hasno = true; + } + + if (has && hasno) + changed = true; + + if (has) + for (int j = 0; j < el.GetNP(); j++) + usedp.Set (el[j]); + } + } + while (changed); + + int nface = 0; + for (int i = 0; i < els_of_face.Size(); i++) + { + Element2d & el = SurfaceElement(els_of_face[i]); + + int hasno = 0; + for (int j = 1; j <= el.GetNP(); j++) + if (!usedp.Test(el.PNum(j))) + hasno = 1; + + if (hasno) + { + if (!nface) + { + FaceDescriptor nfd = GetFaceDescriptor(fdi); + nface = AddFaceDescriptor (nfd); + } + + el.SetIndex (nface); + } + } + + // reconnect list + if (nface) + { + facedecoding[nface-1].firstelement = -1; + facedecoding[fdi-1].firstelement = -1; + + for (int i = 0; i < els_of_face.Size(); i++) + { + int ind = SurfaceElement(els_of_face[i]).GetIndex(); + SurfaceElement(els_of_face[i]).next = facedecoding[ind-1].firstelement; + facedecoding[ind-1].firstelement = els_of_face[i]; + } + } + + fdi++; + } + + + /* + fdi = 1; + while (fdi <= GetNFD()) + { + int firstel = 0; + for (int i = 1; i <= GetNSE(); i++) + if (SurfaceElement(i).GetIndex() == fdi) + { + firstel = i; + break; + } + if (!firstel) continue; + + usedp.Clear(); + for (int j = 1; j <= SurfaceElement(firstel).GetNP(); j++) + usedp.Set (SurfaceElement(firstel).PNum(j)); + + int changed; + do + { + changed = 0; + for (int i = 1; i <= GetNSE(); i++) + { + const Element2d & el = SurfaceElement(i); + if (el.GetIndex() != fdi) + continue; + + int has = 0; + int hasno = 0; + for (int j = 1; j <= el.GetNP(); j++) + { + if (usedp.Test(el.PNum(j))) + has = 1; + else + hasno = 1; + } + if (has && hasno) + changed = 1; + + if (has) + for (int j = 1; j <= el.GetNP(); j++) + usedp.Set (el.PNum(j)); + } + } + while (changed); + + int nface = 0; + for (int i = 1; i <= GetNSE(); i++) + { + Element2d & el = SurfaceElement(i); + if (el.GetIndex() != fdi) + continue; + + int hasno = 0; + for (int j = 1; j <= el.GetNP(); j++) + { + if (!usedp.Test(el.PNum(j))) + hasno = 1; + } + + if (hasno) + { + if (!nface) + { + FaceDescriptor nfd = GetFaceDescriptor(fdi); + nface = AddFaceDescriptor (nfd); + } + + el.SetIndex (nface); + } + } + fdi++; + } + */ + } + + + + void Mesh :: RebuildSurfaceElementLists () + { + for (int i = 0; i < facedecoding.Size(); i++) + facedecoding[i].firstelement = -1; + for (int i = surfelements.Size()-1; i >= 0; i--) + { + int ind = surfelements[i].GetIndex(); + surfelements[i].next = facedecoding[ind-1].firstelement; + facedecoding[ind-1].firstelement = i; + } + } + + void Mesh :: GetSurfaceElementsOfFace (int facenr, Array & sei) const + { + static int timer = NgProfiler::CreateTimer ("GetSurfaceElementsOfFace"); + NgProfiler::RegionTimer reg (timer); + + + /* + sei.SetSize (0); + for (SurfaceElementIndex i = 0; i < GetNSE(); i++) + { + if ( (*this)[i].GetIndex () == facenr && (*this)[i][0] >= PointIndex::BASE && + !(*this)[i].IsDeleted() ) + { + sei.Append (i); + } + } + */ + + /* Philippose - 01/10/2009 + Commented out the following lines, and activated the originally + commented out lines above because of a bug which causes corruption + of the variable "facedecoding" when a mesh is converted to second order + */ + + // int size1 = sei.Size(); + sei.SetSize(0); + + SurfaceElementIndex si = facedecoding[facenr-1].firstelement; + while (si != -1) + { + if ( (*this)[si].GetIndex () == facenr && (*this)[si][0] >= PointIndex::BASE && + !(*this)[si].IsDeleted() ) + { + sei.Append (si); + } + + si = (*this)[si].next; + } + + /* + // *testout << "with list = " << endl << sei << endl; + + if (size1 != sei.Size()) + { + cout << "size mismatch" << endl; + exit(1); + } + */ + } + + + + + void Mesh :: CalcMinMaxAngle (double badellimit, double * retvalues) + { + int i, j; + int lpi1, lpi2, lpi3, lpi4; + double phimax = 0, phimin = 10; + double facephimax = 0, facephimin = 10; + int illegaltets = 0, negativetets = 0, badtets = 0; + + for (i = 1; i <= GetNE(); i++) + { + int badel = 0; + + Element & el = VolumeElement(i); + + if (el.GetType() != TET) + { + VolumeElement(i).flags.badel = 0; + continue; + } + + if (el.Volume(Points()) < 0) + { + badel = 1; + negativetets++; + } + + + if (!LegalTet (el)) + { + badel = 1; + illegaltets++; + (*testout) << "illegal tet: " << i << " "; + for (j = 1; j <= el.GetNP(); j++) + (*testout) << el.PNum(j) << " "; + (*testout) << endl; + } + + + // angles between faces + for (lpi1 = 1; lpi1 <= 3; lpi1++) + for (lpi2 = lpi1+1; lpi2 <= 4; lpi2++) + { + lpi3 = 1; + while (lpi3 == lpi1 || lpi3 == lpi2) + lpi3++; + lpi4 = 10 - lpi1 - lpi2 - lpi3; + + const Point3d & p1 = Point (el.PNum(lpi1)); + const Point3d & p2 = Point (el.PNum(lpi2)); + const Point3d & p3 = Point (el.PNum(lpi3)); + const Point3d & p4 = Point (el.PNum(lpi4)); + + Vec3d n(p1, p2); + n /= n.Length(); + Vec3d v1(p1, p3); + Vec3d v2(p1, p4); + + v1 -= (n * v1) * n; + v2 -= (n * v2) * n; + + double cosphi = (v1 * v2) / (v1.Length() * v2.Length()); + double phi = acos (cosphi); + if (phi > phimax) phimax = phi; + if (phi < phimin) phimin = phi; + + if ((180/M_PI) * phi > badellimit) + badel = 1; + } + + + // angles in faces + for (j = 1; j <= 4; j++) + { + Element2d face; + el.GetFace (j, face); + for (lpi1 = 1; lpi1 <= 3; lpi1++) + { + lpi2 = lpi1 % 3 + 1; + lpi3 = lpi2 % 3 + 1; + + const Point3d & p1 = Point (el.PNum(lpi1)); + const Point3d & p2 = Point (el.PNum(lpi2)); + const Point3d & p3 = Point (el.PNum(lpi3)); + + Vec3d v1(p1, p2); + Vec3d v2(p1, p3); + double cosphi = (v1 * v2) / (v1.Length() * v2.Length()); + double phi = acos (cosphi); + if (phi > facephimax) facephimax = phi; + if (phi < facephimin) facephimin = phi; + + if ((180/M_PI) * phi > badellimit) + badel = 1; + + } + } + + + VolumeElement(i).flags.badel = badel; + if (badel) badtets++; + } + + if (!GetNE()) + { + phimin = phimax = facephimin = facephimax = 0; + } + + if (!retvalues) + { + PrintMessage (1, ""); + PrintMessage (1, "between planes: phimin = ", (180/M_PI) * phimin, + " phimax = ", (180/M_PI) *phimax); + PrintMessage (1, "inside planes: phimin = ", (180/M_PI) * facephimin, + " phimax = ", (180/M_PI) * facephimax); + PrintMessage (1, ""); + } + else + { + retvalues[0] = (180/M_PI) * facephimin; + retvalues[1] = (180/M_PI) * facephimax; + retvalues[2] = (180/M_PI) * phimin; + retvalues[3] = (180/M_PI) * phimax; + } + PrintMessage (3, "negative tets: ", negativetets); + PrintMessage (3, "illegal tets: ", illegaltets); + PrintMessage (3, "bad tets: ", badtets); + } + + + int Mesh :: MarkIllegalElements () + { + int cnt = 0; + int i; + + for (i = 1; i <= GetNE(); i++) + { + LegalTet (VolumeElement(i)); + + /* + Element & el = VolumeElement(i); + int leg1 = LegalTet (el); + el.flags.illegal_valid = 0; + int leg2 = LegalTet (el); + + if (leg1 != leg2) + { + cerr << "legal differs!!" << endl; + (*testout) << "legal differs" << endl; + (*testout) << "elnr = " << i << ", el = " << el + << " leg1 = " << leg1 << ", leg2 = " << leg2 << endl; + } + + // el.flags.illegal = !LegalTet (el); + */ + cnt += VolumeElement(i).Illegal(); + } + return cnt; + } + + // #ifdef NONE + // void Mesh :: AddIdentification (int pi1, int pi2, int identnr) + // { + // INDEX_2 pair(pi1, pi2); + // // pair.Sort(); + // identifiedpoints->Set (pair, identnr); + // if (identnr > maxidentnr) + // maxidentnr = identnr; + // timestamp = NextTimeStamp(); + // } + + // int Mesh :: GetIdentification (int pi1, int pi2) const + // { + // INDEX_2 pair(pi1, pi2); + // if (identifiedpoints->Used (pair)) + // return identifiedpoints->Get(pair); + // else + // return 0; + // } + + // int Mesh :: GetIdentificationSym (int pi1, int pi2) const + // { + // INDEX_2 pair(pi1, pi2); + // if (identifiedpoints->Used (pair)) + // return identifiedpoints->Get(pair); + + // pair = INDEX_2 (pi2, pi1); + // if (identifiedpoints->Used (pair)) + // return identifiedpoints->Get(pair); + + // return 0; + // } + + + // void Mesh :: GetIdentificationMap (int identnr, Array & identmap) const + // { + // int i, j; + + // identmap.SetSize (GetNP()); + // for (i = 1; i <= identmap.Size(); i++) + // identmap.Elem(i) = 0; + + // for (i = 1; i <= identifiedpoints->GetNBags(); i++) + // for (j = 1; j <= identifiedpoints->GetBagSize(i); j++) + // { + // INDEX_2 i2; + // int nr; + // identifiedpoints->GetData (i, j, i2, nr); + + // if (nr == identnr) + // { + // identmap.Elem(i2.I1()) = i2.I2(); + // } + // } + // } + + + // void Mesh :: GetIdentificationPairs (int identnr, Array & identpairs) const + // { + // int i, j; + + // identpairs.SetSize(0); + + // for (i = 1; i <= identifiedpoints->GetNBags(); i++) + // for (j = 1; j <= identifiedpoints->GetBagSize(i); j++) + // { + // INDEX_2 i2; + // int nr; + // identifiedpoints->GetData (i, j, i2, nr); + + // if (identnr == 0 || nr == identnr) + // identpairs.Append (i2); + // } + // } + // #endif + + + + void Mesh :: InitPointCurve(double red, double green, double blue) const + { + pointcurves_startpoint.Append(pointcurves.Size()); + pointcurves_red.Append(red); + pointcurves_green.Append(green); + pointcurves_blue.Append(blue); + } + void Mesh :: AddPointCurvePoint(const Point3d & pt) const + { + pointcurves.Append(pt); + } + int Mesh :: GetNumPointCurves(void) const + { + return pointcurves_startpoint.Size(); + } + int Mesh :: GetNumPointsOfPointCurve(int curve) const + { + if(curve == pointcurves_startpoint.Size()-1) + return (pointcurves.Size() - pointcurves_startpoint.Last()); + else + return (pointcurves_startpoint[curve+1]-pointcurves_startpoint[curve]); + } + + Point3d & Mesh :: GetPointCurvePoint(int curve, int n) const + { + return pointcurves[pointcurves_startpoint[curve]+n]; + } + + void Mesh :: GetPointCurveColor(int curve, double & red, double & green, double & blue) const + { + red = pointcurves_red[curve]; + green = pointcurves_green[curve]; + blue = pointcurves_blue[curve]; + } + + + void Mesh :: ComputeNVertices () + { + int i, j, nv; + int ne = GetNE(); + int nse = GetNSE(); + + numvertices = 0; + for (i = 1; i <= ne; i++) + { + const Element & el = VolumeElement(i); + nv = el.GetNV(); + for (j = 0; j < nv; j++) + if (el[j] > numvertices) + numvertices = el[j]; + } + for (i = 1; i <= nse; i++) + { + const Element2d & el = SurfaceElement(i); + nv = el.GetNV(); + for (j = 1; j <= nv; j++) + if (el.PNum(j) > numvertices) + numvertices = el.PNum(j); + } + + numvertices += 1- PointIndex::BASE; + } + + int Mesh :: GetNV () const + { + if (numvertices < 0) + return GetNP(); + else + return numvertices; + } + + void Mesh :: SetNP (int np) + { + points.SetSize(np); + // ptyps.SetSize(np); + + int mlold = mlbetweennodes.Size(); + mlbetweennodes.SetSize(np); + if (np > mlold) + for (int i = mlold+PointIndex::BASE; + i < np+PointIndex::BASE; i++) + { + mlbetweennodes[i].I1() = PointIndex::BASE-1; + mlbetweennodes[i].I2() = PointIndex::BASE-1; + } + + GetIdentifications().SetMaxPointNr (np + PointIndex::BASE-1); + } + + + /* + void Mesh :: BuildConnectedNodes () + { + if (PureTetMesh()) + { + connectedtonode.SetSize(0); + return; + } + + + int i, j, k; + int np = GetNP(); + int ne = GetNE(); + TABLE conto(np); + for (i = 1; i <= ne; i++) + { + const Element & el = VolumeElement(i); + + if (el.GetType() == PRISM) + { + for (j = 1; j <= 6; j++) + { + int n1 = el.PNum (j); + int n2 = el.PNum ((j+2)%6+1); + // if (n1 != n2) + { + int found = 0; + for (k = 1; k <= conto.EntrySize(n1); k++) + if (conto.Get(n1, k) == n2) + { + found = 1; + break; + } + if (!found) + conto.Add (n1, n2); + } + } + } + else if (el.GetType() == PYRAMID) + { + for (j = 1; j <= 4; j++) + { + int n1, n2; + switch (j) + { + case 1: n1 = 1; n2 = 4; break; + case 2: n1 = 4; n2 = 1; break; + case 3: n1 = 2; n2 = 3; break; + case 4: n1 = 3; n2 = 2; break; + } + + int found = 0; + for (k = 1; k <= conto.EntrySize(n1); k++) + if (conto.Get(n1, k) == n2) + { + found = 1; + break; + } + if (!found) + conto.Add (n1, n2); + } + } + } + + connectedtonode.SetSize(np); + for (i = 1; i <= np; i++) + connectedtonode.Elem(i) = 0; + + for (i = 1; i <= np; i++) + if (connectedtonode.Elem(i) == 0) + { + connectedtonode.Elem(i) = i; + ConnectToNodeRec (i, i, conto); + } + + + + } + + void Mesh :: ConnectToNodeRec (int node, int tonode, + const TABLE & conto) + { + int i, n2; + // (*testout) << "connect " << node << " to " << tonode << endl; + for (i = 1; i <= conto.EntrySize(node); i++) + { + n2 = conto.Get(node, i); + if (!connectedtonode.Get(n2)) + { + connectedtonode.Elem(n2) = tonode; + ConnectToNodeRec (n2, tonode, conto); + } + } + } + */ + + + bool Mesh :: PureTrigMesh (int faceindex) const + { + // if (!faceindex) return !mparam.quad; + + if (!faceindex) + { + for (int i = 1; i <= GetNSE(); i++) + if (SurfaceElement(i).GetNP() != 3) + return false; + return true; + } + + for (int i = 1; i <= GetNSE(); i++) + if (SurfaceElement(i).GetIndex() == faceindex && + SurfaceElement(i).GetNP() != 3) + return false; + return true; + } + + bool Mesh :: PureTetMesh () const + { + for (ElementIndex ei = 0; ei < GetNE(); ei++) + if (VolumeElement(ei).GetNP() != 4) + return 0; + return 1; + } + + void Mesh :: UpdateTopology() + { + topology->Update(); + clusters->Update(); + } + + + void Mesh :: SetMaterial (int domnr, const char * mat) + { + if (domnr > materials.Size()) + { + int olds = materials.Size(); + materials.SetSize (domnr); + for (int i = olds; i < domnr; i++) + materials[i] = 0; + } + materials.Elem(domnr) = new char[strlen(mat)+1]; + strcpy (materials.Elem(domnr), mat); + } + + const char * Mesh :: GetMaterial (int domnr) const + { + if (domnr <= materials.Size()) + return materials.Get(domnr); + return 0; + } + + void Mesh ::SetNBCNames ( int nbcn ) + { + if ( bcnames.Size() ) + for ( int i = 0; i < bcnames.Size(); i++) + if ( bcnames[i] ) delete bcnames[i]; + bcnames.SetSize(nbcn); + bcnames = 0; + } + + void Mesh ::SetBCName ( int bcnr, const string & abcname ) + { + if ( bcnames[bcnr] ) delete bcnames[bcnr]; + if ( abcname != "default" ) + bcnames[bcnr] = new string ( abcname ); + else + bcnames[bcnr] = 0; + } + + const string & Mesh ::GetBCName ( int bcnr ) const + { + static string defaultstring = "default"; + + if ( !bcnames.Size() ) + return defaultstring; + if ( bcnames[bcnr] ) + return *bcnames[bcnr]; + else + return defaultstring; + } + + void Mesh :: SetUserData(const char * id, Array & data) + { + if(userdata_int.Used(id)) + delete userdata_int.Get(id); + + Array * newdata = new Array(data); + + userdata_int.Set(id,newdata); + } + bool Mesh :: GetUserData(const char * id, Array & data, int shift) const + { + if(userdata_int.Used(id)) + { + if(data.Size() < (*userdata_int.Get(id)).Size()+shift) + data.SetSize((*userdata_int.Get(id)).Size()+shift); + for(int i=0; i<(*userdata_int.Get(id)).Size(); i++) + data[i+shift] = (*userdata_int.Get(id))[i]; + return true; + } + else + { + data.SetSize(0); + return false; + } + } + void Mesh :: SetUserData(const char * id, Array & data) + { + if(userdata_double.Used(id)) + delete userdata_double.Get(id); + + Array * newdata = new Array(data); + + userdata_double.Set(id,newdata); + } + bool Mesh :: GetUserData(const char * id, Array & data, int shift) const + { + if(userdata_double.Used(id)) + { + if(data.Size() < (*userdata_double.Get(id)).Size()+shift) + data.SetSize((*userdata_double.Get(id)).Size()+shift); + for(int i=0; i<(*userdata_double.Get(id)).Size(); i++) + data[i+shift] = (*userdata_double.Get(id))[i]; + return true; + } + else + { + data.SetSize(0); + return false; + } + } + + + + void Mesh :: PrintMemInfo (ostream & ost) const + { + ost << "Mesh Mem:" << endl; + + ost << GetNP() << " Points, of size " + << sizeof (Point3d) << " + " << sizeof(POINTTYPE) << " = " + << GetNP() * (sizeof (Point3d) + sizeof(POINTTYPE)) << endl; + + ost << GetNSE() << " Surface elements, of size " + << sizeof (Element2d) << " = " + << GetNSE() * sizeof(Element2d) << endl; + + ost << GetNE() << " Volume elements, of size " + << sizeof (Element) << " = " + << GetNE() * sizeof(Element) << endl; + + ost << "surfs on node:"; + surfacesonnode.PrintMemInfo (cout); + + ost << "boundaryedges: "; + if (boundaryedges) + boundaryedges->PrintMemInfo (cout); + + ost << "surfelementht: "; + if (surfelementht) + surfelementht->PrintMemInfo (cout); + } +} diff --git a/libsrc/meshing/meshclass.hpp b/libsrc/meshing/meshclass.hpp new file mode 100644 index 00000000..d4bb0287 --- /dev/null +++ b/libsrc/meshing/meshclass.hpp @@ -0,0 +1,793 @@ +#ifndef MESHCLASS +#define MESHCLASS + +/**************************************************************************/ +/* File: meshclass.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 20. Nov. 99 */ +/**************************************************************************/ + +/* + The mesh class +*/ + +namespace netgen +{ + enum resthtype { RESTRICTH_FACE, RESTRICTH_EDGE, + RESTRICTH_SURFACEELEMENT, RESTRICTH_POINT, RESTRICTH_SEGMENT }; + + class HPRefElement; + + + /// 2d/3d mesh + class Mesh + { + public: + typedef ::netgen::T_POINTS T_POINTS; + typedef Array T_VOLELEMENTS; + typedef Array T_SURFELEMENTS; + + private: + /// point coordinates + T_POINTS points; + + /// line-segments at edges + Array segments; + /// surface elements, 2d-inner elements + T_SURFELEMENTS surfelements; + /// volume elements + T_VOLELEMENTS volelements; + /// points will be fixed forever + Array lockedpoints; + + + /// surface indices at boundary nodes + TABLE surfacesonnode; + /// boundary edges (1..normal bedge, 2..segment) + INDEX_2_CLOSED_HASHTABLE * boundaryedges; + /// + INDEX_2_CLOSED_HASHTABLE * segmentht; + /// + INDEX_3_CLOSED_HASHTABLE * surfelementht; + + /// faces of rest-solid + Array openelements; + /// open segmenets for surface meshing + Array opensegments; + + + + /** + Representation of local mesh-size h + */ + LocalH * lochfunc; + /// + double hglob; + /// + double hmin; + /// + Array maxhdomain; + + /** + the face-index of the surface element maps into + this table. + */ + Array facedecoding; + + + /** + the edge-index of the line element maps into + this table. + */ + Array edgedecoding; + + /// sub-domain materials + Array materials; + + /// labels for boundary conditions + Array bcnames; + + /// Periodic surface, close surface, etc. identifications + Identifications * ident; + + + /// number of vertices (if < 0, use np) + int numvertices; + + /// geometric search tree for interval intersection search + Box3dTree * elementsearchtree; + /// time stamp for tree + mutable int elementsearchtreets; + + /// element -> face, element -> edge etc ... + class MeshTopology * topology; + /// methods for high order elements + class CurvedElements * curvedelems; + + /// nodes identified by close points + class AnisotropicClusters * clusters; + + /// space dimension (2 or 3) + int dimension; + + /// changed by every minor modification (addpoint, ...) + int timestamp; + /// changed after finishing global algorithm (improve, ...) + int majortimestamp; + + /// mesh access semaphors. + NgMutex mutex; + /// mesh access semaphors. + NgMutex majormutex; + + SYMBOLTABLE< Array* > userdata_int; + SYMBOLTABLE< Array* > userdata_double; + + + mutable Array< Point3d > pointcurves; + mutable Array pointcurves_startpoint; + mutable Array pointcurves_red,pointcurves_green,pointcurves_blue; + + + /// start element for point search (GetElementOfPoint) + mutable int ps_startelement; + + +#ifdef PARALLEL + /// connection to parallel meshes + class ParallelMeshTopology * paralleltop; + +#endif + + + private: + void BuildBoundaryEdges(void); + + public: + bool PointContainedIn2DElement(const Point3d & p, + double lami[3], + const int element, + bool consider3D = false) const; + bool PointContainedIn3DElement(const Point3d & p, + double lami[3], + const int element) const; + bool PointContainedIn3DElementOld(const Point3d & p, + double lami[3], + const int element) const; + + public: + + // store coarse mesh before hp-refinement + Array * hpelements; + Mesh * coarsemesh; + + + /// number of refinement levels + int mglevels; + /// refinement hierarchy + Array mlbetweennodes; + /// parent element of volume element + Array mlparentelement; + /// parent element of surface element + Array mlparentsurfaceelement; + + + + /// + DLL_HEADER Mesh(); + /// + DLL_HEADER ~Mesh(); + + Mesh & operator= (const Mesh & mesh2); + + /// + DLL_HEADER void DeleteMesh(); + + /// + void ClearSurfaceElements(); + + /// + void ClearVolumeElements() + { + volelements.SetSize(0); + timestamp = NextTimeStamp(); + } + + /// + void ClearSegments() + { + segments.SetSize(0); + timestamp = NextTimeStamp(); + } + + /// + bool TestOk () const; + + void SetAllocSize(int nnodes, int nsegs, int nsel, int nel); + + + DLL_HEADER PointIndex AddPoint (const Point3d & p, int layer = 1); + DLL_HEADER PointIndex AddPoint (const Point3d & p, int layer, POINTTYPE type); + + int GetNP () const { return points.Size(); } + + MeshPoint & Point(int i) { return points.Elem(i); } + MeshPoint & Point(PointIndex pi) { return points[pi]; } + const MeshPoint & Point(int i) const { return points.Get(i); } + const MeshPoint & Point(PointIndex pi) const { return points[pi]; } + + const MeshPoint & operator[] (PointIndex pi) const { return points[pi]; } + MeshPoint & operator[] (PointIndex pi) { return points[pi]; } + + const T_POINTS & Points() const { return points; } + T_POINTS & Points() { return points; } + + + DLL_HEADER SegmentIndex AddSegment (const Segment & s); + void DeleteSegment (int segnr) + { + segments.Elem(segnr)[0] = PointIndex::BASE-1; + segments.Elem(segnr)[1] = PointIndex::BASE-1; + } + void FullDeleteSegment (int segnr) // von wem ist das ??? + { + segments.Delete(segnr-PointIndex::BASE); + } + + int GetNSeg () const { return segments.Size(); } + Segment & LineSegment(int i) { return segments.Elem(i); } + const Segment & LineSegment(int i) const { return segments.Get(i); } + + Segment & LineSegment(SegmentIndex si) { return segments[si]; } + const Segment & LineSegment(SegmentIndex si) const { return segments[si]; } + const Segment & operator[] (SegmentIndex si) const { return segments[si]; } + Segment & operator[] (SegmentIndex si) { return segments[si]; } + + + + + DLL_HEADER SurfaceElementIndex AddSurfaceElement (const Element2d & el); + void DeleteSurfaceElement (int eli) + { + surfelements.Elem(eli).Delete(); + surfelements.Elem(eli).PNum(1) = -1; + surfelements.Elem(eli).PNum(2) = -1; + surfelements.Elem(eli).PNum(3) = -1; + timestamp = NextTimeStamp(); + } + + void DeleteSurfaceElement (SurfaceElementIndex eli) + { + DeleteSurfaceElement (int(eli)+1); + } + + int GetNSE () const { return surfelements.Size(); } + Element2d & SurfaceElement(int i) { return surfelements.Elem(i); } + const Element2d & SurfaceElement(int i) const { return surfelements.Get(i); } + Element2d & SurfaceElement(SurfaceElementIndex i) { return surfelements[i]; } + const Element2d & SurfaceElement(SurfaceElementIndex i) const { return surfelements[i]; } + + const Element2d & operator[] (SurfaceElementIndex ei) const + { return surfelements[ei]; } + Element2d & operator[] (SurfaceElementIndex ei) + { return surfelements[ei]; } + + + DLL_HEADER void RebuildSurfaceElementLists (); + DLL_HEADER void GetSurfaceElementsOfFace (int facenr, Array & sei) const; + + DLL_HEADER ElementIndex AddVolumeElement (const Element & el); + + int GetNE () const { return volelements.Size(); } + + Element & VolumeElement(int i) { return volelements.Elem(i); } + const Element & VolumeElement(int i) const { return volelements.Get(i); } + Element & VolumeElement(ElementIndex i) { return volelements[i]; } + const Element & VolumeElement(ElementIndex i) const { return volelements[i]; } + + const Element & operator[] (ElementIndex ei) const + { return volelements[ei]; } + Element & operator[] (ElementIndex ei) + { return volelements[ei]; } + + + + ELEMENTTYPE ElementType (ElementIndex i) const + { return (volelements[i].flags.fixed) ? FIXEDELEMENT : FREEELEMENT; } + + const T_VOLELEMENTS & VolumeElements() const { return volelements; } + T_VOLELEMENTS & VolumeElements() { return volelements; } + + + /// + DLL_HEADER double ElementError (int eli, const MeshingParameters & mp) const; + + /// + DLL_HEADER void AddLockedPoint (PointIndex pi); + /// + void ClearLockedPoints (); + + const Array & LockedPoints() const + { return lockedpoints; } + + /// Returns number of domains + int GetNDomains() const; + + /// + int GetDimension() const + { return dimension; } + void SetDimension(int dim) + { dimension = dim; } + + /// sets internal tables + void CalcSurfacesOfNode (); + + /// additional (temporarily) fix points + void FixPoints (const BitArray & fixpoints); + + /** + finds elements without neighbour and + boundary elements without inner element. + Results are stored in openelements. + if dom == 0, all sub-domains, else subdomain dom */ + DLL_HEADER void FindOpenElements (int dom = 0); + + + /** + finds segments without surface element, + and surface elements without neighbours. + store in opensegmentsy + */ + DLL_HEADER void FindOpenSegments (int surfnr = 0); + /** + remove one layer of surface elements + */ + DLL_HEADER void RemoveOneLayerSurfaceElements (); + + + int GetNOpenSegments () { return opensegments.Size(); } + const Segment & GetOpenSegment (int nr) { return opensegments.Get(nr); } + + /** + Checks overlap of boundary + return == 1, iff overlap + */ + DLL_HEADER int CheckOverlappingBoundary (); + /** + Checks consistent boundary + return == 0, everything ok + */ + DLL_HEADER int CheckConsistentBoundary () const; + + /* + checks element orientation + */ + DLL_HEADER int CheckVolumeMesh () const; + + + /** + finds average h of surface surfnr if surfnr > 0, + else of all surfaces. + */ + DLL_HEADER double AverageH (int surfnr = 0) const; + /// Calculates localh + DLL_HEADER void CalcLocalH (double grading); + /// + DLL_HEADER void SetLocalH (const Point3d & pmin, const Point3d & pmax, double grading); + /// + DLL_HEADER void RestrictLocalH (const Point3d & p, double hloc); + /// + DLL_HEADER void RestrictLocalHLine (const Point3d & p1, const Point3d & p2, + double hloc); + /// number of elements per radius + DLL_HEADER void CalcLocalHFromSurfaceCurvature(double grading, double elperr); + /// + DLL_HEADER void CalcLocalHFromPointDistances(double grading); + /// + DLL_HEADER void RestrictLocalH (resthtype rht, int nr, double loch); + /// + DLL_HEADER void LoadLocalMeshSize (const char * meshsizefilename); + /// + DLL_HEADER void SetGlobalH (double h); + /// + void SetMinimalH (double h); + /// + double MaxHDomain (int dom) const; + /// + void SetMaxHDomain (const Array & mhd); + /// + double GetH (const Point3d & p) const; + /// + double GetMinH (const Point3d & pmin, const Point3d & pmax); + /// + LocalH & LocalHFunction () { return * lochfunc; } + /// + bool LocalHFunctionGenerated(void) const { return (lochfunc != NULL); } + + /// Find bounding box + DLL_HEADER void GetBox (Point3d & pmin, Point3d & pmax, int dom = -1) const; + + /// Find bounding box of points of typ ptyp or less + DLL_HEADER void GetBox (Point3d & pmin, Point3d & pmax, POINTTYPE ptyp ) const; + + /// + int GetNOpenElements() const + { return openelements.Size(); } + /// + const Element2d & OpenElement(int i) const + { return openelements.Get(i); } + + + /// are also quads open elements + bool HasOpenQuads () const; + + /// split into connected pieces + void SplitIntoParts (); + + /// + void SplitSeparatedFaces (); + + /// Refines mesh and projects points to true surface + // void Refine (int levels, const CSGeometry * geom); + + + bool BoundaryEdge (PointIndex pi1, PointIndex pi2) const + { + if(!boundaryedges) + const_cast(this)->BuildBoundaryEdges(); + + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + return boundaryedges->Used (i2); + } + + bool IsSegment (PointIndex pi1, PointIndex pi2) const + { + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + return segmentht->Used (i2); + } + + SegmentIndex SegmentNr (PointIndex pi1, PointIndex pi2) const + { + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + return segmentht->Get (i2); + } + + + /** + Remove unused points. etc. + */ + DLL_HEADER void Compress (); + + /// + void Save (ostream & outfile) const; + /// + void Load (istream & infile); + /// + void Merge (istream & infile, const int surfindex_offset = 0); + /// + void Save (const string & filename) const; + /// + void Load (const string & filename); + /// + void Merge (const string & filename, const int surfindex_offset = 0); + + + /// + void ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal = OPT_QUALITY); + + /// + void ImproveMeshJacobian (const MeshingParameters & mp, OPTIMIZEGOAL goal = OPT_QUALITY, const BitArray * usepoint = NULL); + /// + void ImproveMeshJacobianOnSurface (const MeshingParameters & mp, + const BitArray & usepoint, + const Array< Vec<3>* > & nv, + OPTIMIZEGOAL goal = OPT_QUALITY, + const Array< Array* > * idmaps = NULL); + /** + free nodes in environment of openelements + for optimiztion + */ + void FreeOpenElementsEnvironment (int layers); + + /// + bool LegalTet (Element & el) const + { + if (el.IllegalValid()) + return !el.Illegal(); + return LegalTet2 (el); + } + /// + bool LegalTet2 (Element & el) const; + + + /// + bool LegalTrig (const Element2d & el) const; + /** + if values non-null, return values in 4-double array: + triangle angles min/max, tetangles min/max + if null, output results on cout + */ + void CalcMinMaxAngle (double badellimit, double * retvalues = NULL); + + /* + Marks elements which are dangerous to refine + return: number of illegal elements + */ + int MarkIllegalElements (); + + /// orient surface mesh, for one sub-domain only + void SurfaceMeshOrientation (); + + /// convert mixed element mesh to tet-mesh + void Split2Tets(); + + + /// build box-search tree + DLL_HEADER void BuildElementSearchTree (); + + void SetPointSearchStartElement(const int el) const {ps_startelement = el;} + + /// gives element of point, barycentric coordinates + int GetElementOfPoint (const netgen::Point<3> & p, + double * lami, + bool build_searchtree = 0, + const int index = -1, + const bool allowindex = true) const; + int GetElementOfPoint (const netgen::Point<3> & p, + double * lami, + const Array * const indices, + bool build_searchtree = 0, + const bool allowindex = true) const; + int GetSurfaceElementOfPoint (const netgen::Point<3> & p, + double * lami, + bool build_searchtree = 0, + const int index = -1, + const bool allowindex = true) const; + int GetSurfaceElementOfPoint (const netgen::Point<3> & p, + double * lami, + const Array * const indices, + bool build_searchtree = 0, + const bool allowindex = true) const; + + /// give list of vol elements which are int the box(p1,p2) + void GetIntersectingVolEls(const Point3d& p1, const Point3d& p2, + Array & locels) const; + + /// + int AddFaceDescriptor(const FaceDescriptor& fd) + { return facedecoding.Append(fd); } + + int AddEdgeDescriptor(const EdgeDescriptor & fd) + { return edgedecoding.Append(fd) - 1; } + + /// + DLL_HEADER void SetMaterial (int domnr, const char * mat); + /// + const char * GetMaterial (int domnr) const; + + DLL_HEADER void SetNBCNames ( int nbcn ); + + DLL_HEADER void SetBCName ( int bcnr, const string & abcname ); + + const string & GetBCName ( int bcnr ) const; + + string * GetBCNamePtr ( int bcnr ) + { return bcnames[bcnr]; } + + /// + void ClearFaceDescriptors() + { facedecoding.SetSize(0); } + + /// + int GetNFD () const + { return facedecoding.Size(); } + + const FaceDescriptor & GetFaceDescriptor (int i) const + { return facedecoding.Get(i); } + + const EdgeDescriptor & GetEdgeDescriptor (int i) const + { return edgedecoding[i]; } + + + /// + FaceDescriptor & GetFaceDescriptor (int i) + { return facedecoding.Elem(i); } + + // #ifdef NONE + // /* + // Identify points pi1 and pi2, due to + // identification nr identnr + // */ + // void AddIdentification (int pi1, int pi2, int identnr); + + // int GetIdentification (int pi1, int pi2) const; + // int GetIdentificationSym (int pi1, int pi2) const; + // /// + // INDEX_2_HASHTABLE & GetIdentifiedPoints () + // { + // return *identifiedpoints; + // } + + // /// + // void GetIdentificationMap (int identnr, Array & identmap) const; + // /// + // void GetIdentificationPairs (int identnr, Array & identpairs) const; + // /// + // int GetMaxIdentificationNr () const + // { + // return maxidentnr; + // } + // #endif + + /// return periodic, close surface etc. identifications + Identifications & GetIdentifications () { return *ident; } + /// return periodic, close surface etc. identifications + const Identifications & GetIdentifications () const { return *ident; } + + + void InitPointCurve(double red = 1, double green = 0, double blue = 0) const; + void AddPointCurvePoint(const Point3d & pt) const; + int GetNumPointCurves(void) const; + int GetNumPointsOfPointCurve(int curve) const; + Point3d & GetPointCurvePoint(int curve, int n) const; + void GetPointCurveColor(int curve, double & red, double & green, double & blue) const; + + + + + /// find number of vertices + void ComputeNVertices (); + /// number of vertices (no edge-midpoints) + int GetNV () const; + /// remove edge points + void SetNP (int np); + + + + + bool PureTrigMesh (int faceindex = 0) const; + bool PureTetMesh () const; + + + const class MeshTopology & GetTopology () const + { return *topology; } + + void UpdateTopology(); + + class CurvedElements & GetCurvedElements () const + { return *curvedelems; } + + const class AnisotropicClusters & GetClusters () const + { return *clusters; } + + + class CSurfaceArea + { + const Mesh & mesh; + bool valid; + double area; + public: + CSurfaceArea (const Mesh & amesh) + : mesh(amesh), valid(false) { ; } + + void Add (const Element2d & sel) + { + if (sel.GetNP() == 3) + area += Cross ( mesh[sel[1]]-mesh[sel[0]], + mesh[sel[2]]-mesh[sel[0]] ).Length() / 2; + else + area += Cross (Vec3d (mesh.Point (sel.PNum(1)), + mesh.Point (sel.PNum(3))), + Vec3d (mesh.Point (sel.PNum(1)), + mesh.Point (sel.PNum(4)))).Length() / 2;; + } + void ReCalc () + { + area = 0; + for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + Add (mesh[sei]); + valid = true; + } + + operator double () const { return area; } + bool Valid() const { return valid; } + }; + + CSurfaceArea surfarea; + CSurfaceArea & SurfaceArea() { return surfarea; } + const CSurfaceArea & SurfaceArea() const { return surfarea; } + + + + int GetTimeStamp() const { return timestamp; } + void SetNextTimeStamp() + { timestamp = NextTimeStamp(); } + + int GetMajorTimeStamp() const { return majortimestamp; } + void SetNextMajorTimeStamp() + { majortimestamp = timestamp = NextTimeStamp(); } + + + /// return mutex + NgMutex & Mutex () { return mutex; } + NgMutex & MajorMutex () { return majormutex; } + + + /// + void SetUserData(const char * id, Array & data); + /// + bool GetUserData(const char * id, Array & data, int shift = 0) const; + /// + void SetUserData(const char * id, Array & data); + /// + bool GetUserData(const char * id, Array & data, int shift = 0) const; + + /// + friend void OptimizeRestart (Mesh & mesh3d); + /// + void PrintMemInfo (ostream & ost) const; + /// + friend class Meshing3; + + + enum GEOM_TYPE { NO_GEOM = 0, GEOM_2D = 1, GEOM_CSG = 10, GEOM_STL = 11, GEOM_OCC = 12, GEOM_ACIS = 13 }; + GEOM_TYPE geomtype; + + + +#ifdef PARALLEL + /// returns parallel topology + class ParallelMeshTopology & GetParallelTopology () const + { return *paralleltop; } + + + /// distributes the master-mesh to local meshes + void Distribute (); + void Distribute (Array & volume_weights, Array & surface_weights, + Array & segment_weights); + + + /// find connection to parallel meshes + // void FindExchangePoints () ; + + // void FindExchangeEdges (); + // void FindExchangeFaces (); + + /// use metis to decompose master mesh + void ParallelMetis (); // Array & neloc ); + void ParallelMetis (Array & volume_weights, Array & surface_weights, + Array & segment_weights); + + void PartHybridMesh (); // Array & neloc ); + void PartDualHybridMesh (); // Array & neloc ); + void PartDualHybridMesh2D (); // ( Array & neloc ); + + + /// send mesh from master to local procs + void SendRecvMesh (); + + /// send mesh to parallel machine, keep global mesh at master + void SendMesh ( ) const; // Mesh * mastermesh, Array & neloc) const; + /// loads a mesh sent from master processor + void ReceiveParallelMesh (); + +#endif + + + }; + + inline ostream& operator<<(ostream& ost, const Mesh& mesh) + { + ost << "mesh: " << endl; + mesh.Save(ost); + return ost; + } + +} + +#endif + + diff --git a/libsrc/meshing/meshfunc.cpp b/libsrc/meshing/meshfunc.cpp new file mode 100644 index 00000000..91002d1b --- /dev/null +++ b/libsrc/meshing/meshfunc.cpp @@ -0,0 +1,712 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + extern const char * tetrules[]; + // extern const char * tetrules2[]; + extern const char * prismrules2[]; + extern const char * pyramidrules[]; + extern const char * pyramidrules2[]; + + + // extern double teterrpow; + MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d) + { + int oldne; + int meshed; + + Array connectednodes; + + if (&mesh3d.LocalHFunction() == NULL) mesh3d.CalcLocalH(mp.grading); + + mesh3d.Compress(); + + // mesh3d.PrintMemInfo (cout); + + if (mp.checkoverlappingboundary) + if (mesh3d.CheckOverlappingBoundary()) + throw NgException ("Stop meshing since boundary mesh is overlapping"); + + int nonconsist = 0; + for (int k = 1; k <= mesh3d.GetNDomains(); k++) + { + PrintMessage (3, "Check subdomain ", k, " / ", mesh3d.GetNDomains()); + + mesh3d.FindOpenElements(k); + + /* + bool res = mesh3d.CheckOverlappingBoundary(); + if (res) + { + PrintError ("Surface is overlapping !!"); + nonconsist = 1; + } + */ + + bool res = (mesh3d.CheckConsistentBoundary() != 0); + if (res) + { + PrintError ("Surface mesh not consistent"); + nonconsist = 1; + } + } + + if (nonconsist) + { + PrintError ("Stop meshing since surface mesh not consistent"); + throw NgException ("Stop meshing since surface mesh not consistent"); + } + + double globmaxh = mp.maxh; + + for (int k = 1; k <= mesh3d.GetNDomains(); k++) + { + if (multithread.terminate) + break; + + PrintMessage (2, ""); + PrintMessage (1, "Meshing subdomain ", k, " of ", mesh3d.GetNDomains()); + (*testout) << "Meshing subdomain " << k << endl; + + mp.maxh = min2 (globmaxh, mesh3d.MaxHDomain(k)); + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(k); + + if (!mesh3d.GetNOpenElements()) + continue; + + + + Box<3> domain_bbox( Box<3>::EMPTY_BOX ); + + for (SurfaceElementIndex sei = 0; sei < mesh3d.GetNSE(); sei++) + { + const Element2d & el = mesh3d[sei]; + if (el.IsDeleted() ) continue; + + if (mesh3d.GetFaceDescriptor(el.GetIndex()).DomainIn() == k || + mesh3d.GetFaceDescriptor(el.GetIndex()).DomainOut() == k) + + for (int j = 0; j < el.GetNP(); j++) + domain_bbox.Add (mesh3d[el[j]]); + } + domain_bbox.Increase (0.01 * domain_bbox.Diam()); + + + for (int qstep = 1; qstep <= 3; qstep++) + { + // cout << "openquads = " << mesh3d.HasOpenQuads() << endl; + if (mesh3d.HasOpenQuads()) + { + string rulefile = ngdir; + + const char ** rulep = NULL; + switch (qstep) + { + case 1: + rulefile += "/rules/prisms2.rls"; + rulep = prismrules2; + break; + case 2: // connect pyramid to triangle + rulefile += "/rules/pyramids2.rls"; + rulep = pyramidrules2; + break; + case 3: // connect to vis-a-vis point + rulefile += "/rules/pyramids.rls"; + rulep = pyramidrules; + break; + } + + // Meshing3 meshing(rulefile); + Meshing3 meshing(rulep); + + MeshingParameters mpquad = mp; + + mpquad.giveuptol = 15; + mpquad.baseelnp = 4; + mpquad.starshapeclass = 1000; + mpquad.check_impossible = qstep == 1; // for prisms only (air domain in trafo) + + + for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) + meshing.AddPoint (mesh3d[pi], pi); + + mesh3d.GetIdentifications().GetPairs (0, connectednodes); + for (int i = 1; i <= connectednodes.Size(); i++) + meshing.AddConnectedPair (connectednodes.Get(i)); + + for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) + { + Element2d hel = mesh3d.OpenElement(i); + meshing.AddBoundaryElement (hel); + } + + oldne = mesh3d.GetNE(); + + meshing.GenerateMesh (mesh3d, mpquad); + + for (int i = oldne + 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (k); + + (*testout) + << "mesh has " << mesh3d.GetNE() << " prism/pyramid elements" << endl; + + mesh3d.FindOpenElements(k); + } + } + + + if (mesh3d.HasOpenQuads()) + { + PrintSysError ("mesh has still open quads"); + throw NgException ("Stop meshing since too many attempts"); + // return MESHING3_GIVEUP; + } + + + if (mp.delaunay && mesh3d.GetNOpenElements()) + { + Meshing3 meshing((const char**)NULL); + + mesh3d.FindOpenElements(k); + + + for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) + meshing.AddPoint (mesh3d[pi], pi); + + for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) + meshing.AddBoundaryElement (mesh3d.OpenElement(i)); + + oldne = mesh3d.GetNE(); + + meshing.Delaunay (mesh3d, k, mp); + + for (int i = oldne + 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (k); + + PrintMessage (3, mesh3d.GetNP(), " points, ", + mesh3d.GetNE(), " elements"); + } + + + int cntsteps = 0; + if (mesh3d.GetNOpenElements()) + do + { + if (multithread.terminate) + break; + + mesh3d.FindOpenElements(k); + PrintMessage (5, mesh3d.GetNOpenElements(), " open faces"); + cntsteps++; + + if (cntsteps > mp.maxoutersteps) + throw NgException ("Stop meshing since too many attempts"); + + string rulefile = ngdir + "/tetra.rls"; + PrintMessage (1, "start tetmeshing"); + + // Meshing3 meshing(rulefile); + Meshing3 meshing(tetrules); + + Array glob2loc(mesh3d.GetNP()); + glob2loc = -1; + + for (PointIndex pi = mesh3d.Points().Begin(); pi < mesh3d.Points().End(); pi++) + if (domain_bbox.IsIn (mesh3d[pi])) + glob2loc[pi] = + meshing.AddPoint (mesh3d[pi], pi); + + for (int i = 1; i <= mesh3d.GetNOpenElements(); i++) + { + Element2d hel = mesh3d.OpenElement(i); + for (int j = 0; j < hel.GetNP(); j++) + hel[j] = glob2loc[hel[j]]; + meshing.AddBoundaryElement (hel); + // meshing.AddBoundaryElement (mesh3d.OpenElement(i)); + } + + oldne = mesh3d.GetNE(); + + mp.giveuptol = 15 + 10 * cntsteps; + mp.sloppy = 5; + meshing.GenerateMesh (mesh3d, mp); + + for (ElementIndex ei = oldne; ei < mesh3d.GetNE(); ei++) + mesh3d[ei].SetIndex (k); + + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(k); + + // teterrpow = 2; + if (mesh3d.GetNOpenElements() != 0) + { + meshed = 0; + PrintMessage (5, mesh3d.GetNOpenElements(), " open faces found"); + + MeshOptimize3d optmesh(mp); + + const char * optstr = "mcmstmcmstmcmstmcm"; + for (size_t j = 1; j <= strlen(optstr); j++) + { + mesh3d.CalcSurfacesOfNode(); + mesh3d.FreeOpenElementsEnvironment(2); + mesh3d.CalcSurfacesOfNode(); + + switch (optstr[j-1]) + { + case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; + case 'd': optmesh.SplitImprove(mesh3d, OPT_REST); break; + case 's': optmesh.SwapImprove(mesh3d, OPT_REST); break; + case 't': optmesh.SwapImprove2(mesh3d, OPT_REST); break; + case 'm': mesh3d.ImproveMesh(mp, OPT_REST); break; + } + + } + + mesh3d.FindOpenElements(k); + PrintMessage (3, "Call remove problem"); + RemoveProblem (mesh3d, k); + mesh3d.FindOpenElements(k); + } + else + { + meshed = 1; + PrintMessage (1, "Success !"); + } + } + while (!meshed); + + PrintMessage (1, mesh3d.GetNP(), " points, ", + mesh3d.GetNE(), " elements"); + } + + mp.maxh = globmaxh; + + MeshQuality3d (mesh3d); + + return MESHING3_OK; + } + + + + + /* + + + MESHING3_RESULT MeshVolumeOld (MeshingParameters & mp, Mesh& mesh3d) + { + int i, k, oldne; + + + int meshed; + int cntsteps; + + + PlotStatistics3d * pstat; + if (globflags.GetNumFlag("silentflag", 1) <= 2) + pstat = new XPlotStatistics3d; + else + pstat = new TerminalPlotStatistics3d; + + cntsteps = 0; + do + { + cntsteps++; + if (cntsteps > mp.maxoutersteps) + { + return MESHING3_OUTERSTEPSEXCEEDED; + } + + + int noldp = mesh3d.GetNP(); + + + if ( (cntsteps == 1) && globflags.GetDefineFlag ("delaunay")) + { + cntsteps ++; + + mesh3d.CalcSurfacesOfNode(); + + + for (k = 1; k <= mesh3d.GetNDomains(); k++) + { + Meshing3 meshing(NULL, pstat); + + mesh3d.FindOpenElements(k); + + for (i = 1; i <= noldp; i++) + meshing.AddPoint (mesh3d.Point(i), i); + + for (i = 1; i <= mesh3d.GetNOpenElements(); i++) + { + if (mesh3d.OpenElement(i).GetIndex() == k) + meshing.AddBoundaryElement (mesh3d.OpenElement(i)); + } + + oldne = mesh3d.GetNE(); + if (globflags.GetDefineFlag ("blockfill")) + { + if (!globflags.GetDefineFlag ("localh")) + meshing.BlockFill + (mesh3d, mp.h * globflags.GetNumFlag ("relblockfillh", 1)); + else + meshing.BlockFillLocalH (mesh3d); + } + + MeshingParameters mpd; + meshing.Delaunay (mesh3d, mpd); + + for (i = oldne + 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (k); + } + } + + noldp = mesh3d.GetNP(); + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(); + for (k = 1; k <= mesh3d.GetNDomains(); k++) + { + Meshing3 meshing(globflags.GetStringFlag ("rules3d", NULL), pstat); + + Point3d pmin, pmax; + mesh3d.GetBox (pmin, pmax, k); + + rot.SetCenter (Center (pmin, pmax)); + + for (i = 1; i <= noldp; i++) + meshing.AddPoint (mesh3d.Point(i), i); + + for (i = 1; i <= mesh3d.GetNOpenElements(); i++) + { + if (mesh3d.OpenElement(i).GetIndex() == k) + meshing.AddBoundaryElement (mesh3d.OpenElement(i)); + } + + oldne = mesh3d.GetNE(); + + + if ( (cntsteps == 1) && globflags.GetDefineFlag ("blockfill")) + { + if (!globflags.GetDefineFlag ("localh")) + { + meshing.BlockFill + (mesh3d, + mp.h * globflags.GetNumFlag ("relblockfillh", 1)); + } + else + { + meshing.BlockFillLocalH (mesh3d); + } + } + + + mp.giveuptol = int(globflags.GetNumFlag ("giveuptol", 15)); + + meshing.GenerateMesh (mesh3d, mp); + + for (i = oldne + 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (k); + } + + + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(); + + teterrpow = 2; + if (mesh3d.GetNOpenElements() != 0) + { + meshed = 0; + (*mycout) << "Open elements found, old" << endl; + const char * optstr = "mcmcmcmcm"; + int j; + for (j = 1; j <= strlen(optstr); j++) + switch (optstr[j-1]) + { + case 'c': mesh3d.CombineImprove(); break; + case 'd': mesh3d.SplitImprove(); break; + case 's': mesh3d.SwapImprove(); break; + case 'm': mesh3d.ImproveMesh(2); break; + } + + (*mycout) << "Call remove" << endl; + RemoveProblem (mesh3d); + (*mycout) << "Problem removed" << endl; + } + else + meshed = 1; + } + while (!meshed); + + MeshQuality3d (mesh3d); + + return MESHING3_OK; + } + + */ + + + + + /* + MESHING3_RESULT MeshMixedVolume(MeshingParameters & mp, Mesh& mesh3d) + { + int i, j; + MESHING3_RESULT res; + Point3d pmin, pmax; + + mp.giveuptol = 10; + mp.baseelnp = 4; + mp.starshapeclass = 100; + + // TerminalPlotStatistics3d pstat; + + Meshing3 meshing1("pyramids.rls"); + for (i = 1; i <= mesh3d.GetNP(); i++) + meshing1.AddPoint (mesh3d.Point(i), i); + + mesh3d.FindOpenElements(); + for (i = 1; i <= mesh3d.GetNOpenElements(); i++) + if (mesh3d.OpenElement(i).GetIndex() == 1) + meshing1.AddBoundaryElement (mesh3d.OpenElement(i)); + + res = meshing1.GenerateMesh (mesh3d, mp); + + mesh3d.GetBox (pmin, pmax); + PrintMessage (1, "Mesh pyramids, res = ", res); + if (res) + exit (1); + + + for (i = 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (1); + + // do delaunay + + mp.baseelnp = 0; + mp.starshapeclass = 5; + + Meshing3 meshing2(NULL); + for (i = 1; i <= mesh3d.GetNP(); i++) + meshing2.AddPoint (mesh3d.Point(i), i); + + mesh3d.FindOpenElements(); + for (i = 1; i <= mesh3d.GetNOpenElements(); i++) + if (mesh3d.OpenElement(i).GetIndex() == 1) + meshing2.AddBoundaryElement (mesh3d.OpenElement(i)); + + MeshingParameters mpd; + meshing2.Delaunay (mesh3d, mpd); + + for (i = 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (1); + + + mp.baseelnp = 0; + mp.giveuptol = 10; + + for (int trials = 1; trials <= 50; trials++) + { + if (multithread.terminate) + return MESHING3_TERMINATE; + + Meshing3 meshing3("tetra.rls"); + for (i = 1; i <= mesh3d.GetNP(); i++) + meshing3.AddPoint (mesh3d.Point(i), i); + + mesh3d.FindOpenElements(); + for (i = 1; i <= mesh3d.GetNOpenElements(); i++) + if (mesh3d.OpenElement(i).GetIndex() == 1) + meshing3.AddBoundaryElement (mesh3d.OpenElement(i)); + + if (trials > 1) + CheckSurfaceMesh2 (mesh3d); + res = meshing3.GenerateMesh (mesh3d, mp); + + for (i = 1; i <= mesh3d.GetNE(); i++) + mesh3d.VolumeElement(i).SetIndex (1); + + if (res == 0) break; + + + + for (i = 1; i <= mesh3d.GetNE(); i++) + { + const Element & el = mesh3d.VolumeElement(i); + if (el.GetNP() != 4) + { + for (j = 1; j <= el.GetNP(); j++) + mesh3d.AddLockedPoint (el.PNum(j)); + } + } + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(); + + MeshOptimize3d optmesh; + + teterrpow = 2; + const char * optstr = "mcmcmcmcm"; + for (j = 1; j <= strlen(optstr); j++) + switch (optstr[j-1]) + { + case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; + case 'd': optmesh.SplitImprove(mesh3d); break; + case 's': optmesh.SwapImprove(mesh3d); break; + case 'm': mesh3d.ImproveMesh(); break; + } + + RemoveProblem (mesh3d); + } + + + PrintMessage (1, "Meshing tets, res = ", res); + if (res) + { + mesh3d.FindOpenElements(); + PrintSysError (1, "Open elemetns: ", mesh3d.GetNOpenElements()); + exit (1); + } + + + + for (i = 1; i <= mesh3d.GetNE(); i++) + { + const Element & el = mesh3d.VolumeElement(i); + if (el.GetNP() != 4) + { + for (j = 1; j <= el.GetNP(); j++) + mesh3d.AddLockedPoint (el.PNum(j)); + } + } + + mesh3d.CalcSurfacesOfNode(); + mesh3d.FindOpenElements(); + + MeshOptimize3d optmesh; + + teterrpow = 2; + const char * optstr = "mcmcmcmcm"; + for (j = 1; j <= strlen(optstr); j++) + switch (optstr[j-1]) + { + case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; + case 'd': optmesh.SplitImprove(mesh3d); break; + case 's': optmesh.SwapImprove(mesh3d); break; + case 'm': mesh3d.ImproveMesh(); break; + } + + + return MESHING3_OK; + } +*/ + + + + + + + MESHING3_RESULT OptimizeVolume (MeshingParameters & mp, + Mesh & mesh3d) + // const CSGeometry * geometry) + { + int i; + + PrintMessage (1, "Volume Optimization"); + + /* + if (!mesh3d.PureTetMesh()) + return MESHING3_OK; + */ + + // (*mycout) << "optstring = " << mp.optimize3d << endl; + /* + const char * optstr = globflags.GetStringFlag ("optimize3d", "cmh"); + int optsteps = int (globflags.GetNumFlag ("optsteps3d", 2)); + */ + + mesh3d.CalcSurfacesOfNode(); + for (i = 1; i <= mp.optsteps3d; i++) + { + if (multithread.terminate) + break; + + MeshOptimize3d optmesh(mp); + + // teterrpow = mp.opterrpow; + for (size_t j = 1; j <= strlen(mp.optimize3d); j++) + { + if (multithread.terminate) + break; + + switch (mp.optimize3d[j-1]) + { + case 'c': optmesh.CombineImprove(mesh3d, OPT_REST); break; + case 'd': optmesh.SplitImprove(mesh3d); break; + case 's': optmesh.SwapImprove(mesh3d); break; + // case 'u': optmesh.SwapImproveSurface(mesh3d); break; + case 't': optmesh.SwapImprove2(mesh3d); break; +#ifdef SOLIDGEOM + case 'm': mesh3d.ImproveMesh(*geometry); break; + case 'M': mesh3d.ImproveMesh(*geometry); break; +#else + case 'm': mesh3d.ImproveMesh(mp); break; + case 'M': mesh3d.ImproveMesh(mp); break; +#endif + case 'j': mesh3d.ImproveMeshJacobian(mp); break; + } + } + mesh3d.mglevels = 1; + MeshQuality3d (mesh3d); + } + + return MESHING3_OK; + } + + + + + void RemoveIllegalElements (Mesh & mesh3d) + { + int it = 10; + int nillegal, oldn; + + PrintMessage (1, "Remove Illegal Elements"); + // return, if non-pure tet-mesh + /* + if (!mesh3d.PureTetMesh()) + return; + */ + mesh3d.CalcSurfacesOfNode(); + + nillegal = mesh3d.MarkIllegalElements(); + + MeshingParameters dummymp; + MeshOptimize3d optmesh(dummymp); + while (nillegal && (it--) > 0) + { + if (multithread.terminate) + break; + + PrintMessage (5, nillegal, " illegal tets"); + optmesh.SplitImprove (mesh3d, OPT_LEGAL); + + mesh3d.MarkIllegalElements(); // test + optmesh.SwapImprove (mesh3d, OPT_LEGAL); + mesh3d.MarkIllegalElements(); // test + optmesh.SwapImprove2 (mesh3d, OPT_LEGAL); + + oldn = nillegal; + nillegal = mesh3d.MarkIllegalElements(); + + if (oldn != nillegal) + it = 10; + } + PrintMessage (5, nillegal, " illegal tets"); + } +} diff --git a/libsrc/meshing/meshfunc.hpp b/libsrc/meshing/meshfunc.hpp new file mode 100644 index 00000000..f39c0a8f --- /dev/null +++ b/libsrc/meshing/meshfunc.hpp @@ -0,0 +1,41 @@ +#ifndef FILE_MESHFUNC +#define FILE_MESHFUNC + +/**************************************************************************/ +/* File: meshfunc.hpp */ +/* Author: Johannes Gerstmayr, Joachim Schoeberl */ +/* Date: 26. Jan. 98 */ +/**************************************************************************/ + + +/* + Functions for mesh-generations strategies + */ + +class Mesh; +// class CSGeometry; + +/// Build tet-mesh +MESHING3_RESULT MeshVolume (MeshingParameters & mp, Mesh& mesh3d); + +/// Build mixed-element mesh +// MESHING3_RESULT MeshMixedVolume (MeshingParameters & mp, Mesh& mesh3d); + +/// Optimize tet-mesh +MESHING3_RESULT OptimizeVolume (MeshingParameters & mp, Mesh& mesh3d); +// const CSGeometry * geometry = NULL); + +void RemoveIllegalElements (Mesh & mesh3d); + + +enum MESHING_STEP { + MESHCONST_ANALYSE = 1, + MESHCONST_MESHEDGES = 2, + MESHCONST_MESHSURFACE = 3, + MESHCONST_OPTSURFACE = 4, + MESHCONST_MESHVOLUME = 5, + MESHCONST_OPTVOLUME = 6 +}; + + +#endif diff --git a/libsrc/meshing/meshfunc2d.cpp b/libsrc/meshing/meshfunc2d.cpp new file mode 100644 index 00000000..c3f2573e --- /dev/null +++ b/libsrc/meshing/meshfunc2d.cpp @@ -0,0 +1,57 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + + DLL_HEADER void Optimize2d (Mesh & mesh, MeshingParameters & mp) + { + static int timer = NgProfiler::CreateTimer ("optimize2d"); + NgProfiler::RegionTimer reg(timer); + + mesh.CalcSurfacesOfNode(); + + const char * optstr = mp.optimize2d; + int optsteps = mp.optsteps2d; + + for (int i = 1; i <= optsteps; i++) + for (size_t j = 1; j <= strlen(optstr); j++) + { + if (multithread.terminate) break; + switch (optstr[j-1]) + { + case 's': + { // topological swap + MeshOptimize2d meshopt; + meshopt.SetMetricWeight (0); + meshopt.EdgeSwapping (mesh, 0); + break; + } + case 'S': + { // metric swap + MeshOptimize2d meshopt; + meshopt.SetMetricWeight (0); + meshopt.EdgeSwapping (mesh, 1); + break; + } + case 'm': + { + MeshOptimize2d meshopt; + meshopt.SetMetricWeight (1); + meshopt.ImproveMesh(mesh, mp); + break; + } + case 'c': + { + MeshOptimize2d meshopt; + meshopt.SetMetricWeight (0.2); + meshopt.CombineImprove(mesh); + break; + } + default: + cerr << "Optimization code " << optstr[j-1] << " not defined" << endl; + } + } + } + +} diff --git a/libsrc/meshing/meshing.hpp b/libsrc/meshing/meshing.hpp new file mode 100644 index 00000000..7fd9c196 --- /dev/null +++ b/libsrc/meshing/meshing.hpp @@ -0,0 +1,71 @@ +#ifndef FILE_MESHING +#define FILE_MESHING + + + +#include "../include/myadt.hpp" +#include "../include/gprim.hpp" +#include "../include/linalg.hpp" +#include "../include/opti.hpp" + + + +namespace netgen +{ + // extern int printmessage_importance; + + class CSGeometry; + class NetgenGeometry; +} + + +#include "msghandler.hpp" +#include "meshtype.hpp" +#include "localh.hpp" +#include "meshclass.hpp" +#include "global.hpp" + + +namespace netgen +{ +#include "meshtool.hpp" +#include "ruler2.hpp" +#include "adfront2.hpp" +#include "meshing2.hpp" +#include "improve2.hpp" + + +#include "geomsearch.hpp" +#include "adfront3.hpp" +#include "ruler3.hpp" + +#define _INCLUDE_MORE + + +#include "meshing3.hpp" +#include "improve3.hpp" + +#include "findip.hpp" +#include "findip2.hpp" + +#include "topology.hpp" +#include "curvedelems.hpp" +#include "clusters.hpp" + +#include "meshfunc.hpp" + +#include "bisect.hpp" +#include "hprefinement.hpp" +#include "boundarylayer.hpp" +#include "specials.hpp" +} + +#include "validate.hpp" +#include "basegeom.hpp" + +#ifdef PARALLEL +#include "paralleltop.hpp" +#endif + + +#endif diff --git a/libsrc/meshing/meshing2.cpp b/libsrc/meshing/meshing2.cpp new file mode 100644 index 00000000..8a3c9b0e --- /dev/null +++ b/libsrc/meshing/meshing2.cpp @@ -0,0 +1,1965 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + static void glrender (int wait); + + + // global variable for visualization +// static Array locpoints; +// static Array legalpoints; +// static Array plainpoints; +// static Array plainzones; +// static Array loclines; +// // static int geomtrig; +// //static const char * rname; +// static int cntelem, trials, nfaces; +// static int oldnl; +// static int qualclass; + + + Meshing2 :: Meshing2 (const MeshingParameters & mp, const Box<3> & aboundingbox) + { + boundingbox = aboundingbox; + + LoadRules (NULL, mp.quad); + // LoadRules ("rules/quad.rls"); + // LoadRules ("rules/triangle.rls"); + + adfront = new AdFront2(boundingbox); + starttime = GetTime(); + + maxarea = -1; + } + + + Meshing2 :: ~Meshing2 () + { + delete adfront; + for (int i = 0; i < rules.Size(); i++) + delete rules[i]; + } + + void Meshing2 :: AddPoint (const Point3d & p, PointIndex globind, + MultiPointGeomInfo * mgi, + bool pointonsurface) + { + //(*testout) << "add point " << globind << endl; + adfront ->AddPoint (p, globind, mgi, pointonsurface); + } + + void Meshing2 :: AddBoundaryElement (int i1, int i2, + const PointGeomInfo & gi1, const PointGeomInfo & gi2) + { + // (*testout) << "add line " << i1 << " - " << i2 << endl; + if (!gi1.trignum || !gi2.trignum) + { + PrintSysError ("addboundaryelement: illegal geominfo"); + } + adfront -> AddLine (i1-1, i2-1, gi1, gi2); + } + + + + void Meshing2 :: StartMesh () + { + foundmap.SetSize (rules.Size()); + canuse.SetSize (rules.Size()); + ruleused.SetSize (rules.Size()); + + foundmap = 0; + canuse = 0; + ruleused = 0; + + // cntelem = 0; + // trials = 0; + } + + void Meshing2 :: EndMesh () + { + for (int i = 0; i < ruleused.Size(); i++) + (*testout) << setw(4) << ruleused[i] + << " times used rule " << rules[i] -> Name() << endl; + } + + void Meshing2 :: SetStartTime (double astarttime) + { + starttime = astarttime; + } + + + void Meshing2 :: SetMaxArea (double amaxarea) + { + maxarea = amaxarea; + } + + + double Meshing2 :: CalcLocalH (const Point3d & /* p */, double gh) const + { + return gh; + } + + // should be class variables !!(?) + // static Vec3d ex, ey; + // static Point3d globp1; + + void Meshing2 :: DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo1, + const PointGeomInfo * geominfo2) + { + globp1 = p1; + ex = p2 - p1; + ex /= ex.Length(); + ey.X() = -ex.Y(); + ey.Y() = ex.X(); + ey.Z() = 0; + } + + void Meshing2 :: TransformToPlain (const Point3d & locpoint, + const MultiPointGeomInfo & geominf, + Point2d & plainpoint, double h, int & zone) + { + Vec3d p1p (globp1, locpoint); + + // p1p = locpoint - globp1; + p1p /= h; + plainpoint.X() = p1p * ex; + plainpoint.Y() = p1p * ey; + zone = 0; + } + + int Meshing2 :: TransformFromPlain (Point2d & plainpoint, + Point3d & locpoint, + PointGeomInfo & gi, + double h) + { + Vec3d p1p; + gi.trignum = 1; + + p1p = plainpoint.X() * ex + plainpoint.Y() * ey; + p1p *= h; + locpoint = globp1 + p1p; + return 0; + } + + + int Meshing2 :: BelongsToActiveChart (const Point3d & p, + const PointGeomInfo & gi) + { + return 1; + } + + + int Meshing2 :: ComputePointGeomInfo (const Point3d & p, PointGeomInfo & gi) + { + gi.trignum = 1; + return 0; + } + + + int Meshing2 :: ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, + PointGeomInfo & pgi) + { + pgi = mpgi.GetPGI(1); + return 0; + } + + + + int Meshing2 :: + IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, + int endpoint, const PointGeomInfo & geominfo) + { + return 1; + } + + void Meshing2 :: + GetChartBoundary (Array & points, + Array & points3d, + Array & lines, double h) const + { + points.SetSize (0); + points3d.SetSize (0); + lines.SetSize (0); + } + + double Meshing2 :: Area () const + { + return -1; + } + + + + + + MESHING2_RESULT Meshing2 :: GenerateMesh (Mesh & mesh, const MeshingParameters & mp, double gh, int facenr) + { + static int timer = NgProfiler::CreateTimer ("surface meshing"); + + static int timer1 = NgProfiler::CreateTimer ("surface meshing1"); + static int timer2 = NgProfiler::CreateTimer ("surface meshing2"); + static int timer3 = NgProfiler::CreateTimer ("surface meshing3"); + + static int ts1 = NgProfiler::CreateTimer ("surface meshing start 1"); + static int ts2 = NgProfiler::CreateTimer ("surface meshing start 2"); + static int ts3 = NgProfiler::CreateTimer ("surface meshing start 3"); + + + NgProfiler::RegionTimer reg (timer); + + NgProfiler::StartTimer (ts1); + + Array pindex, lindex; + Array delpoints, dellines; + + Array upgeominfo; // unique info + Array mpgeominfo; // multiple info + + Array locelements; + + int z1, z2, oldnp(-1); + bool found; + int rulenr(-1); + Point<3> p1, p2; + + const PointGeomInfo * blgeominfo1; + const PointGeomInfo * blgeominfo2; + + bool morerisc; + bool debugflag; + + double h, his, hshould; + + + Array locpoints; + Array legalpoints; + Array plainpoints; + Array plainzones; + Array loclines; + int cntelem = 0, trials = 0, nfaces = 0; + int oldnl = 0; + int qualclass; + + + + // test for 3d overlaps + Box3dTree surfeltree (boundingbox.PMin(), + boundingbox.PMax()); + + Array intersecttrias; + Array critpoints; + + // test for doubled edges + //INDEX_2_HASHTABLE doubleedge(300000); + + + testmode = 0; + + StartMesh(); + + Array chartboundpoints; + Array chartboundpoints3d; + Array chartboundlines; + + // illegal points: points with more then 50 elements per node + int maxlegalpoint(-1), maxlegalline(-1); + Array trigsonnode; + Array illegalpoint; + + trigsonnode.SetSize (mesh.GetNP()); + illegalpoint.SetSize (mesh.GetNP()); + + trigsonnode = 0; + illegalpoint = 0; + + double totalarea = Area (); + double meshedarea = 0; + + + // search tree for surface elements: + /* + for (sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & sel = mesh[sei]; + + if (sel.IsDeleted()) continue; + + if (sel.GetIndex() == facenr) + { + Box<3> box; + box.Set ( mesh[sel[0]] ); + box.Add ( mesh[sel[1]] ); + box.Add ( mesh[sel[2]] ); + surfeltree.Insert (box, sei); + } + } + */ + Array seia; + mesh.GetSurfaceElementsOfFace (facenr, seia); + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & sel = mesh[seia[i]]; + + if (sel.IsDeleted()) continue; + + Box<3> box; + box.Set ( mesh[sel[0]] ); + box.Add ( mesh[sel[1]] ); + box.Add ( mesh[sel[2]] ); + surfeltree.Insert (box, seia[i]); + } + + NgProfiler::StopTimer (ts1); + NgProfiler::StartTimer (ts2); + + if (totalarea > 0 || maxarea > 0) + meshedarea = mesh.SurfaceArea(); + /* + for (SurfaceElementIndex sei = 0; sei < mesh.GetNSE(); sei++) + { + const Element2d & sel = mesh[sei]; + if (sel.IsDeleted()) continue; + + double trigarea = Cross ( mesh[sel[1]]-mesh[sel[0]], + mesh[sel[2]]-mesh[sel[0]] ).Length() / 2; + + + if (sel.GetNP() == 4) + trigarea += Cross (Vec3d (mesh.Point (sel.PNum(1)), + mesh.Point (sel.PNum(3))), + Vec3d (mesh.Point (sel.PNum(1)), + mesh.Point (sel.PNum(4)))).Length() / 2;; + meshedarea += trigarea; + } + */ + // cout << "meshedarea = " << meshedarea << " =?= " + // << mesh.SurfaceArea() << endl; + + NgProfiler::StopTimer (ts2); + NgProfiler::StartTimer (ts3); + + const char * savetask = multithread.task; + multithread.task = "Surface meshing"; + + adfront ->SetStartFront (); + + + int plotnexttrial = 999; + + double meshedarea_before = meshedarea; + + NgProfiler::StopTimer (ts3); + + while (!adfront ->Empty() && !multithread.terminate) + { + NgProfiler::RegionTimer reg1 (timer1); + + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + // known for STL meshing + if (totalarea > 0) + multithread.percent = 100 * meshedarea / totalarea; + /* + else + multithread.percent = 0; + */ + + locpoints.SetSize(0); + loclines.SetSize(0); + pindex.SetSize(0); + lindex.SetSize(0); + delpoints.SetSize(0); + dellines.SetSize(0); + locelements.SetSize(0); + + + + // plot statistics + if (trials > plotnexttrial) + { + PrintMessage (5, + "faces = ", nfaces, + " trials = ", trials, + " elements = ", mesh.GetNSE(), + " els/sec = ", + (mesh.GetNSE() / (GetTime() - starttime + 0.0001))); + plotnexttrial += 1000; + } + + + // unique-pgi, multi-pgi + upgeominfo.SetSize(0); + mpgeominfo.SetSize(0); + + + nfaces = adfront->GetNFL(); + trials ++; + + + if (trials % 1000 == 0) + { + (*testout) << "\n"; + for (int i = 1; i <= canuse.Size(); i++) + { + (*testout) << foundmap.Get(i) << "/" + << canuse.Get(i) << "/" + << ruleused.Get(i) << " map/can/use rule " << rules.Get(i)->Name() << "\n"; + } + (*testout) << "\n"; + } + + + int baselineindex = adfront -> SelectBaseLine (p1, p2, blgeominfo1, blgeominfo2, qualclass); + + + found = 1; + + his = Dist (p1, p2); + + Point3d pmid = Center (p1, p2); + hshould = CalcLocalH (pmid, mesh.GetH (pmid)); + if (gh < hshould) hshould = gh; + + mesh.RestrictLocalH (pmid, hshould); + + h = hshould; + + double hinner = (3 + qualclass) * max2 (his, hshould); + + adfront ->GetLocals (baselineindex, locpoints, mpgeominfo, loclines, + pindex, lindex, 2*hinner); + + + NgProfiler::RegionTimer reg2 (timer2); + + //(*testout) << "h for locals: " << 2*hinner << endl; + + + //(*testout) << "locpoints " << locpoints << endl; + + if (qualclass > mp.giveuptol2d) + { + PrintMessage (3, "give up with qualclass ", qualclass); + PrintMessage (3, "number of frontlines = ", adfront->GetNFL()); + // throw NgException ("Give up 2d meshing"); + break; + } + + /* + if (found && qualclass > 60) + { + found = 0; + } + */ + // morerisc = ((qualclass > 20) && (qualclass % 2 == 1)); + // morerisc = 1; + morerisc = 0; + + + PointIndex gpi1 = adfront -> GetGlobalIndex (pindex.Get(loclines[0].I1())); + PointIndex gpi2 = adfront -> GetGlobalIndex (pindex.Get(loclines[0].I2())); + + + debugflag = + ( + debugparam.haltsegment && + ( ((debugparam.haltsegmentp1 == gpi1) && (debugparam.haltsegmentp2 == gpi2)) || + ((debugparam.haltsegmentp1 == gpi2) && (debugparam.haltsegmentp2 == gpi1))) + ) + || + ( + debugparam.haltnode && + ( (debugparam.haltsegmentp1 == gpi1) || (debugparam.haltsegmentp2 == gpi1)) + ); + + + if (debugparam.haltface && debugparam.haltfacenr == facenr) + { + debugflag = 1; + cout << "set debugflag" << endl; + } + + if (debugparam.haltlargequalclass && qualclass > 50) + debugflag = 1; + + // problem recognition ! + if (found && + (gpi1 < illegalpoint.Size()+PointIndex::BASE) && + (gpi2 < illegalpoint.Size()+PointIndex::BASE) ) + { + if (illegalpoint[gpi1] || illegalpoint[gpi2]) + found = 0; + } + + + Point2d p12d, p22d; + + if (found) + { + oldnp = locpoints.Size(); + oldnl = loclines.Size(); + + if (debugflag) + (*testout) << "define new transformation" << endl; + + DefineTransformation (p1, p2, blgeominfo1, blgeominfo2); + + plainpoints.SetSize (locpoints.Size()); + plainzones.SetSize (locpoints.Size()); + + // (*testout) << endl; + + if (debugflag) + { + *testout << "3d->2d transformation" << endl; + *testout << "3d points: " << endl << locpoints << endl; + } + + for (int i = 1; i <= locpoints.Size(); i++) + { + // (*testout) << "pindex(i) = " << pindex[i-1] << endl; + TransformToPlain (locpoints.Get(i), + mpgeominfo.Get(i), + plainpoints.Elem(i), h, plainzones.Elem(i)); + // (*testout) << mpgeominfo.Get(i).GetPGI(1).u << " " << mpgeominfo.Get(i).GetPGI(1).v << " "; + // (*testout) << plainpoints.Get(i).X() << " " << plainpoints.Get(i).Y() << endl; + //(*testout) << "transform " << locpoints.Get(i) << " to " << plainpoints.Get(i).X() << " " << plainpoints.Get(i).Y() << endl; + } + // (*testout) << endl << endl << endl; + + + if (debugflag) + *testout << "2d points: " << endl << plainpoints << endl; + + + p12d = plainpoints.Get(1); + p22d = plainpoints.Get(2); + + /* + // last idea on friday + plainzones.Elem(1) = 0; + plainzones.Elem(2) = 0; + */ + + + /* + // old netgen: + for (i = 2; i <= loclines.Size(); i++) // don't remove first line + { + z1 = plainzones.Get(loclines.Get(i).I1()); + z2 = plainzones.Get(loclines.Get(i).I2()); + + if (z1 && z2 && (z1 != z2) || (z1 == -1) || (z2 == -1) ) + { + loclines.DeleteElement(i); + lindex.DeleteElement(i); + oldnl--; + i--; + } + } + + // for (i = 1; i <= plainpoints.Size(); i++) + // if (plainzones.Elem(i) == -1) + // plainpoints.Elem(i) = Point2d (1e4, 1e4); + */ + + + + for (int i = 2; i <= loclines.Size(); i++) // don't remove first line + { + // (*testout) << "loclines(i) = " << loclines.Get(i).I1() << " - " << loclines.Get(i).I2() << endl; + z1 = plainzones.Get(loclines.Get(i).I1()); + z2 = plainzones.Get(loclines.Get(i).I2()); + + + // one inner point, one outer + if ( (z1 >= 0) != (z2 >= 0)) + { + int innerp = (z1 >= 0) ? 1 : 2; + if (IsLineVertexOnChart (locpoints.Get(loclines.Get(i).I1()), + locpoints.Get(loclines.Get(i).I2()), + innerp, + adfront->GetLineGeomInfo (lindex.Get(i), innerp))) + // pgeominfo.Get(loclines.Get(i).I(innerp)))) + { + + if (!morerisc) + { + // use one end of line + int pini, pouti; + Vec2d v; + + pini = loclines.Get(i).I(innerp); + pouti = loclines.Get(i).I(3-innerp); + + Point2d pin (plainpoints.Get(pini)); + Point2d pout (plainpoints.Get(pouti)); + v = pout - pin; + double len = v.Length(); + if (len <= 1e-6) + (*testout) << "WARNING(js): inner-outer: short vector" << endl; + else + v /= len; + + /* + // don't elongate line towards base-line !! + if (Vec2d (pin, p12d) * v > 0 && + Vec2d (pin, p22d) * v > 0) + v *= -1; + */ + + Point2d newpout = pin + 1000 * v; + newpout = pout; + + + plainpoints.Append (newpout); + Point3d pout3d = locpoints.Get(pouti); + locpoints.Append (pout3d); + + plainzones.Append (0); + pindex.Append (-1); + oldnp++; + loclines.Elem(i).I(3-innerp) = oldnp; + } + else + plainzones.Elem(loclines.Get(i).I(3-innerp)) = 0; + + + // (*testout) << "inner - outer correction" << endl; + } + else + { + // remove line + loclines.DeleteElement(i); + lindex.DeleteElement(i); + oldnl--; + i--; + } + } + + else if ( (z1 > 0 && z2 > 0 && (z1 != z2)) || ((z1 < 0) && (z2 < 0)) ) + { + loclines.DeleteElement(i); + lindex.DeleteElement(i); + oldnl--; + i--; + } + } + + + + + + legalpoints.SetSize(plainpoints.Size()); + for (int i = 1; i <= legalpoints.Size(); i++) + legalpoints.Elem(i) = 1; + + double avy = 0; + for (int i = 1; i <= plainpoints.Size(); i++) + avy += plainpoints.Elem(i).Y(); + avy *= 1./plainpoints.Size(); + + + for (int i = 1; i <= plainpoints.Size(); i++) + { + if (plainzones.Elem(i) < 0) + { + plainpoints.Elem(i) = Point2d (1e4, 1e4); + legalpoints.Elem(i) = 0; + } + if (pindex.Elem(i) == -1) + { + legalpoints.Elem(i) = 0; + } + + + if (plainpoints.Elem(i).Y() < -1e-10*avy) // changed + { + legalpoints.Elem(i) = 0; + } + } + /* + for (i = 3; i <= plainpoints.Size(); i++) + if (sqr (plainpoints.Get(i).X()) + sqr (plainpoints.Get(i).Y()) + > sqr (2 + 0.2 * qualclass)) + legalpoints.Elem(i) = 0; + */ + + /* + int clp = 0; + for (i = 1; i <= plainpoints.Size(); i++) + if (legalpoints.Get(i)) + clp++; + (*testout) << "legalpts: " << clp << "/" << plainpoints.Size() << endl; + + // sort legal/illegal lines + int lastleg = 2; + int firstilleg = oldnl; + + while (lastleg < firstilleg) + { + while (legalpoints.Get(loclines.Get(lastleg).I1()) && + legalpoints.Get(loclines.Get(lastleg).I2()) && + lastleg < firstilleg) + lastleg++; + while ( ( !legalpoints.Get(loclines.Get(firstilleg).I1()) || + !legalpoints.Get(loclines.Get(firstilleg).I2())) && + lastleg < firstilleg) + firstilleg--; + + if (lastleg < firstilleg) + { + swap (loclines.Elem(lastleg), loclines.Elem(firstilleg)); + swap (lindex.Elem(lastleg), lindex.Elem(firstilleg)); + } + } + + (*testout) << "leglines " << lastleg << "/" << oldnl << endl; + */ + + + GetChartBoundary (chartboundpoints, + chartboundpoints3d, + chartboundlines, h); + + oldnp = plainpoints.Size(); + + maxlegalpoint = locpoints.Size(); + maxlegalline = loclines.Size(); + + + + if (mp.checkchartboundary) + { + for (int i = 1; i <= chartboundpoints.Size(); i++) + { + plainpoints.Append (chartboundpoints.Get(i)); + locpoints.Append (chartboundpoints3d.Get(i)); + legalpoints.Append (0); + } + + + for (int i = 1; i <= chartboundlines.Size(); i++) + { + INDEX_2 line (chartboundlines.Get(i).I1()+oldnp, + chartboundlines.Get(i).I2()+oldnp); + loclines.Append (line); + // (*testout) << "line: " << line.I1() << "-" << line.I2() << endl; + } + } + + oldnl = loclines.Size(); + oldnp = plainpoints.Size(); + } + + + /* + if (qualclass > 100) + { + multithread.drawing = 1; + glrender(1); + cout << "qualclass 100, nfl = " << adfront->GetNFL() << endl; + } + */ + + if (found) + { + rulenr = ApplyRules (plainpoints, legalpoints, maxlegalpoint, + loclines, maxlegalline, locelements, + dellines, qualclass, mp); + + // (*testout) << "Rule Nr = " << rulenr << endl; + if (!rulenr) + { + found = 0; + if ( debugflag || debugparam.haltnosuccess ) + PrintWarning ("no rule found"); + } + } + + NgProfiler::RegionTimer reg3 (timer3); + + + for (int i = 1; i <= locelements.Size() && found; i++) + { + const Element2d & el = locelements.Get(i); + + for (int j = 1; j <= el.GetNP(); j++) + if (el.PNum(j) <= oldnp && pindex.Get(el.PNum(j)) == -1) + { + found = 0; + PrintSysError ("meshing2, index missing"); + } + } + + + if (found) + { + locpoints.SetSize (plainpoints.Size()); + upgeominfo.SetSize(locpoints.Size()); + + for (int i = oldnp+1; i <= plainpoints.Size(); i++) + { + int err = + TransformFromPlain (plainpoints.Elem(i), locpoints.Elem(i), + upgeominfo.Elem(i), h); + + if (err) + { + found = 0; + + if ( debugflag || debugparam.haltnosuccess ) + PrintSysError ("meshing2, Backtransformation failed"); + + break; + } + } + } + + + // for (i = 1; i <= oldnl; i++) + // adfront -> ResetClass (lindex[i]); + + + /* + double violateminh; + if (qualclass <= 10) + violateminh = 3; + else + violateminh = 3 * qualclass; + + if (uselocalh && found) // && qualclass <= 10) + { + for (i = 1; i <= locelements.Size(); i++) + { + Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1)); + Point3d pmax = pmin; + for (j = 2; j <= 3; j++) + { + const Point3d & hp = + locpoints.Get(locelements.Get(i).PNum(j)); + pmin.SetToMin (hp); + pmax.SetToMax (hp); + } + double minh = mesh.GetMinH (pmin, pmax); + if (h > violateminh * minh) + { + found = 0; + loclines.SetSize (oldnl); + locpoints.SetSize (oldnp); + } + } + } + */ + + + if (found) + { + double violateminh = 3 + 0.1 * sqr (qualclass); + double minh = 1e8; + double newedgemaxh = 0; + for (int i = oldnl+1; i <= loclines.Size(); i++) + { + double eh = Dist (locpoints.Get(loclines.Get(i).I1()), + locpoints.Get(loclines.Get(i).I2())); + + // Markus (brute force method to avoid bad elements on geometries like \_/ ) + //if(eh > 4.*mesh.GetH(locpoints.Get(loclines.Get(i).I1()))) found = 0; + //if(eh > 4.*mesh.GetH(locpoints.Get(loclines.Get(i).I2()))) found = 0; + // Markus end + + if (eh > newedgemaxh) + newedgemaxh = eh; + } + + for (int i = 1; i <= locelements.Size(); i++) + { + Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1)); + Point3d pmax = pmin; + for (int j = 2; j <= locelements.Get(i).GetNP(); j++) + { + const Point3d & hp = + locpoints.Get(locelements.Get(i).PNum(j)); + pmin.SetToMin (hp); + pmax.SetToMax (hp); + } + double eh = mesh.GetMinH (pmin, pmax); + if (eh < minh) + minh = eh; + } + + for (int i = 1; i <= locelements.Size(); i++) + for (int j = 1; j <= locelements.Get(i).GetNP(); j++) + if (Dist2 (locpoints.Get(locelements.Get(i).PNum(j)), pmid) > hinner*hinner) + found = 0; + + // cout << "violate = " << newedgemaxh / minh << endl; + static double maxviolate = 0; + if (newedgemaxh / minh > maxviolate) + { + maxviolate = newedgemaxh / minh; + // cout << "max minhviolate = " << maxviolate << endl; + } + + + if (newedgemaxh > violateminh * minh) + { + found = 0; + loclines.SetSize (oldnl); + locpoints.SetSize (oldnp); + + if ( debugflag || debugparam.haltnosuccess ) + PrintSysError ("meshing2, maxh too large"); + + + } + } + + + + /* + // test good ComputeLineGeoInfo + if (found) + { + // is line on chart ? + for (i = oldnl+1; i <= loclines.Size(); i++) + { + int gisize; + void *geominfo; + + if (ComputeLineGeoInfo (locpoints.Get(loclines.Get(i).I1()), + locpoints.Get(loclines.Get(i).I2()), + gisize, geominfo)) + found = 0; + } + } + */ + + + // changed for OCC meshing + if (found) + { + // take geominfo from dellines + // upgeominfo.SetSize(locpoints.Size()); + + /* + for (i = 1; i <= dellines.Size(); i++) + for (j = 1; j <= 2; j++) + { + upgeominfo.Elem(loclines.Get(dellines.Get(i)).I(j)) = + adfront -> GetLineGeomInfo (lindex.Get(dellines.Get(i)), j); + } + */ + + + for (int i = 1; i <= locelements.Size(); i++) + for (int j = 1; j <= locelements.Get(i).GetNP(); j++) + { + int pi = locelements.Get(i).PNum(j); + if (pi <= oldnp) + { + + if (ChooseChartPointGeomInfo (mpgeominfo.Get(pi), upgeominfo.Elem(pi))) + { + // cannot select, compute new one + PrintWarning ("calc point geominfo instead of using"); + if (ComputePointGeomInfo (locpoints.Get(pi), upgeominfo.Elem(pi))) + { + found = 0; + PrintSysError ("meshing2d, geominfo failed"); + } + } + } + } + + /* + // use upgeominfo from ProjectFromPlane + for (i = oldnp+1; i <= locpoints.Size(); i++) + { + if (ComputePointGeomInfo (locpoints.Get(i), upgeominfo.Elem(i))) + { + found = 0; + if ( debugflag || debugparam.haltnosuccess ) + PrintSysError ("meshing2d, compute geominfo failed"); + } + } + */ + } + + + if (found && mp.checkoverlap) + { + // cout << "checkoverlap" << endl; + // test for overlaps + + Point3d hullmin(1e10, 1e10, 1e10); + Point3d hullmax(-1e10, -1e10, -1e10); + + for (int i = 1; i <= locelements.Size(); i++) + for (int j = 1; j <= locelements.Get(i).GetNP(); j++) + { + const Point3d & p = locpoints.Get(locelements.Get(i).PNum(j)); + hullmin.SetToMin (p); + hullmax.SetToMax (p); + } + hullmin += Vec3d (-his, -his, -his); + hullmax += Vec3d ( his, his, his); + + surfeltree.GetIntersecting (hullmin, hullmax, intersecttrias); + + critpoints.SetSize (0); + for (int i = oldnp+1; i <= locpoints.Size(); i++) + critpoints.Append (locpoints.Get(i)); + + for (int i = 1; i <= locelements.Size(); i++) + { + const Element2d & tri = locelements.Get(i); + if (tri.GetNP() == 3) + { + const Point3d & tp1 = locpoints.Get(tri.PNum(1)); + const Point3d & tp2 = locpoints.Get(tri.PNum(2)); + const Point3d & tp3 = locpoints.Get(tri.PNum(3)); + + Vec3d tv1 (tp1, tp2); + Vec3d tv2 (tp1, tp3); + + double lam1, lam2; + for (lam1 = 0.2; lam1 <= 0.8; lam1 += 0.2) + for (lam2 = 0.2; lam2 + lam1 <= 0.8; lam2 += 0.2) + { + Point3d hp = tp1 + lam1 * tv1 + lam2 * tv2; + critpoints.Append (hp); + } + } + else if (tri.GetNP() == 4) + { + const Point3d & tp1 = locpoints.Get(tri.PNum(1)); + const Point3d & tp2 = locpoints.Get(tri.PNum(2)); + const Point3d & tp3 = locpoints.Get(tri.PNum(3)); + const Point3d & tp4 = locpoints.Get(tri.PNum(4)); + + double l1, l2; + for (l1 = 0.1; l1 <= 0.9; l1 += 0.1) + for (l2 = 0.1; l2 <= 0.9; l2 += 0.1) + { + Point3d hp; + hp.X() = + (1-l1)*(1-l2) * tp1.X() + + l1*(1-l2) * tp2.X() + + l1*l2 * tp3.X() + + (1-l1)*l2 * tp4.X(); + hp.Y() = + (1-l1)*(1-l2) * tp1.Y() + + l1*(1-l2) * tp2.Y() + + l1*l2 * tp3.Y() + + (1-l1)*l2 * tp4.Y(); + hp.Z() = + (1-l1)*(1-l2) * tp1.Z() + + l1*(1-l2) * tp2.Z() + + l1*l2 * tp3.Z() + + (1-l1)*l2 * tp4.Z(); + + + critpoints.Append (hp); + } + } + } + /* + for (i = oldnl+1; i <= loclines.Size(); i++) + { + Point3d hp = locpoints.Get(loclines.Get(i).I1()); + Vec3d hv(hp, locpoints.Get(loclines.Get(i).I2())); + int ncp = 2; + for (j = 1; j <= ncp; j++) + critpoints.Append ( hp + (double(j)/(ncp+1)) * hv); + } + */ + + + /* + for (i = oldnp+1; i <= locpoints.Size(); i++) + { + const Point3d & p = locpoints.Get(i); + */ + + + for (int i = 1; i <= critpoints.Size(); i++) + { + const Point3d & p = critpoints.Get(i); + + for (int jj = 0; jj < intersecttrias.Size(); jj++) + { + // int j = intersecttrias.Get(jj); + // const Element2d & el = mesh.SurfaceElement(j); + + SurfaceElementIndex j = intersecttrias[jj]; + const Element2d & el = mesh[j]; + + int ntrig = (el.GetNP() == 3) ? 1 : 2; + + int jl; + for (jl = 1; jl <= ntrig; jl++) + { + Point3d tp1, tp2, tp3; + + if (jl == 1) + { + tp1 = mesh.Point(el.PNum(1)); + tp2 = mesh.Point(el.PNum(2)); + tp3 = mesh.Point(el.PNum(3)); + } + else + { + tp1 = mesh.Point(el.PNum(1)); + tp2 = mesh.Point(el.PNum(3)); + tp3 = mesh.Point(el.PNum(4)); + } + + int onchart = 0; + for (int k = 1; k <= el.GetNP(); k++) + if (BelongsToActiveChart (mesh.Point(el.PNum(k)), + el.GeomInfoPi(k))) + onchart = 1; + if (!onchart) + continue; + + Vec3d e1(tp1, tp2); + Vec3d e2(tp1, tp3); + Vec3d n = Cross (e1, e2); + n /= n.Length(); + double lam1, lam2, lam3; + lam3 = n * Vec3d (tp1, p); + LocalCoordinates (e1, e2, Vec3d (tp1, p), lam1, lam2); + + if (fabs (lam3) < 0.1 * hshould && + lam1 > 0 && lam2 > 0 && (lam1 + lam2) < 1) + { +#ifdef DEVELOP + cout << "overlap" << endl; + (*testout) << "overlap:" << endl + << "tri = " << tp1 << "-" << tp2 << "-" << tp3 << endl + << "point = " << p << endl + << "lam1, 2 = " << lam1 << ", " << lam2 << endl + << "lam3 = " << lam3 << endl; + + // cout << "overlap !!!" << endl; +#endif + for (int k = 1; k <= 5; k++) + adfront -> IncrementClass (lindex.Get(1)); + + found = 0; + + if ( debugflag || debugparam.haltnosuccess ) + PrintWarning ("overlapping"); + + + if (debugparam.haltoverlap) + { + debugflag = 1; + } + + /* + multithread.drawing = 1; + glrender(1); + */ + } + } + } + } + } + + + if (found) + { + // check, whether new front line already exists + + for (int i = oldnl+1; i <= loclines.Size(); i++) + { + int nlgpi1 = loclines.Get(i).I1(); + int nlgpi2 = loclines.Get(i).I2(); + if (nlgpi1 <= pindex.Size() && nlgpi2 <= pindex.Size()) + { + nlgpi1 = adfront->GetGlobalIndex (pindex.Get(nlgpi1)); + nlgpi2 = adfront->GetGlobalIndex (pindex.Get(nlgpi2)); + + int exval = adfront->ExistsLine (nlgpi1, nlgpi2); + if (exval) + { + cout << "ERROR: new line exits, val = " << exval << endl; + (*testout) << "ERROR: new line exits, val = " << exval << endl; + found = 0; + + + if (debugparam.haltexistingline) + debugflag = 1; + + } + } + } + + } + + + /* + if (found) + { + // check, whether new triangles insert edges twice + for (i = 1; i <= locelements.Size(); i++) + for (j = 1; j <= 3; j++) + { + int tpi1 = locelements.Get(i).PNumMod (j); + int tpi2 = locelements.Get(i).PNumMod (j+1); + if (tpi1 <= pindex.Size() && tpi2 <= pindex.Size()) + { + tpi1 = adfront->GetGlobalIndex (pindex.Get(tpi1)); + tpi2 = adfront->GetGlobalIndex (pindex.Get(tpi2)); + + if (doubleedge.Used (INDEX_2(tpi1, tpi2))) + { + if (debugparam.haltexistingline) + debugflag = 1; + cerr << "ERROR Insert edge " + << tpi1 << " - " << tpi2 << " twice !!!" << endl; + found = 0; + } + doubleedge.Set (INDEX_2(tpi1, tpi2), 1); + } + } + } + */ + + + if (found) + { + // everything is ok, perform mesh update + + ruleused.Elem(rulenr)++; + + + pindex.SetSize(locpoints.Size()); + + for (int i = oldnp+1; i <= locpoints.Size(); i++) + { + PointIndex globind = mesh.AddPoint (locpoints.Get(i)); + pindex.Elem(i) = adfront -> AddPoint (locpoints.Get(i), globind); + } + + for (int i = oldnl+1; i <= loclines.Size(); i++) + { + /* + for (j = 1; j <= locpoints.Size(); j++) + { + (*testout) << j << ": " << locpoints.Get(j) << endl; + } + */ + + /* + ComputeLineGeoInfo (locpoints.Get(loclines.Get(i).I1()), + locpoints.Get(loclines.Get(i).I2()), + gisize, geominfo); + */ + + if (pindex.Get(loclines.Get(i).I1()) == -1 || + pindex.Get(loclines.Get(i).I2()) == -1) + { + (*testout) << "pindex is 0" << endl; + } + + if (!upgeominfo.Get(loclines.Get(i).I1()).trignum || + !upgeominfo.Get(loclines.Get(i).I2()).trignum) + { + cout << "new el: illegal geominfo" << endl; + } + + adfront -> AddLine (pindex.Get(loclines.Get(i).I1()), + pindex.Get(loclines.Get(i).I2()), + upgeominfo.Get(loclines.Get(i).I1()), + upgeominfo.Get(loclines.Get(i).I2())); + } + for (int i = 1; i <= locelements.Size(); i++) + { + Element2d mtri(locelements.Get(i).GetNP()); + mtri = locelements.Get(i); + mtri.SetIndex (facenr); + + + // compute triangle geominfo: + // (*testout) << "triggeominfo: "; + for (int j = 1; j <= locelements.Get(i).GetNP(); j++) + { + mtri.GeomInfoPi(j) = upgeominfo.Get(locelements.Get(i).PNum(j)); + // (*testout) << mtri.GeomInfoPi(j).trignum << " "; + } + // (*testout) << endl; + + for (int j = 1; j <= locelements.Get(i).GetNP(); j++) + { + mtri.PNum(j) = + locelements.Elem(i).PNum(j) = + adfront -> GetGlobalIndex (pindex.Get(locelements.Get(i).PNum(j))); + } + + + + + mesh.AddSurfaceElement (mtri); + cntelem++; + // cout << "elements: " << cntelem << endl; + + + + Box<3> box; + box.Set (mesh[mtri[0]]); + box.Add (mesh[mtri[1]]); + box.Add (mesh[mtri[2]]); + surfeltree.Insert (box, mesh.GetNSE()-1); + + const Point3d & sep1 = mesh.Point (mtri.PNum(1)); + const Point3d & sep2 = mesh.Point (mtri.PNum(2)); + const Point3d & sep3 = mesh.Point (mtri.PNum(3)); + + double trigarea = Cross (Vec3d (sep1, sep2), + Vec3d (sep1, sep3)).Length() / 2; + + if (mtri.GetNP() == 4) + { + const Point3d & sep4 = mesh.Point (mtri.PNum(4)); + trigarea += Cross (Vec3d (sep1, sep3), + Vec3d (sep1, sep4)).Length() / 2; + } + + meshedarea += trigarea; + + if(maxarea > 0 && meshedarea-meshedarea_before > maxarea) + { + cerr << "meshed area = " << meshedarea-meshedarea_before << endl + << "maximal area = " << maxarea << endl + << "GIVING UP" << endl; + return MESHING2_GIVEUP; + } + + + + for (int j = 1; j <= locelements.Get(i).GetNP(); j++) + { + int gpi = locelements.Get(i).PNum(j); + + int oldts = trigsonnode.Size(); + if (gpi >= oldts+PointIndex::BASE) + { + trigsonnode.SetSize (gpi+1-PointIndex::BASE); + illegalpoint.SetSize (gpi+1-PointIndex::BASE); + for (int k = oldts+PointIndex::BASE; + k <= gpi; k++) + { + trigsonnode[k] = 0; + illegalpoint[k] = 0; + } + } + + trigsonnode[gpi]++; + + if (trigsonnode[gpi] > 20) + { + illegalpoint[gpi] = 1; + // cout << "illegal point: " << gpi << endl; + (*testout) << "illegal point: " << gpi << endl; + } + + static int mtonnode = 0; + if (trigsonnode[gpi] > mtonnode) + mtonnode = trigsonnode[gpi]; + } + // cout << "els = " << cntelem << " trials = " << trials << endl; + // if (trials > 100) return; + } + + for (int i = 1; i <= dellines.Size(); i++) + adfront -> DeleteLine (lindex.Get(dellines.Get(i))); + + // rname = rules.Get(rulenr)->Name(); +#ifdef MYGRAPH + if (silentflag<3) + { + plotsurf.DrawPnL(locpoints, loclines); + plotsurf.Plot(testmode, testmode); + } +#endif + + if (morerisc) + { + cout << "generated due to morerisc" << endl; + // multithread.drawing = 1; + // glrender(1); + } + + + + + if ( debugparam.haltsuccess || debugflag ) + { + // adfront -> PrintOpenSegments (*testout); + cout << "success of rule" << rules.Get(rulenr)->Name() << endl; + multithread.drawing = 1; + multithread.testmode = 1; + multithread.pause = 1; + + + /* + extern STLGeometry * stlgeometry; + stlgeometry->ClearMarkedSegs(); + for (i = 1; i <= loclines.Size(); i++) + { + stlgeometry->AddMarkedSeg(locpoints.Get(loclines.Get(i).I1()), + locpoints.Get(loclines.Get(i).I2())); + } + */ + + (*testout) << "success of rule" << rules.Get(rulenr)->Name() << endl; + (*testout) << "trials = " << trials << endl; + + (*testout) << "locpoints " << endl; + for (int i = 1; i <= pindex.Size(); i++) + (*testout) << adfront->GetGlobalIndex (pindex.Get(i)) << endl; + + (*testout) << "old number of lines = " << oldnl << endl; + for (int i = 1; i <= loclines.Size(); i++) + { + (*testout) << "line "; + for (int j = 1; j <= 2; j++) + { + int hi = 0; + if (loclines.Get(i).I(j) >= 1 && + loclines.Get(i).I(j) <= pindex.Size()) + hi = adfront->GetGlobalIndex (pindex.Get(loclines.Get(i).I(j))); + + (*testout) << hi << " "; + } + (*testout) << " : " + << plainpoints.Get(loclines.Get(i).I1()) << " - " + << plainpoints.Get(loclines.Get(i).I2()) << " 3d: " + << locpoints.Get(loclines.Get(i).I1()) << " - " + << locpoints.Get(loclines.Get(i).I2()) + << endl; + } + + + + glrender(1); + } + } + else + { + adfront -> IncrementClass (lindex.Get(1)); + + if ( debugparam.haltnosuccess || debugflag ) + { + cout << "Problem with seg " << gpi1 << " - " << gpi2 + << ", class = " << qualclass << endl; + + (*testout) << "Problem with seg " << gpi1 << " - " << gpi2 + << ", class = " << qualclass << endl; + + multithread.drawing = 1; + multithread.testmode = 1; + multithread.pause = 1; + + + /* + extern STLGeometry * stlgeometry; + stlgeometry->ClearMarkedSegs(); + for (i = 1; i <= loclines.Size(); i++) + { + stlgeometry->AddMarkedSeg(locpoints.Get(loclines.Get(i).I1()), + locpoints.Get(loclines.Get(i).I2())); + } + */ + + for (int i = 1; i <= loclines.Size(); i++) + { + (*testout) << "line "; + for (int j = 1; j <= 2; j++) + { + int hi = 0; + if (loclines.Get(i).I(j) >= 1 && + loclines.Get(i).I(j) <= pindex.Size()) + hi = adfront->GetGlobalIndex (pindex.Get(loclines.Get(i).I(j))); + + (*testout) << hi << " "; + } + (*testout) << " : " + << plainpoints.Get(loclines.Get(i).I1()) << " - " + << plainpoints.Get(loclines.Get(i).I2()) << " 3d: " + << locpoints.Get(loclines.Get(i).I1()) << " - " + << locpoints.Get(loclines.Get(i).I2()) + << endl; + } + + + /* + cout << "p1gi = " << blgeominfo[0].trignum + << ", p2gi = " << blgeominfo[1].trignum << endl; + */ + + glrender(1); + } + + +#ifdef MYGRAPH + if (silentflag<3) + { + if (testmode || trials%2 == 0) + { + plotsurf.DrawPnL(locpoints, loclines); + plotsurf.Plot(testmode, testmode); + } + } +#endif + } + + } + + PrintMessage (3, "Surface meshing done"); + + + adfront->PrintOpenSegments (*testout); + + multithread.task = savetask; + + + EndMesh (); + + + if (!adfront->Empty()) + return MESHING2_GIVEUP; + + return MESHING2_OK; + } + + + + + + + + + +} + + + + + + +// #define OPENGL +#ifdef OPENGLxx + +/* *********************** Draw Surface Meshing **************** */ + + +#include +#include + +namespace netgen +{ + + extern STLGeometry * stlgeometry; + extern Mesh * mesh; + VisualSceneSurfaceMeshing vssurfacemeshing; + + + + void glrender (int wait) + { + // cout << "plot adfront" << endl; + + if (multithread.drawing) + { + // vssurfacemeshing.Render(); + Render (); + + if (wait || multithread.testmode) + { + multithread.pause = 1; + } + while (multithread.pause); + } + } + + + + VisualSceneSurfaceMeshing :: VisualSceneSurfaceMeshing () + : VisualScene() + { + ; + } + + VisualSceneSurfaceMeshing :: ~VisualSceneSurfaceMeshing () + { + ; + } + + void VisualSceneSurfaceMeshing :: DrawScene () + { + int i, j, k; + + if (loclines.Size() != changeval) + { + center = Point<3>(0,0,-5); + rad = 0.1; + + CalcTransformationMatrices(); + changeval = loclines.Size(); + } + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SetLight(); + + // glEnable (GL_COLOR_MATERIAL); + + // glDisable (GL_SHADING); + // glColor3f (0.0f, 1.0f, 1.0f); + // glLineWidth (1.0f); + // glShadeModel (GL_SMOOTH); + + // glCallList (linelists.Get(1)); + + // SetLight(); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + glShadeModel (GL_SMOOTH); + // glDisable (GL_COLOR_MATERIAL); + glEnable (GL_COLOR_MATERIAL); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // glEnable (GL_LIGHTING); + + double shine = vispar.shininess; + double transp = vispar.transp; + + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); + glLogicOp (GL_COPY); + + + + /* + + float mat_col[] = { 0.2, 0.2, 0.8, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + float mat_colbl[] = { 0.8, 0.2, 0.2, 1 }; + float mat_cololdl[] = { 0.2, 0.8, 0.2, 1 }; + float mat_colnewl[] = { 0.8, 0.8, 0.2, 1 }; + + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glPolygonOffset (1, -1); + glLineWidth (3); + + for (i = 1; i <= loclines.Size(); i++) + { + if (i == 1) + { + glEnable (GL_POLYGON_OFFSET_FILL); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbl); + } + else if (i <= oldnl) + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_cololdl); + else + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colnewl); + + int pi1 = loclines.Get(i).I1(); + int pi2 = loclines.Get(i).I2(); + + if (pi1 >= 1 && pi2 >= 1) + { + Point3d p1 = locpoints.Get(pi1); + Point3d p2 = locpoints.Get(pi2); + + glBegin (GL_LINES); + glVertex3f (p1.X(), p1.Y(), p1.Z()); + glVertex3f (p2.X(), p2.Y(), p2.Z()); + glEnd(); + } + + glDisable (GL_POLYGON_OFFSET_FILL); + } + + + glLineWidth (1); + + + glPointSize (5); + float mat_colp[] = { 1, 0, 0, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); + glBegin (GL_POINTS); + for (i = 1; i <= locpoints.Size(); i++) + { + Point3d p = locpoints.Get(i); + glVertex3f (p.X(), p.Y(), p.Z()); + } + glEnd(); + + + glPopMatrix(); + */ + + float mat_colp[] = { 1, 0, 0, 1 }; + + float mat_col2d1[] = { 1, 0.5, 0.5, 1 }; + float mat_col2d[] = { 1, 1, 1, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); + + double scalex = 0.1, scaley = 0.1; + + glBegin (GL_LINES); + for (i = 1; i <= loclines.Size(); i++) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); + if (i == 1) + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d1); + + int pi1 = loclines.Get(i).I1(); + int pi2 = loclines.Get(i).I2(); + + if (pi1 >= 1 && pi2 >= 1) + { + Point2d p1 = plainpoints.Get(pi1); + Point2d p2 = plainpoints.Get(pi2); + + glBegin (GL_LINES); + glVertex3f (scalex * p1.X(), scaley * p1.Y(), -5); + glVertex3f (scalex * p2.X(), scaley * p2.Y(), -5); + glEnd(); + } + } + glEnd (); + + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); + glBegin (GL_POINTS); + for (i = 1; i <= plainpoints.Size(); i++) + { + Point2d p = plainpoints.Get(i); + glVertex3f (scalex * p.X(), scaley * p.Y(), -5); + } + glEnd(); + + + + + + + glDisable (GL_POLYGON_OFFSET_FILL); + + glPopMatrix(); + DrawCoordinateCross (); + DrawNetgenLogo (); + glFinish(); + + /* + glDisable (GL_POLYGON_OFFSET_FILL); + + // cout << "draw surfacemeshing" << endl; + // + // if (changeval != stlgeometry->GetNT()) + // BuildScene(); + // changeval = stlgeometry->GetNT(); + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + SetLight(); + + glPushMatrix(); + glLoadMatrixf (transmat); + glMultMatrixf (rotmat); + + glShadeModel (GL_SMOOTH); + glDisable (GL_COLOR_MATERIAL); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + float mat_spec_col[] = { 1, 1, 1, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); + + double shine = vispar.shininess; + double transp = vispar.transp; + + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); + glLogicOp (GL_COPY); + + + float mat_col[] = { 0.2, 0.2, 0.8, transp }; + float mat_colrt[] = { 0.2, 0.8, 0.8, transp }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glColor3f (1.0f, 1.0f, 1.0f); + + glEnable (GL_NORMALIZE); + + // glBegin (GL_TRIANGLES); + // for (j = 1; j <= stlgeometry -> GetNT(); j++) + // { + // glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + // if (j == geomtrig) + // glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colrt); + + + // const STLReadTriangle & tria = stlgeometry -> GetReadTriangle(j); + // glNormal3f (tria.normal.X(), + // tria.normal.Y(), + // tria.normal.Z()); + + // for (k = 0; k < 3; k++) + // { + // glVertex3f (tria.pts[k].X(), + // tria.pts[k].Y(), + // tria.pts[k].Z()); + // } + // } + // glEnd (); + + + + glDisable (GL_POLYGON_OFFSET_FILL); + + float mat_colbl[] = { 0.8, 0.2, 0.2, 1 }; + float mat_cololdl[] = { 0.2, 0.8, 0.2, 1 }; + float mat_colnewl[] = { 0.8, 0.8, 0.2, 1 }; + + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glPolygonOffset (1, -1); + glLineWidth (3); + + for (i = 1; i <= loclines.Size(); i++) + { + if (i == 1) + { + glEnable (GL_POLYGON_OFFSET_FILL); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbl); + } + else if (i <= oldnl) + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_cololdl); + else + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colnewl); + + int pi1 = loclines.Get(i).I1(); + int pi2 = loclines.Get(i).I2(); + + if (pi1 >= 1 && pi2 >= 1) + { + Point3d p1 = locpoints.Get(pi1); + Point3d p2 = locpoints.Get(pi2); + + glBegin (GL_LINES); + glVertex3f (p1.X(), p1.Y(), p1.Z()); + glVertex3f (p2.X(), p2.Y(), p2.Z()); + glEnd(); + } + + glDisable (GL_POLYGON_OFFSET_FILL); + } + + + glLineWidth (1); + + + glPointSize (5); + float mat_colp[] = { 1, 0, 0, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); + glBegin (GL_POINTS); + for (i = 1; i <= locpoints.Size(); i++) + { + Point3d p = locpoints.Get(i); + glVertex3f (p.X(), p.Y(), p.Z()); + } + glEnd(); + + + glPopMatrix(); + + + float mat_col2d1[] = { 1, 0.5, 0.5, 1 }; + float mat_col2d[] = { 1, 1, 1, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); + + double scalex = 0.1, scaley = 0.1; + + glBegin (GL_LINES); + for (i = 1; i <= loclines.Size(); i++) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d); + if (i == 1) + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col2d1); + + int pi1 = loclines.Get(i).I1(); + int pi2 = loclines.Get(i).I2(); + + if (pi1 >= 1 && pi2 >= 1) + { + Point2d p1 = plainpoints.Get(pi1); + Point2d p2 = plainpoints.Get(pi2); + + glBegin (GL_LINES); + glVertex3f (scalex * p1.X(), scaley * p1.Y(), -5); + glVertex3f (scalex * p2.X(), scaley * p2.Y(), -5); + glEnd(); + } + } + glEnd (); + + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colp); + glBegin (GL_POINTS); + for (i = 1; i <= plainpoints.Size(); i++) + { + Point2d p = plainpoints.Get(i); + glVertex3f (scalex * p.X(), scaley * p.Y(), -5); + } + glEnd(); + + glFinish(); +*/ + } + + + void VisualSceneSurfaceMeshing :: BuildScene (int zoomall) + { + int i, j, k; + /* + center = stlgeometry -> GetBoundingBox().Center(); + rad = stlgeometry -> GetBoundingBox().Diam() / 2; + + CalcTransformationMatrices(); + */ + } + +} + + +#else +namespace netgen +{ + void glrender (int wait) + { ; } +} +#endif diff --git a/libsrc/meshing/meshing2.hpp b/libsrc/meshing/meshing2.hpp new file mode 100644 index 00000000..4e145964 --- /dev/null +++ b/libsrc/meshing/meshing2.hpp @@ -0,0 +1,164 @@ +#ifndef FILE_MESHING2 +#define FILE_MESHING2 + +/**************************************************************************/ +/* File: meshing2.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Okt. 95 */ +/**************************************************************************/ + + + +enum MESHING2_RESULT +{ + MESHING2_OK = 0, + MESHING2_GIVEUP = 1 +}; + + +/* + +The basis class for 2D mesh generation. +Has the method GenerateMesh + +For surface mesh generation, or non-Euklidean meshing, +derive from Meshing2, and replace transformation. + +*/ + +class Meshing2 +{ + /// the current advancing front + AdFront2 * adfront; + /// rules for mesh generation + Array rules; + /// statistics + Array ruleused, canuse, foundmap; + /// + Box<3> boundingbox; + /// + double starttime; + /// + double maxarea; + + Vec3d ex, ey; + Point3d globp1; + +public: + /// + DLL_HEADER Meshing2 (const MeshingParameters & mp, const Box<3> & aboundingbox); + + /// + DLL_HEADER virtual ~Meshing2 (); + + /// Load rules, either from file, or compiled rules + void LoadRules (const char * filename, bool quad); + + /// + DLL_HEADER MESHING2_RESULT GenerateMesh (Mesh & mesh, const MeshingParameters & mp, double gh, int facenr); + + DLL_HEADER void Delaunay (Mesh & mesh, int domainnr, const MeshingParameters & mp); + DLL_HEADER void BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp); + + + /// + DLL_HEADER void AddPoint (const Point3d & p, PointIndex globind, MultiPointGeomInfo * mgi = NULL, + bool pointonsurface = true); + + /// + DLL_HEADER void AddBoundaryElement (INDEX i1, INDEX i2, + const PointGeomInfo & gi1, const PointGeomInfo & gi2); + + /// + void SetStartTime (double astarttime); + + /// + void SetMaxArea (double amaxarea); + +protected: + /// + virtual void StartMesh (); + /// + virtual void EndMesh (); + /// + virtual double CalcLocalH (const Point3d & p, double gh) const; + + /// + virtual void DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo1, + const PointGeomInfo * geominfo2); + /// + virtual void TransformToPlain (const Point3d & locpoint, const MultiPointGeomInfo & geominfo, + Point2d & plainpoint, double h, int & zone); + /// return 0 .. ok + /// return >0 .. cannot transform point to true surface + virtual int TransformFromPlain (Point2d & plainpoint, + Point3d & locpoint, + PointGeomInfo & geominfo, + double h); + + /// projects to surface + /// return 0 .. ok + virtual int BelongsToActiveChart (const Point3d & p, + const PointGeomInfo & gi); + + /// computes geoinfo data for line with respect to + /// selected chart + virtual int ComputePointGeomInfo (const Point3d & p, + PointGeomInfo & gi); + + /// Tries to select unique geominfo on active chart + /// return 0: success + /// return 1: failed + virtual int ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, + PointGeomInfo & pgi); + + + + /* + tests, whether endpoint (= 1 or 2) of line segment p1-p2 + is inside of the selected chart. The endpoint must be on the + chart + */ + virtual int IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, + int endpoint, const PointGeomInfo & geominfo); + + /* + get (projected) boundary of current chart + */ + virtual void GetChartBoundary (Array & points, + Array & points3d, + Array & lines, double p) const; + + virtual double Area () const; + + +/** Applies 2D rules. + Tests all 2D rules */ + int ApplyRules (Array & lpoints, + Array & legalpoints, + int maxlegalpoint, + Array & llines, + int maxlegelline, + Array & elements, Array & dellines, + int tolerance, + const MeshingParameters & mp); + + +}; + + + + + + + + +#endif + + + + + + + diff --git a/libsrc/meshing/meshing3.cpp b/libsrc/meshing/meshing3.cpp new file mode 100644 index 00000000..58562d2b --- /dev/null +++ b/libsrc/meshing/meshing3.cpp @@ -0,0 +1,1264 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + +double minother; +double minwithoutother; + + + + + +MeshingStat3d :: MeshingStat3d () +{ + cntsucc = cnttrials = cntelem = qualclass = 0; + vol0 = h = 1; + problemindex = 1; +} + + +Meshing3 :: Meshing3 (const string & rulefilename) +{ + tolfak = 1; + + LoadRules (rulefilename.c_str(), NULL); + adfront = new AdFront3; + + problems.SetSize (rules.Size()); + foundmap.SetSize (rules.Size()); + canuse.SetSize (rules.Size()); + ruleused.SetSize (rules.Size()); + + for (int i = 1; i <= rules.Size(); i++) + { + problems.Elem(i) = new char[255]; + foundmap.Elem(i) = 0; + canuse.Elem(i) = 0; + ruleused.Elem(i) = 0; + } +} + + +Meshing3 :: Meshing3 (const char ** rulep) +{ + tolfak = 1; + + LoadRules (NULL, rulep); + adfront = new AdFront3; + + problems.SetSize (rules.Size()); + foundmap.SetSize (rules.Size()); + canuse.SetSize (rules.Size()); + ruleused.SetSize (rules.Size()); + + for (int i = 0; i < rules.Size(); i++) + { + problems[i] = new char[255]; + foundmap[i] = 0; + canuse[i] = 0; + ruleused[i] = 0; + } +} + +Meshing3 :: ~Meshing3 () +{ + delete adfront; + for (int i = 0; i < rules.Size(); i++) + { + delete [] problems[i]; + delete rules[i]; + } +} + + + +static double CalcLocH (const Array & locpoints, + const Array & locfaces, + double h) +{ + return h; + + // was war das ???? + + int i, j; + double hi, h1, d, dn, sum, weight, wi; + Point3d p0, pc; + Vec3d n, v1, v2; + + p0.X() = p0.Y() = p0.Z() = 0; + for (j = 1; j <= 3; j++) + { + p0.X() += locpoints.Get(locfaces.Get(1).PNum(j)).X(); + p0.Y() += locpoints.Get(locfaces.Get(1).PNum(j)).Y(); + p0.Z() += locpoints.Get(locfaces.Get(1).PNum(j)).Z(); + } + p0.X() /= 3; p0.Y() /= 3; p0.Z() /= 3; + + v1 = locpoints.Get(locfaces.Get(1).PNum(2)) - + locpoints.Get(locfaces.Get(1).PNum(1)); + v2 = locpoints.Get(locfaces.Get(1).PNum(3)) - + locpoints.Get(locfaces.Get(1).PNum(1)); + + h1 = v1.Length(); + n = Cross (v2, v1); + n /= n.Length(); + + sum = 0; + weight = 0; + + for (i = 1; i <= locfaces.Size(); i++) + { + pc.X() = pc.Y() = pc.Z() = 0; + for (j = 1; j <= 3; j++) + { + pc.X() += locpoints.Get(locfaces.Get(i).PNum(j)).X(); + pc.Y() += locpoints.Get(locfaces.Get(i).PNum(j)).Y(); + pc.Z() += locpoints.Get(locfaces.Get(i).PNum(j)).Z(); + } + pc.X() /= 3; pc.Y() /= 3; pc.Z() /= 3; + + d = Dist (p0, pc); + dn = n * (pc - p0); + hi = Dist (locpoints.Get(locfaces.Get(i).PNum(1)), + locpoints.Get(locfaces.Get(i).PNum(2))); + + if (dn > -0.2 * h1) + { + wi = 1 / (h1 + d); + wi *= wi; + } + else + wi = 0; + + sum += hi * wi; + weight += wi; + } + + return sum/weight; +} + + +PointIndex Meshing3 :: AddPoint (const Point3d & p, PointIndex globind) +{ + return adfront -> AddPoint (p, globind); +} + +void Meshing3 :: AddBoundaryElement (const Element2d & elem) +{ + MiniElement2d mini(elem.GetNP()); + for (int j = 0; j < elem.GetNP(); j++) + mini[j] = elem[j]; + adfront -> AddFace(mini); +} + + +void Meshing3 :: AddBoundaryElement (const MiniElement2d & elem) +{ + adfront -> AddFace(elem); +} + +int Meshing3 :: AddConnectedPair (const INDEX_2 & apair) +{ + return adfront -> AddConnectedPair (apair); +} + +MESHING3_RESULT Meshing3 :: +GenerateMesh (Mesh & mesh, const MeshingParameters & mp) +{ + static int meshing3_timer = NgProfiler::CreateTimer ("Meshing3::GenerateMesh"); + static int meshing3_timer_a = NgProfiler::CreateTimer ("Meshing3::GenerateMesh a"); + static int meshing3_timer_b = NgProfiler::CreateTimer ("Meshing3::GenerateMesh b"); + static int meshing3_timer_c = NgProfiler::CreateTimer ("Meshing3::GenerateMesh c"); + static int meshing3_timer_d = NgProfiler::CreateTimer ("Meshing3::GenerateMesh d"); + NgProfiler::RegionTimer reg (meshing3_timer); + + + Array locpoints; // local points + Array locfaces; // local faces + Array pindex; // mapping from local to front point numbering + Array allowpoint; // point is allowd ? + Array findex; // mapping from local to front face numbering + //INDEX_2_HASHTABLE connectedpairs(100); // connecgted pairs for prism meshing + + Array plainpoints; // points in reference coordinates + Array delpoints, delfaces; // points and lines to be deleted + Array locelements; // new generated elements + + int i, j, oldnp, oldnf; + int found; + referencetransform trans; + int rotind; + Point3d inp; + float err; + + INDEX locfacesplit; //index for faces in outer area + + bool loktestmode = false; + + int uselocalh = mp.uselocalh; + + // int giveuptol = mp.giveuptol; // + MeshingStat3d stat; // statistics + int plotstat_oldne = -1; + + + // for star-shaped domain meshing + Array grouppoints; + Array groupfaces; + Array grouppindex; + Array groupfindex; + + + float minerr; + int hasfound; + double tetvol; + // int giveup = 0; + + + Array tempnewpoints; + Array tempnewfaces; + Array tempdelfaces; + Array templocelements; + + + stat.h = mp.maxh; + + adfront->SetStartFront (mp.baseelnp); + + + found = 0; + stat.vol0 = adfront -> Volume(); + tetvol = 0; + + stat.qualclass = 1; + + while (1) + { + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + // break if advancing front is empty + if (!mp.baseelnp && adfront->Empty()) + break; + + // break, if advancing front has no elements with + // mp.baseelnp nodes + if (mp.baseelnp && adfront->Empty (mp.baseelnp)) + break; + + locpoints.SetSize(0); + locfaces.SetSize(0); + locelements.SetSize(0); + pindex.SetSize(0); + findex.SetSize(0); + + INDEX_2_HASHTABLE connectedpairs(100); // connected pairs for prism meshing + + // select base-element (will be locface[1]) + // and get local environment of radius (safety * h) + + + int baseelem = adfront -> SelectBaseElement (); + if (mp.baseelnp && adfront->GetFace (baseelem).GetNP() != mp.baseelnp) + { + adfront->IncrementClass (baseelem); + continue; + } + + const MiniElement2d & bel = adfront->GetFace (baseelem); + const Point3d & p1 = adfront->GetPoint (bel.PNum(1)); + const Point3d & p2 = adfront->GetPoint (bel.PNum(2)); + const Point3d & p3 = adfront->GetPoint (bel.PNum(3)); + + // (*testout) << endl << "base = " << bel << endl; + + + Point3d pmid = Center (p1, p2, p3); + + double his = (Dist (p1, p2) + Dist(p1, p3) + Dist(p2, p3)) / 3; + double hshould; + + hshould = mesh.GetH (pmid); + + if (adfront->GetFace (baseelem).GetNP() == 4) + hshould = max2 (his, hshould); + + double hmax = (his > hshould) ? his : hshould; + + // qualclass should come from baseelem !!!!! + double hinner = hmax * (1 + stat.qualclass); + double houter = hmax * (1 + 2 * stat.qualclass); + + NgProfiler::StartTimer (meshing3_timer_a); + stat.qualclass = + adfront -> GetLocals (baseelem, locpoints, locfaces, + pindex, findex, connectedpairs, + houter, hinner, + locfacesplit); + NgProfiler::StopTimer (meshing3_timer_a); + + // (*testout) << "locfaces = " << endl << locfaces << endl; + + int pi1 = pindex.Get(locfaces[0].PNum(1)); + int pi2 = pindex.Get(locfaces[0].PNum(2)); + int pi3 = pindex.Get(locfaces[0].PNum(3)); + + //loktestmode = 1; + testmode = loktestmode; //changed + // loktestmode = testmode = (adfront->GetFace (baseelem).GetNP() == 4) && (rules.Size() == 5); + + loktestmode = stat.qualclass > 5; + + + if (loktestmode) + { + (*testout) << "baseel = " << baseelem << ", ind = " << findex.Get(1) << endl; + (*testout) << "pi = " << pi1 << ", " << pi2 << ", " << pi3 << endl; + } + + + + + + if (testmode) + { + (*testout) << "baseelem = " << baseelem << " qualclass = " << stat.qualclass << endl; + (*testout) << "locpoints = " << endl << locpoints << endl; + (*testout) << "connected = " << endl << connectedpairs << endl; + } + + + + // loch = CalcLocH (locpoints, locfaces, h); + + stat.nff = adfront->GetNF(); + stat.vol = adfront->Volume(); + if (stat.vol < 0) break; + + oldnp = locpoints.Size(); + oldnf = locfaces.Size(); + + + allowpoint.SetSize(locpoints.Size()); + if (uselocalh && stat.qualclass <= 3) + for (i = 1; i <= allowpoint.Size(); i++) + { + allowpoint.Elem(i) = + (mesh.GetH (locpoints.Get(i)) > 0.4 * hshould / mp.sloppy) ? 2 : 1; + } + else + allowpoint = 2; + + + + if (stat.qualclass >= mp.starshapeclass && + mp.baseelnp != 4) + { + NgProfiler::RegionTimer reg1 (meshing3_timer_b); + // star-shaped domain removing + + grouppoints.SetSize (0); + groupfaces.SetSize (0); + grouppindex.SetSize (0); + groupfindex.SetSize (0); + + adfront -> GetGroup (findex[0], grouppoints, groupfaces, + grouppindex, groupfindex); + + bool onlytri = 1; + for (i = 0; i < groupfaces.Size(); i++) + if (groupfaces[i].GetNP() != 3) + onlytri = 0; + + if (onlytri && groupfaces.Size() <= 20 + 2*stat.qualclass && + FindInnerPoint (grouppoints, groupfaces, inp)) + { + (*testout) << "inner point found" << endl; + + for (i = 1; i <= groupfaces.Size(); i++) + adfront -> DeleteFace (groupfindex.Get(i)); + + for (i = 1; i <= groupfaces.Size(); i++) + for (j = 1; j <= locfaces.Size(); j++) + if (findex.Get(j) == groupfindex.Get(i)) + delfaces.Append (j); + + + delfaces.SetSize (0); + + INDEX npi; + Element newel; + + npi = mesh.AddPoint (inp); + newel.SetNP(4); + newel.PNum(4) = npi; + + for (i = 1; i <= groupfaces.Size(); i++) + { + for (j = 1; j <= 3; j++) + { + newel.PNum(j) = + adfront->GetGlobalIndex + (grouppindex.Get(groupfaces.Get(i).PNum(j))); + } + mesh.AddVolumeElement (newel); + } + continue; + } + } + + found = 0; + hasfound = 0; + minerr = 1e6; + + // int optother = 0; + + /* + for (i = 1; i <= locfaces.Size(); i++) + { + (*testout) << "Face " << i << ": "; + for (j = 1; j <= locfaces.Get(i).GetNP(); j++) + (*testout) << pindex.Get(locfaces.Get(i).PNum(j)) << " "; + (*testout) << endl; + } + for (i = 1; i <= locpoints.Size(); i++) + { + (*testout) << "p" << i + << ", gi = " << pindex.Get(i) + << " = " << locpoints.Get(i) << endl; + } + */ + + minother = 1e10; + minwithoutother = 1e10; + + bool impossible = 1; + + for (rotind = 1; rotind <= locfaces[0].GetNP(); rotind++) + { + // set transformatino to reference coordinates + + if (locfaces.Get(1).GetNP() == 3) + { + trans.Set (locpoints.Get(locfaces.Get(1).PNumMod(1+rotind)), + locpoints.Get(locfaces.Get(1).PNumMod(2+rotind)), + locpoints.Get(locfaces.Get(1).PNumMod(3+rotind)), hshould); + } + else + { + trans.Set (locpoints.Get(locfaces.Get(1).PNumMod(1+rotind)), + locpoints.Get(locfaces.Get(1).PNumMod(2+rotind)), + locpoints.Get(locfaces.Get(1).PNumMod(4+rotind)), hshould); + } + + trans.ToPlain (locpoints, plainpoints); + + + for (i = 1; i <= allowpoint.Size(); i++) + { + if (plainpoints.Get(i).Z() > 0) + { + //if(loktestmode) + // (*testout) << "plainpoints.Get(i).Z() = " << plainpoints.Get(i).Z() << " > 0" << endl; + allowpoint.Elem(i) = 0; + } + } + + stat.cnttrials++; + + + if (stat.cnttrials % 100 == 0) + { + (*testout) << "\n"; + for (i = 1; i <= canuse.Size(); i++) + { + (*testout) << foundmap.Get(i) << "/" + << canuse.Get(i) << "/" + << ruleused.Get(i) << " map/can/use rule " << rules.Get(i)->Name() << "\n"; + } + (*testout) << endl; + } + + NgProfiler::StartTimer (meshing3_timer_c); + + found = ApplyRules (plainpoints, allowpoint, + locfaces, locfacesplit, connectedpairs, + locelements, delfaces, + stat.qualclass, mp.sloppy, rotind, err); + + if (found >= 0) impossible = 0; + if (found < 0) found = 0; + + + NgProfiler::StopTimer (meshing3_timer_c); + + if (!found) loktestmode = 0; + + NgProfiler::RegionTimer reg2 (meshing3_timer_d); + + if (loktestmode) + { + (*testout) << "plainpoints = " << endl << plainpoints << endl; + (*testout) << "Applyrules found " << found << endl; + } + + if (found) stat.cntsucc++; + + locpoints.SetSize (plainpoints.Size()); + for (i = oldnp+1; i <= plainpoints.Size(); i++) + trans.FromPlain (plainpoints.Elem(i), locpoints.Elem(i)); + + + + // avoid meshing from large to small mesh-size + if (uselocalh && found && stat.qualclass <= 3) + { + for (i = 1; i <= locelements.Size(); i++) + { + Point3d pmin = locpoints.Get(locelements.Get(i).PNum(1)); + Point3d pmax = pmin; + for (j = 2; j <= 4; j++) + { + const Point3d & hp = locpoints.Get(locelements.Get(i).PNum(j)); + pmin.SetToMin (hp); + pmax.SetToMax (hp); + } + + if (mesh.GetMinH (pmin, pmax) < 0.4 * hshould / mp.sloppy) + found = 0; + } + } + if (found) + { + for (i = 1; i <= locelements.Size(); i++) + for (j = 1; j <= 4; j++) + { + const Point3d & hp = locpoints.Get(locelements.Get(i).PNum(j)); + if (Dist (hp, pmid) > hinner) + found = 0; + } + } + + + if (found) + ruleused.Elem(found)++; + + + // plotstat->Plot(stat); + + if (stat.cntelem != plotstat_oldne) + { + plotstat_oldne = stat.cntelem; + + PrintMessageCR (5, "El: ", stat.cntelem, + // << " trials: " << stat.cnttrials + " faces: ", stat.nff, + " vol = ", float(100 * stat.vol / stat.vol0)); + + multithread.percent = 100 - 100.0 * stat.vol / stat.vol0; + } + + + if (found && (!hasfound || err < minerr) ) + { + + if (testmode) + { + (*testout) << "found is active, 3" << endl; + for (i = 1; i <= plainpoints.Size(); i++) + { + (*testout) << "p"; + if (i <= pindex.Size()) + (*testout) << pindex.Get(i) << ": "; + else + (*testout) << "new: "; + (*testout) << plainpoints.Get(i) << endl; + } + } + + + + hasfound = found; + minerr = err; + + tempnewpoints.SetSize (0); + for (i = oldnp+1; i <= locpoints.Size(); i++) + tempnewpoints.Append (locpoints.Get(i)); + + tempnewfaces.SetSize (0); + for (i = oldnf+1; i <= locfaces.Size(); i++) + tempnewfaces.Append (locfaces.Get(i)); + + tempdelfaces.SetSize (0); + for (i = 1; i <= delfaces.Size(); i++) + tempdelfaces.Append (delfaces.Get(i)); + + templocelements.SetSize (0); + for (i = 1; i <= locelements.Size(); i++) + templocelements.Append (locelements.Get(i)); + + /* + optother = + strcmp (problems[found], "other") == 0; + */ + } + + locpoints.SetSize (oldnp); + locfaces.SetSize (oldnf); + delfaces.SetSize (0); + locelements.SetSize (0); + } + + + + if (hasfound) + { + + /* + if (optother) + (*testout) << "Other is optimal" << endl; + + if (minother < minwithoutother) + { + (*testout) << "Other is better, " << minother << " less " << minwithoutother << endl; + } + */ + + for (i = 1; i <= tempnewpoints.Size(); i++) + locpoints.Append (tempnewpoints.Get(i)); + for (i = 1; i <= tempnewfaces.Size(); i++) + locfaces.Append (tempnewfaces.Get(i)); + for (i = 1; i <= tempdelfaces.Size(); i++) + delfaces.Append (tempdelfaces.Get(i)); + for (i = 1; i <= templocelements.Size(); i++) + locelements.Append (templocelements.Get(i)); + + + if (loktestmode) + { + (*testout) << "apply rule" << endl; + for (i = 1; i <= locpoints.Size(); i++) + { + (*testout) << "p"; + if (i <= pindex.Size()) + (*testout) << pindex.Get(i) << ": "; + else + (*testout) << "new: "; + (*testout) << locpoints.Get(i) << endl; + } + } + + + + pindex.SetSize(locpoints.Size()); + + for (i = oldnp+1; i <= locpoints.Size(); i++) + { + PointIndex globind = mesh.AddPoint (locpoints.Get(i)); + pindex.Elem(i) = adfront -> AddPoint (locpoints.Get(i), globind); + } + + for (i = 1; i <= locelements.Size(); i++) + { + Point3d * hp1, * hp2, * hp3, * hp4; + hp1 = &locpoints.Elem(locelements.Get(i).PNum(1)); + hp2 = &locpoints.Elem(locelements.Get(i).PNum(2)); + hp3 = &locpoints.Elem(locelements.Get(i).PNum(3)); + hp4 = &locpoints.Elem(locelements.Get(i).PNum(4)); + + tetvol += (1.0 / 6.0) * ( Cross ( *hp2 - *hp1, *hp3 - *hp1) * (*hp4 - *hp1) ); + + for (j = 1; j <= locelements.Get(i).NP(); j++) + locelements.Elem(i).PNum(j) = + adfront -> GetGlobalIndex (pindex.Get(locelements.Get(i).PNum(j))); + + mesh.AddVolumeElement (locelements.Get(i)); + stat.cntelem++; + } + + for (i = oldnf+1; i <= locfaces.Size(); i++) + { + for (j = 1; j <= locfaces.Get(i).GetNP(); j++) + locfaces.Elem(i).PNum(j) = + pindex.Get(locfaces.Get(i).PNum(j)); + // (*testout) << "add face " << locfaces.Get(i) << endl; + adfront->AddFace (locfaces.Get(i)); + } + + for (i = 1; i <= delfaces.Size(); i++) + adfront->DeleteFace (findex.Get(delfaces.Get(i))); + } + else + { + adfront->IncrementClass (findex.Get(1)); + if (impossible && mp.check_impossible) + { + (*testout) << "skip face since it is impossible" << endl; + for (j = 0; j < 100; j++) + adfront->IncrementClass (findex.Get(1)); + } + } + + locelements.SetSize (0); + delpoints.SetSize(0); + delfaces.SetSize(0); + + if (stat.qualclass >= mp.giveuptol) + break; + } + + PrintMessage (5, ""); // line feed after statistics + + for (i = 1; i <= ruleused.Size(); i++) + (*testout) << setw(4) << ruleused.Get(i) + << " times used rule " << rules.Get(i) -> Name() << endl; + + + if (!mp.baseelnp && adfront->Empty()) + return MESHING3_OK; + + if (mp.baseelnp && adfront->Empty (mp.baseelnp)) + return MESHING3_OK; + + if (stat.vol < -1e-15) + return MESHING3_NEGVOL; + + return MESHING3_NEGVOL; +} + + + + +enum blocktyp { BLOCKUNDEF, BLOCKINNER, BLOCKBOUND, BLOCKOUTER }; + +void Meshing3 :: BlockFill (Mesh & mesh, double gh) +{ + PrintMessage (3, "Block-filling called (obsolete) "); + + int i, j(0), i1, i2, i3, j1, j2, j3; + int n1, n2, n3, n, min1, min2, min3, max1, max2, max3; + int changed, filled; + double xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0); + double xminb, xmaxb, yminb, ymaxb, zminb, zmaxb; + //double rad = 0.7 * gh; + + for (i = 1; i <= adfront->GetNP(); i++) + { + const Point3d & p = adfront->GetPoint(PointIndex(i)); + if (i == 1) + { + xmin = xmax = p.X(); + ymin = ymax = p.Y(); + zmin = zmax = p.Z(); + } + else + { + if (p.X() < xmin) xmin = p.X(); + if (p.X() > xmax) xmax = p.X(); + if (p.Y() < ymin) ymin = p.Y(); + if (p.Y() > ymax) ymax = p.Y(); + if (p.Z() < zmin) zmin = p.Z(); + if (p.Z() > zmax) zmax = p.Z(); + } + } + + xmin -= 5 * gh; + ymin -= 5 * gh; + zmin -= 5 * gh; + + n1 = int ((xmax-xmin) / gh + 5); + n2 = int ((ymax-ymin) / gh + 5); + n3 = int ((zmax-zmin) / gh + 5); + n = n1 * n2 * n3; + + PrintMessage (5, "n1 = ", n1, " n2 = ", n2, " n3 = ", n3); + + Array inner(n); + Array pointnr(n); + Array frontpointnr(n); + + + // initialize inner to 1 + + for (i = 1; i <= n; i++) + inner.Elem(i) = BLOCKUNDEF; + + + // set blocks cutting surfaces to 0 + + for (i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & el = adfront->GetFace(i); + xminb = xmax; xmaxb = xmin; + yminb = ymax; ymaxb = ymin; + zminb = zmax; zmaxb = zmin; + + for (j = 1; j <= 3; j++) + { + const Point3d & p = adfront->GetPoint (el.PNum(j)); + if (p.X() < xminb) xminb = p.X(); + if (p.X() > xmaxb) xmaxb = p.X(); + if (p.Y() < yminb) yminb = p.Y(); + if (p.Y() > ymaxb) ymaxb = p.Y(); + if (p.Z() < zminb) zminb = p.Z(); + if (p.Z() > zmaxb) zmaxb = p.Z(); + } + + + + double filldist = 0.2; // globflags.GetNumFlag ("filldist", 0.4); + xminb -= filldist * gh; + xmaxb += filldist * gh; + yminb -= filldist * gh; + ymaxb += filldist * gh; + zminb -= filldist * gh; + zmaxb += filldist * gh; + + min1 = int ((xminb - xmin) / gh) + 1; + max1 = int ((xmaxb - xmin) / gh) + 1; + min2 = int ((yminb - ymin) / gh) + 1; + max2 = int ((ymaxb - ymin) / gh) + 1; + min3 = int ((zminb - zmin) / gh) + 1; + max3 = int ((zmaxb - zmin) / gh) + 1; + + + for (i1 = min1; i1 <= max1; i1++) + for (i2 = min2; i2 <= max2; i2++) + for (i3 = min3; i3 <= max3; i3++) + inner.Elem(i3 + (i2-1) * n3 + (i1-1) * n2 * n3) = BLOCKBOUND; + } + + + + + while (1) + { + int undefi = 0; + Point3d undefp; + + for (i1 = 1; i1 <= n1 && !undefi; i1++) + for (i2 = 1; i2 <= n2 && !undefi; i2++) + for (i3 = 1; i3 <= n3 && !undefi; i3++) + { + i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; + if (inner.Elem(i) == BLOCKUNDEF) + { + undefi = i; + undefp.X() = xmin + (i1-0.5) * gh; + undefp.Y() = ymin + (i2-0.5) * gh; + undefp.Z() = zmin + (i3-0.5) * gh; + } + } + + if (!undefi) + break; + + // PrintMessage (5, "Test point: ", undefp); + + if (adfront -> Inside (undefp)) + { + // (*mycout) << "inner" << endl; + inner.Elem(undefi) = BLOCKINNER; + } + else + { + // (*mycout) << "outer" << endl; + inner.Elem(undefi) = BLOCKOUTER; + } + + do + { + changed = 0; + for (i1 = 1; i1 <= n1; i1++) + for (i2 = 1; i2 <= n2; i2++) + for (i3 = 1; i3 <= n3; i3++) + { + i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; + + for (int k = 1; k <= 3; k++) + { + switch (k) + { + case 1: j = i + n2 * n3; break; + case 2: j = i + n3; break; + case 3: j = i + 1; break; + } + + if (j > n1 * n2 * n3) continue; + + if (inner.Elem(i) == BLOCKOUTER && inner.Elem(j) == BLOCKUNDEF) + { + changed = 1; + inner.Elem(j) = BLOCKOUTER; + } + if (inner.Elem(j) == BLOCKOUTER && inner.Elem(i) == BLOCKUNDEF) + { + changed = 1; + inner.Elem(i) = BLOCKOUTER; + } + if (inner.Elem(i) == BLOCKINNER && inner.Elem(j) == BLOCKUNDEF) + { + changed = 1; + inner.Elem(j) = BLOCKINNER; + } + if (inner.Elem(j) == BLOCKINNER && inner.Elem(i) == BLOCKUNDEF) + { + changed = 1; + inner.Elem(i) = BLOCKINNER; + } + } + } + } + while (changed); + + } + + + + filled = 0; + for (i = 1; i <= n; i++) + if (inner.Elem(i) == BLOCKINNER) + { + filled++; + } + PrintMessage (5, "Filled blocks: ", filled); + + for (i = 1; i <= n; i++) + { + pointnr.Elem(i) = 0; + frontpointnr.Elem(i) = 0; + } + + for (i1 = 1; i1 <= n1-1; i1++) + for (i2 = 1; i2 <= n2-1; i2++) + for (i3 = 1; i3 <= n3-1; i3++) + { + i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; + if (inner.Elem(i) == BLOCKINNER) + { + for (j1 = i1; j1 <= i1+1; j1++) + for (j2 = i2; j2 <= i2+1; j2++) + for (j3 = i3; j3 <= i3+1; j3++) + { + j = j3 + (j2-1) * n3 + (j1-1) * n2 * n3; + if (pointnr.Get(j) == 0) + { + Point3d hp(xmin + (j1-1) * gh, + ymin + (j2-1) * gh, + zmin + (j3-1) * gh); + pointnr.Elem(j) = mesh.AddPoint (hp); + frontpointnr.Elem(j) = + AddPoint (hp, pointnr.Elem(j)); + + } + } + } + } + + + for (i1 = 2; i1 <= n1-1; i1++) + for (i2 = 2; i2 <= n2-1; i2++) + for (i3 = 2; i3 <= n3-1; i3++) + { + i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; + if (inner.Elem(i) == BLOCKINNER) + { + int pn[9]; + pn[1] = pointnr.Get(i); + pn[2] = pointnr.Get(i+1); + pn[3] = pointnr.Get(i+n3); + pn[4] = pointnr.Get(i+n3+1); + pn[5] = pointnr.Get(i+n2*n3); + pn[6] = pointnr.Get(i+n2*n3+1); + pn[7] = pointnr.Get(i+n2*n3+n3); + pn[8] = pointnr.Get(i+n2*n3+n3+1); + static int elind[][4] = + { + { 1, 8, 2, 4 }, + { 1, 8, 4, 3 }, + { 1, 8, 3, 7 }, + { 1, 8, 7, 5 }, + { 1, 8, 5, 6 }, + { 1, 8, 6, 2 } + }; + for (j = 1; j <= 6; j++) + { + Element el(4); + for (int k = 1; k <= 4; k++) + el.PNum(k) = pn[elind[j-1][k-1]]; + + mesh.AddVolumeElement (el); + } + } + } + + + + for (i1 = 2; i1 <= n1-1; i1++) + for (i2 = 2; i2 <= n2-1; i2++) + for (i3 = 2; i3 <= n3-1; i3++) + { + i = i3 + (i2-1) * n3 + (i1-1) * n2 * n3; + if (inner.Elem(i) == BLOCKINNER) + { + int pi1(0), pi2(0), pi3(0), pi4(0); + + int pn1 = frontpointnr.Get(i); + int pn2 = frontpointnr.Get(i+1); + int pn3 = frontpointnr.Get(i+n3); + int pn4 = frontpointnr.Get(i+n3+1); + int pn5 = frontpointnr.Get(i+n2*n3); + int pn6 = frontpointnr.Get(i+n2*n3+1); + int pn7 = frontpointnr.Get(i+n2*n3+n3); + int pn8 = frontpointnr.Get(i+n2*n3+n3+1); + + for (int k = 1; k <= 6; k++) + { + switch (k) + { + case 1: // j3 = i3+1 + j = i + 1; + pi1 = pn2; + pi2 = pn6; + pi3 = pn4; + pi4 = pn8; + break; + case 2: // j3 = i3-1 + j = i - 1; + pi1 = pn1; + pi2 = pn3; + pi3 = pn5; + pi4 = pn7; + break; + case 3: // j2 = i2+1 + j = i + n3; + pi1 = pn3; + pi2 = pn4; + pi3 = pn7; + pi4 = pn8; + break; + case 4: // j2 = i2-1 + j = i - n3; + pi1 = pn1; + pi2 = pn5; + pi3 = pn2; + pi4 = pn6; + break; + case 5: // j1 = i1+1 + j = i + n3*n2; + pi1 = pn5; + pi2 = pn7; + pi3 = pn6; + pi4 = pn8; + break; + case 6: // j1 = i1-1 + j = i - n3*n2; + pi1 = pn1; + pi2 = pn2; + pi3 = pn3; + pi4 = pn4; + break; + } + + if (inner.Get(j) == BLOCKBOUND) + { + MiniElement2d face; + face.PNum(1) = pi4; + face.PNum(2) = pi1; + face.PNum(3) = pi3; + AddBoundaryElement (face); + + face.PNum(1) = pi1; + face.PNum(2) = pi4; + face.PNum(3) = pi2; + AddBoundaryElement (face); + + } + } + } + } +} + + +/* +static const AdFront3 * locadfront; +static int TestInner (const Point3d & p) +{ + return locadfront->Inside (p); +} +static int TestSameSide (const Point3d & p1, const Point3d & p2) +{ + return locadfront->SameSide (p1, p2); +} +*/ + + + +void Meshing3 :: BlockFillLocalH (Mesh & mesh, + const MeshingParameters & mp) +{ + double filldist = mp.filldist; + + (*testout) << "blockfill local h" << endl; + (*testout) << "rel filldist = " << filldist << endl; + PrintMessage (3, "blockfill local h"); + + + Array > npoints; + + adfront -> CreateTrees(); + + Box<3> bbox ( Box<3>::EMPTY_BOX ); + double maxh = 0; + + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & el = adfront->GetFace(i); + for (int j = 1; j <= 3; j++) + { + const Point3d & p1 = adfront->GetPoint (el.PNumMod(j)); + const Point3d & p2 = adfront->GetPoint (el.PNumMod(j+1)); + + double hi = Dist (p1, p2); + if (hi > maxh) maxh = hi; + + bbox.Add (p1); + } + } + + + Point3d mpmin = bbox.PMin(); + Point3d mpmax = bbox.PMax(); + Point3d mpc = Center (mpmin, mpmax); + double d = max3(mpmax.X()-mpmin.X(), + mpmax.Y()-mpmin.Y(), + mpmax.Z()-mpmin.Z()) / 2; + mpmin = mpc - Vec3d (d, d, d); + mpmax = mpc + Vec3d (d, d, d); + Box3d meshbox (mpmin, mpmax); + + LocalH loch2 (mpmin, mpmax, 1); + + if (mp.maxh < maxh) maxh = mp.maxh; + + bool changed; + do + { + mesh.LocalHFunction().ClearFlags(); + + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & el = adfront->GetFace(i); + + Box<3> bbox (adfront->GetPoint (el[0])); + bbox.Add (adfront->GetPoint (el[1])); + bbox.Add (adfront->GetPoint (el[2])); + + + double filld = filldist * bbox.Diam(); + bbox.Increase (filld); + + mesh.LocalHFunction().CutBoundary (bbox); // .PMin(), bbox.PMax()); + } + + // locadfront = adfront; + mesh.LocalHFunction().FindInnerBoxes (adfront, NULL); + + npoints.SetSize(0); + mesh.LocalHFunction().GetInnerPoints (npoints); + + changed = false; + for (int i = 1; i <= npoints.Size(); i++) + { + if (mesh.LocalHFunction().GetH(npoints.Get(i)) > 1.5 * maxh) + { + mesh.LocalHFunction().SetH (npoints.Get(i), maxh); + changed = true; + } + } + } + while (changed); + + if (debugparam.slowchecks) + (*testout) << "Blockfill with points: " << endl; + for (int i = 1; i <= npoints.Size(); i++) + { + if (meshbox.IsIn (npoints.Get(i))) + { + PointIndex gpnum = mesh.AddPoint (npoints.Get(i)); + adfront->AddPoint (npoints.Get(i), gpnum); + + if (debugparam.slowchecks) + { + (*testout) << npoints.Get(i) << endl; + if (!adfront->Inside(npoints.Get(i))) + { + cout << "add outside point" << endl; + (*testout) << "outside" << endl; + } + } + + } + } + + + + // find outer points + + loch2.ClearFlags(); + + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & el = adfront->GetFace(i); + Point3d pmin = adfront->GetPoint (el.PNum(1)); + Point3d pmax = pmin; + + for (int j = 2; j <= 3; j++) + { + const Point3d & p = adfront->GetPoint (el.PNum(j)); + pmin.SetToMin (p); + pmax.SetToMax (p); + } + + loch2.SetH (Center (pmin, pmax), Dist (pmin, pmax)); + } + + for (int i = 1; i <= adfront->GetNF(); i++) + { + const MiniElement2d & el = adfront->GetFace(i); + Point3d pmin = adfront->GetPoint (el.PNum(1)); + Point3d pmax = pmin; + + for (int j = 2; j <= 3; j++) + { + const Point3d & p = adfront->GetPoint (el.PNum(j)); + pmin.SetToMin (p); + pmax.SetToMax (p); + } + + double filld = filldist * Dist (pmin, pmax); + pmin = pmin - Vec3d (filld, filld, filld); + pmax = pmax + Vec3d (filld, filld, filld); + // loch2.CutBoundary (pmin, pmax); + loch2.CutBoundary (Box<3> (pmin, pmax)); // pmin, pmax); + } + + // locadfront = adfront; + loch2.FindInnerBoxes (adfront, NULL); + + npoints.SetSize(0); + loch2.GetOuterPoints (npoints); + + for (int i = 1; i <= npoints.Size(); i++) + { + if (meshbox.IsIn (npoints.Get(i))) + { + PointIndex gpnum = mesh.AddPoint (npoints.Get(i)); + adfront->AddPoint (npoints.Get(i), gpnum); + } + } +} + +} diff --git a/libsrc/meshing/meshing3.hpp b/libsrc/meshing/meshing3.hpp new file mode 100644 index 00000000..84e9ca6b --- /dev/null +++ b/libsrc/meshing/meshing3.hpp @@ -0,0 +1,130 @@ +#ifndef FILE_MESHING3 +#define FILE_MESHING3 + + + + +enum MESHING3_RESULT +{ + MESHING3_OK = 0, + MESHING3_GIVEUP = 1, + MESHING3_NEGVOL = 2, + MESHING3_OUTERSTEPSEXCEEDED = 3, + MESHING3_TERMINATE = 4, + MESHING3_BADSURFACEMESH = 5 +}; + + +/// 3d volume mesh generation +class Meshing3 +{ + /// current state of front + AdFront3 * adfront; + /// 3d generation rules + Array rules; + /// counts how often a rule is used + Array ruleused, canuse, foundmap; + /// describes, why a rule is not applied + Array problems; + /// tolerance criterion + double tolfak; +public: + /// + Meshing3 (const string & rulefilename); + /// + Meshing3 (const char ** rulep); + /// + virtual ~Meshing3 (); + + /// + void LoadRules (const char * filename, const char ** prules); + /// + MESHING3_RESULT GenerateMesh (Mesh & mesh, const MeshingParameters & mp); + + /// + int ApplyRules (Array & lpoints, Array & allowpoint, + Array & lfaces, INDEX lfacesplit, + INDEX_2_HASHTABLE & connectedpairs, + Array & elements, + Array & delfaces, int tolerance, + double sloppy, int rotind1, + float & retminerr); + + /// + PointIndex AddPoint (const Point3d & p, PointIndex globind); + /// + void AddBoundaryElement (const Element2d & elem); + /// + void AddBoundaryElement (const MiniElement2d & elem); + /// + int AddConnectedPair (const INDEX_2 & pair); + + /// + void BlockFill (Mesh & mesh, double gh); + /// + void BlockFillLocalH (Mesh & mesh, const MeshingParameters & mp); + + /// uses points of adfront, and puts new elements into mesh + void Delaunay (Mesh & mesh, int domainnr, const MeshingParameters & mp); + /// + friend class PlotVolMesh; + /// + friend void TestRules (); +}; + + + + +/// status of mesh generation +class MeshingStat3d +{ +public: + /// + MeshingStat3d (); + /// + int cntsucc; + /// + int cnttrials; + /// + int cntelem; + /// + int nff; + /// + int qualclass; + /// + double vol0; + /// + double vol; + /// + double h; + /// + int problemindex; +}; + + + + + +/* +template +extern int FindInnerPoint (POINTArray & grouppoints, + FACEArray & groupfaces, + Point3d & p); + +*/ + + + + + +#endif + + + + + + + + + + diff --git a/libsrc/meshing/meshtool.cpp b/libsrc/meshing/meshtool.cpp new file mode 100644 index 00000000..4a349ac9 --- /dev/null +++ b/libsrc/meshing/meshtool.cpp @@ -0,0 +1,1015 @@ +#include + +#include "meshing.hpp" +#include +#include + +namespace netgen +{ + + int CheckSurfaceMesh (const Mesh & mesh) + { + PrintMessage (3, "Check Surface mesh"); + + int nf = mesh.GetNSE(); + INDEX_2_HASHTABLE edges(nf+2); + int i, j; + INDEX_2 i2; + int cnt1 = 0, cnt2 = 0; + + for (i = 1; i <= nf; i++) + for (j = 1; j <= 3; j++) + { + i2.I1() = mesh.SurfaceElement(i).PNumMod(j); + i2.I2() = mesh.SurfaceElement(i).PNumMod(j+1); + if (edges.Used(i2)) + { + int hi; + hi = edges.Get(i2); + if (hi != 1) + PrintSysError ("CheckSurfaceMesh, hi = ", hi); + edges.Set(i2, 2); + cnt2++; + } + else + { + Swap (i2.I1(), i2.I2()); + edges.Set(i2, 1); + cnt1++; + } + } + + + if (cnt1 != cnt2) + { + PrintUserError ("Surface mesh not consistent"); + // MyBeep(2); + // (*mycout) << "cnt1 = " << cnt1 << " cnt2 = " << cnt2 << endl; + return 0; + } + return 1; + } + + + + int CheckSurfaceMesh2 (const Mesh & mesh) + { + int i, j, k; + const Point<3> *tri1[3], *tri2[3]; + + for (i = 1; i <= mesh.GetNOpenElements(); i++) + { + PrintDot (); + for (j = 1; j < i; j++) + { + for (k = 1; k <= 3; k++) + { + tri1[k-1] = &mesh.Point (mesh.OpenElement(i).PNum(k)); + tri2[k-1] = &mesh.Point (mesh.OpenElement(j).PNum(k)); + } + if (IntersectTriangleTriangle (&tri1[0], &tri2[0])) + { + PrintSysError ("Surface elements are intersecting"); + (*testout) << "Intersecting: " << endl; + for (k = 0; k <= 2; k++) + (*testout) << *tri1[k] << " "; + (*testout) << endl; + for (k = 0; k <= 2; k++) + (*testout) << *tri2[k] << " "; + (*testout) << endl; + } + + } + } + return 0; + } + + + + + + static double TriangleQualityInst (const Point3d & p1, const Point3d & p2, + const Point3d & p3) + { + // quality 0 (worst) .. 1 (optimal) + + Vec3d v1, v2, v3; + double s1, s2, s3; + double an1, an2, an3; + + v1 = p2 - p1; + v2 = p3 - p1; + v3 = p3 - p2; + + an1 = Angle (v1, v2); + v1 *= -1; + an2 = Angle (v1, v3); + an3 = Angle (v2, v3); + + s1 = sin (an1/2); + s2 = sin (an2/2); + s3 = sin (an3/2); + + return 8 * s1 * s2 * s3; + } + + + + + + + + + + + + + + + void MeshQuality2d (const Mesh & mesh) + { + int ncl = 20, cl; + Array incl(ncl); + INDEX i; + SurfaceElementIndex sei; + double qual; + + incl = 0; + + for (sei = 0; sei < mesh.GetNSE(); sei++) + { + qual = TriangleQualityInst (mesh[mesh[sei][0]], + mesh[mesh[sei][1]], + mesh[mesh[sei][2]]); + + cl = int ( (ncl-1e-3) * qual ) + 1; + incl.Elem(cl)++; + } + + (*testout) << endl << endl; + + (*testout) << "Points: " << mesh.GetNP() << endl; + (*testout) << "Surface Elements: " << mesh.GetNSE() << endl; + + (*testout) << endl; + (*testout) << "Elements in qualityclasses:" << endl; + // (*testout).precision(2); + (*testout) << setprecision(2); + for (i = 1; i <= ncl; i++) + { + (*testout) << setw(4) << double (i-1)/ncl << " - " + << setw(4) << double (i) / ncl << ": " + << incl.Get(i) << endl; + } + } + + + static double TetElementQuality (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4) + { + double vol, l, l4, l5, l6; + + + Vec3d v1 = p2 - p1; + Vec3d v2 = p3 - p1; + Vec3d v3 = p4 - p1; + + vol = fabs ((Cross (v1, v2) * v3)) / 6; + l4 = Dist (p2, p3); + l5 = Dist (p2, p4); + l6 = Dist (p3, p4); + + l = v1.Length() + v2.Length() + v3.Length() + l4 + l5 + l6; + + if (vol <= 1e-8 * l * l * l) return 1e-10; + + return vol/(l*l*l) * 1832.82; // 6^4 * sqrt(2) + } + + + + + // static double teterrpow = 2; + + double CalcTetBadness (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, double h, + const MeshingParameters & mp) + { + double vol, l, ll, lll, ll1, ll2, ll3, ll4, ll5, ll6; + double err; + + Vec3d v1 (p1, p2); + Vec3d v2 (p1, p3); + Vec3d v3 (p1, p4); + + vol = Determinant (v1, v2, v3) * (-0.166666666666666); + + ll1 = v1.Length2(); + ll2 = v2.Length2(); + ll3 = v3.Length2(); + ll4 = Dist2 (p2, p3); + ll5 = Dist2 (p2, p4); + ll6 = Dist2 (p3, p4); + + ll = ll1 + ll2 + ll3 + ll4 + ll5 + ll6; + l = sqrt (ll); + lll = l * ll; + + if (vol <= 1e-24 * lll) + return 1e24; + + err = 0.0080187537 * lll / vol; // sqrt(216) / (6^4 * sqrt(2)) + + if (h > 0) + err += ll / (h * h) + + h * h * ( 1 / ll1 + 1 / ll2 + 1 / ll3 + + 1 / ll4 + 1 / ll5 + 1 / ll6 ) - 12; + + double teterrpow = mp.opterrpow; + if(teterrpow < 1) teterrpow = 1; + + if (teterrpow == 1) return err; + if (teterrpow == 2) return err*err; + return pow (err, teterrpow); + } + + + double CalcTetBadnessGrad (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, double h, + int pi, Vec<3> & grad, + const MeshingParameters & mp) + { + double vol, l, ll, lll; + double err; + + const Point3d *pp1, *pp2, *pp3, *pp4; + + pp1 = &p1; + pp2 = &p2; + pp3 = &p3; + pp4 = &p4; + + switch (pi) + { + case 2: + { + swap (pp1, pp2); + swap (pp3, pp4); + break; + } + case 3: + { + swap (pp1, pp3); + swap (pp2, pp4); + break; + } + case 4: + { + swap (pp1, pp4); + swap (pp3, pp2); + break; + } + } + + + Vec3d v1 (*pp1, *pp2); + Vec3d v2 (*pp1, *pp3); + Vec3d v3 (*pp1, *pp4); + + Vec3d v4 (*pp2, *pp3); + Vec3d v5 (*pp2, *pp4); + Vec3d v6 (*pp3, *pp4); + + vol = Determinant (v1, v2, v3) * (-0.166666666666666); + + Vec3d gradvol; + Cross (v5, v4, gradvol); + gradvol *= (-1.0/6.0); + + + double ll1 = v1.Length2(); + double ll2 = v2.Length2(); + double ll3 = v3.Length2(); + double ll4 = v4.Length2(); + double ll5 = v5.Length2(); + double ll6 = v6.Length2(); + + ll = ll1 + ll2 + ll3 + ll4 + ll5 + ll6; + l = sqrt (ll); + lll = l * ll; + + if (vol <= 1e-24 * lll) + { + grad = Vec3d (0, 0, 0); + return 1e24; + } + + + + Vec3d gradll1 (*pp2, *pp1); + Vec3d gradll2 (*pp3, *pp1); + Vec3d gradll3 (*pp4, *pp1); + gradll1 *= 2; + gradll2 *= 2; + gradll3 *= 2; + + Vec3d gradll (gradll1); + gradll += gradll2; + gradll += gradll3; + + /* + Vec3d gradll; + gradll = v1+v2+v3; + gradll *= -2; + */ + + err = 0.0080187537 * lll / vol; + + + gradll *= (0.0080187537 * 1.5 * l / vol); + Vec3d graderr(gradll); + gradvol *= ( -0.0080187537 * lll / (vol * vol) ); + graderr += gradvol; + + if (h > 0) + { + /* + Vec3d gradll1 (*pp2, *pp1); + Vec3d gradll2 (*pp3, *pp1); + Vec3d gradll3 (*pp4, *pp1); + gradll1 *= 2; + gradll2 *= 2; + gradll3 *= 2; + */ + err += ll / (h*h) + + h*h * ( 1 / ll1 + 1 / ll2 + 1 / ll3 + + 1 / ll4 + 1 / ll5 + 1 / ll6 ) - 12; + + graderr += (1/(h*h) - h*h/(ll1*ll1)) * gradll1; + graderr += (1/(h*h) - h*h/(ll2*ll2)) * gradll2; + graderr += (1/(h*h) - h*h/(ll3*ll3)) * gradll3; + } + + double errpow; + + double teterrpow = mp.opterrpow; + if(teterrpow < 1) teterrpow = 1; + + if (teterrpow == 1) + { + errpow = err; + grad = graderr; + } + + if (teterrpow == 2) + { + errpow = err*err; + grad = (2 * err) * graderr; + } + + if(teterrpow > 2) + { + errpow = pow (err, teterrpow); + grad = (teterrpow * errpow / err) * graderr; + } + return errpow; + } + + + + + + /* + + double CalcTetBadness (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, double h) + { + double vol, l; + double err; + + + Vec3d v1 (p1, p2); + Vec3d v2 (p1, p3); + Vec3d v3 (p1, p4); + + vol = -Determinant (v1, v2, v3) / 6; + + double l1 = v1.Length(); + double l2 = v2.Length(); + double l3 = v3.Length(); + double l4 = Dist (p2, p3); + double l5 = Dist (p2, p4); + double l6 = Dist (p3, p4); + + l = l1 + l2 + l3 + l4 + l5 + l6; + + // just for timing + // l += 1e-40 * CalcTetBadnessNew (p1, p2, p3, p4, h); + + if (vol <= 1e-24 * l * l * l) + { + return 1e24; + } + + err = (l*l*l) / (1832.82 * vol); // 6^4 * sqrt(2) + + if (h > 0) + err += l / h + + h * (1 / l1 + 1/l2 + 1/l3 + 1/l4 + 1/l5 + 1/l6) - 12; + + return pow (err, teterrpow); + } + + + + double CalcTetBadnessGrad (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, double h, + int pi, Vec3d & grad) + { + double vol, l; + double err; + + const Point3d *pp1, *pp2, *pp3, *pp4; + + pp1 = &p1; + pp2 = &p2; + pp3 = &p3; + pp4 = &p4; + + switch (pi) + { + case 2: + { + swap (pp1, pp2); + swap (pp3, pp4); + break; + } + case 3: + { + swap (pp1, pp3); + swap (pp2, pp4); + break; + } + case 4: + { + swap (pp1, pp4); + swap (pp3, pp2); + break; + } + } + + + Vec3d v1 (*pp1, *pp2); + Vec3d v2 (*pp1, *pp3); + Vec3d v3 (*pp1, *pp4); + + Vec3d v4 (*pp2, *pp3); + Vec3d v5 (*pp2, *pp4); + Vec3d v6 (*pp3, *pp4); + + + // Vec3d n; + // Cross (v1, v2, n); + // vol = - (n * v3) / 6; + + + vol = -Determinant (v1, v2, v3) / 6; + + Vec3d gradvol; + Cross (v5, v4, gradvol); + gradvol *= (-1.0/6.0); + + + double l1 = v1.Length(); + double l2 = v2.Length(); + double l3 = v3.Length(); + double l4 = v4.Length(); + double l5 = v5.Length(); + double l6 = v6.Length(); + + l = l1 + l2 + l3 +l4 + l5 + l6; + + Vec3d gradl1 (*pp2, *pp1); + Vec3d gradl2 (*pp3, *pp1); + Vec3d gradl3 (*pp4, *pp1); + gradl1 /= l1; + gradl2 /= l2; + gradl3 /= l3; + + Vec3d gradl (gradl1); + gradl += gradl2; + gradl += gradl3; + + + if (vol <= 1e-24 * l * l * l) + { + grad = Vec3d (0, 0, 0); + return 1e24; + } + + + double c1 = 1.0 / 1832.82; // 6^4 * sqrt(2) + err = c1 * (l*l*l) / vol; + + + gradl *= (c1 * 3 * l * l / vol); + Vec3d graderr(gradl); + gradvol *= ( -c1 * l * l * l / (vol * vol) ); + graderr+= gradvol; + + if (h > 0) + { + err += l / h + + h * ( 1 / l1 + 1 / l2 + 1 / l3 + + 1 / l4 + 1 / l5 + 1 / l6 ) - 12; + + graderr += (1/h - h/(l1*l1)) * gradl1; + graderr += (1/h - h/(l2*l2)) * gradl2; + graderr += (1/h - h/(l3*l3)) * gradl3; + cout << "?"; + } + + double errpow = pow (err, teterrpow); + grad = (teterrpow * errpow / err) * graderr; + + return errpow; + } + + */ + + + + + + /* + double CalcVolume (const Array & points, + const Element & el) + { + Vec3d v1 = points.Get(el.PNum(2)) - + points.Get(el.PNum(1)); + Vec3d v2 = points.Get(el.PNum(3)) - + points.Get(el.PNum(1)); + Vec3d v3 = points.Get(el.PNum(4)) - + points.Get(el.PNum(1)); + + return -(Cross (v1, v2) * v3) / 6; + } + */ + + double CalcVolume (const Array & points, + const Array & elements) + { + double vol; + Vec3d v1, v2, v3; + + vol = 0; + for (int i = 0; i < elements.Size(); i++) + { + v1 = points.Get(elements[i][1]) - points.Get(elements[i][0]); + v2 = points.Get(elements[i][2]) - points.Get(elements[i][0]); + v3 = points.Get(elements[i][3]) - points.Get(elements[i][0]); + vol -= (Cross (v1, v2) * v3) / 6; + } + return vol; + } + + + + + void MeshQuality3d (const Mesh & mesh, Array * inclass) + { + int ncl = 20; + signed int cl; + Array incl(ncl); + INDEX i; + double qual; + double sum = 0; + int nontet = 0; + + for (i = 1; i <= incl.Size(); i++) + incl.Elem(i) = 0; + + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + if (mesh[ei].GetType() != TET) + { + nontet++; + continue; + } + + qual = TetElementQuality (mesh.Point(mesh[ei][0]), + mesh.Point(mesh[ei][1]), + mesh.Point(mesh[ei][2]), + mesh.Point(mesh[ei][3])); + + if (qual > 1) qual = 1; + cl = int (ncl * qual ) + 1; + + if (cl < 1) cl = 1; + if (cl > ncl) cl = ncl; + + incl.Elem(cl)++; + if (inclass) (*inclass)[ei] = cl; + sum += 1/qual; + } + + (*testout) << endl << endl; + (*testout) << "Points: " << mesh.GetNP() << endl; + (*testout) << "Volume Elements: " << mesh.GetNE() << endl; + if (nontet) + (*testout) << nontet << " non tetrahedral elements" << endl; + (*testout) << endl; + + (*testout) << "Volume elements in qualityclasses:" << endl; + (*testout) << setprecision(2); + for (i = 1; i <= ncl; i++) + { + (*testout) << setw(4) << double (i-1)/ncl << " - " + << setw(4) << double (i) / ncl << ": " + << incl.Get(i) << endl; + } + (*testout) << "total error: " << sum << endl; + } + + + void SaveEdges (const Mesh & mesh, const char * geomfile, double h, char * filename) + { + ofstream of (filename); + int i; + const Segment * seg; + + of << "edges" << endl; + of << geomfile << endl; + of << h << endl; + + of << mesh.GetNP() << endl; + for (i = 1; i <= mesh.GetNP(); i++) + of << mesh.Point(i)(0) << " " + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << "\n"; + + of << 2 * mesh.GetNSeg() << endl; + for (i = 1; i <= mesh.GetNSeg(); i++) + { + seg = &mesh.LineSegment(i); + + of << (*seg)[1] << " " << (*seg)[0] << " " << seg->si << "\n"; + } + + } + + + void SaveSurfaceMesh (const Mesh & mesh, + double h, + char * filename) + + { + INDEX i; + + ofstream outfile(filename); + + outfile << "surfacemesh" << endl; + outfile << h << endl; + + outfile << mesh.GetNP() << endl; + for (i = 1; i <= mesh.GetNP(); i++) + outfile << mesh.Point(i)(0) << " " + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << endl; + + + + outfile << mesh.GetNSE() << endl; + for (i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & el = mesh.SurfaceElement(i); + + if (mesh.GetFaceDescriptor(el.GetIndex()).DomainOut() == 0) + outfile << mesh.SurfaceElement(i).PNum(1) << " " + << mesh.SurfaceElement(i).PNum(2) << " " + << mesh.SurfaceElement(i).PNum(3) << endl; + if (mesh.GetFaceDescriptor(el.GetIndex()).DomainIn() == 0) + outfile << mesh.SurfaceElement(i).PNum(1) << " " + << mesh.SurfaceElement(i).PNum(3) << " " + << mesh.SurfaceElement(i).PNum(2) << endl; + } + } + + +#ifdef OLD + void Save2DMesh ( + const Mesh & mesh2d, + const Array * splines, + ostream & outfile) + + { + int i, j; + outfile.precision (6); + + outfile << "areamesh2" << endl; + + + outfile << endl; + outfile << mesh2d.GetNSeg() << endl; + for (i = 1; i <= mesh2d.GetNSeg(); i++) + outfile << mesh2d.LineSegment(i).si << " " + << mesh2d.LineSegment(i)[0] << " " + << mesh2d.LineSegment(i)[1] << " " << endl; + + + outfile << mesh2d.GetNSE() << endl; + for (i = 1; i <= mesh2d.GetNSE(); i++) + { + outfile << mesh2d.SurfaceElement(i).GetIndex() << " "; + outfile << mesh2d.SurfaceElement(i).GetNP() << " "; + for (j = 1; j <= mesh2d.SurfaceElement(i).GetNP(); j++) + outfile << mesh2d.SurfaceElement(i).PNum(j) << " "; + outfile << endl; + } + + outfile << mesh2d.GetNP() << endl; + for (i = 1; i <= mesh2d.GetNP(); i++) + outfile << mesh2d.Point(i).X() << " " + << mesh2d.Point(i).Y() << endl; + + if (splines) + { + outfile << splines->Size() << endl; + for (i = 1; i <= splines->Size(); i++) + splines->Get(i) -> PrintCoeff (outfile); + } + else + outfile << "0" << endl; + } +#endif + + + + + + + + + void SaveVolumeMesh (const Mesh & mesh, + const CSGeometry & geometry, + char * filename) + { + INDEX i; + + ofstream outfile(filename); + outfile << "volumemesh" << endl; + + outfile << mesh.GetNSE() << endl; + for (i = 1; i <= mesh.GetNSE(); i++) + { + if (mesh.SurfaceElement(i).GetIndex()) + outfile << mesh.GetFaceDescriptor(mesh.SurfaceElement(i).GetIndex ()).SurfNr() + << "\t"; + else + outfile << "0" << "\t"; + outfile << mesh.SurfaceElement(i)[0] << " " + << mesh.SurfaceElement(i)[1] << " " + << mesh.SurfaceElement(i)[2] << endl; + } + outfile << mesh.GetNE() << endl; + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + outfile << mesh[ei].GetIndex() << "\t" + << mesh[ei][0] << " " << mesh[ei][1] << " " + << mesh[ei][2] << " " << mesh[ei][3] << endl; + + outfile << mesh.GetNP() << endl; + for (i = 1; i <= mesh.GetNP(); i++) + outfile << mesh.Point(i)(0) << " " + << mesh.Point(i)(1) << " " + << mesh.Point(i)(2) << endl; + +#ifdef SOLIDGEOM + outfile << geometry.GetNSurf() << endl; + for (i = 1; i <= geometry.GetNSurf(); i++) + geometry.GetSurface(i) -> Print (outfile); +#endif + } + + + + + int CheckCode () + { + return 1; + + /* + char st[100]; + ifstream ist("pw"); + + if (!ist.good()) return 0; + ist >> st; + if (strcmp (st, "JKULinz") == 0) return 1; + return 0; + */ + } + + + + /* ******************** CheckMesh ******************************* */ + + /// Checks, whether mesh contains a valid 3d mesh + int CheckMesh3D (const Mesh & mesh) + { + INDEX_3_HASHTABLE faceused(mesh.GetNE()/3); + INDEX i; + int j, k, l; + INDEX_3 i3; + int ok = 1; + ElementIndex ei; + + for (i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & el = mesh.SurfaceElement(i); + + if (mesh.GetFaceDescriptor(el.GetIndex()).DomainIn() == 0 || + mesh.GetFaceDescriptor(el.GetIndex()).DomainOut() == 0) + { + for (j = 1; j <= 3; j++) + i3.I(j) = el.PNum(j); + + i3.Sort(); + faceused.Set (i3, 1); + } + } + + for (ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + for (j = 1; j <= 4; j++) + { + l = 0; + for (k = 1; k <= 4; k++) + { + if (j != k) + { + l++; + i3.I(l) = el.PNum(k); + } + } + + i3.Sort(); + if (faceused.Used(i3)) + faceused.Set(i3, faceused.Get(i3)+1); + else + faceused.Set (i3, 1); + } + } + + + for (i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & el = mesh.SurfaceElement(i); + + for (j = 1; j <= 3; j++) + i3.I(j) = el.PNum(j); + + i3.Sort(); + k = faceused.Get (i3); + if (k != 2) + { + ok = 0; + (*testout) << "face " << i << " with points " + << i3.I1() << "-" << i3.I2() << "-" << i3.I3() + << " has " << k << " elements" << endl; + } + } + + for (ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + + for (j = 1; j <= 4; j++) + { + l = 0; + for (k = 1; k <= 4; k++) + { + if (j != k) + { + l++; + i3.I(l) = el.PNum(k); + } + } + + i3.Sort(); + k = faceused.Get(i3); + if (k != 2) + { + ok = 0; + (*testout) << "element " << ei << " with face " + << i3.I1() << "-" << i3.I2() << "-" + << i3.I3() + << " has " << k << " elements" << endl; + } + } + } + + + + + + /* + for (i = 1; i <= faceused.GetNBags(); i++) + for (j = 1; j <= faceused.GetBagSize(i); j++) + { + faceused.GetData(i, j, i3, k); + if (k != 2) + { + (*testout) << "Face: " << i3.I1() << "-" + << i3.I2() << "-" << i3.I3() << " has " + << k << " Faces " << endl; + cerr << "Face Error" << endl; + ok = 0; + } + } + */ + + + if (!ok) + { + (*testout) << "surfelements: " << endl; + for (i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & el = mesh.SurfaceElement(i); + (*testout) << setw(5) << i << ":" + << setw(6) << el.GetIndex() + << setw(6) << el.PNum(1) + << setw(4) << el.PNum(2) + << setw(4) << el.PNum(3) << endl; + } + (*testout) << "volelements: " << endl; + for (ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + (*testout) << setw(5) << i << ":" + << setw(6) << el.GetIndex() + << setw(6) << el[0] << setw(4) << el[1] + << setw(4) << el[2] << setw(4) << el[3] << endl; + } + } + + + return ok; + } + + + + void RemoveProblem (Mesh & mesh, int domainnr) + { + int i, j, k; + + mesh.FindOpenElements(domainnr); + int np = mesh.GetNP(); + + BitArrayChar ppoints(np); + + // int ndom = mesh.GetNDomains(); + + PrintMessage (3, "Elements before Remove: ", mesh.GetNE()); + // for (k = 1; k <= ndom; k++) + k = domainnr; + { + ppoints.Clear(); + + for (i = 1; i <= mesh.GetNOpenElements(); i++) + { + const Element2d & sel = mesh.OpenElement(i); + if (sel.GetIndex() == k) + { + for (j = 1; j <= sel.GetNP(); j++) + ppoints.Set (sel.PNum(j)); + } + } + + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + if (el.GetIndex() == k) + { + int todel = 0; + for (j = 0; j < el.GetNP(); j++) + if (ppoints.Test (el[j])) + todel = 1; + + if (el.GetNP() != 4) + todel = 0; + + if (todel) + { + mesh[ei].Delete(); + // ei--; + } + } + } + } + + mesh.Compress(); + PrintMessage (3, "Elements after Remove: ", mesh.GetNE()); + } + +} diff --git a/libsrc/meshing/meshtool.hpp b/libsrc/meshing/meshtool.hpp new file mode 100644 index 00000000..b6472ce0 --- /dev/null +++ b/libsrc/meshing/meshtool.hpp @@ -0,0 +1,81 @@ +#ifndef FILE_MESHTOOL +#define FILE_MESHTOOL + + +/// +extern void MeshQuality2d (const Mesh & mesh); + +/// +extern void MeshQuality3d (const Mesh & mesh, + Array * inclass = NULL); + +/// +extern void SaveEdges (const Mesh & mesh, + const char * geomfile, + double h, + char * filename); + +/// +extern void SaveSurfaceMesh (const Mesh & mesh, + double h, + char * filename); +/* +/// +extern void Save2DMesh ( + const Mesh & mesh2d, + const Array * splines, + ostream & outfile); +*/ + +class Surface; +/// +extern void SaveVolumeMesh ( + const Array & points, + const Array & elements, + const Array & volelements, + const Array & surfaces, + char * filename); + +/// +void SaveVolumeMesh (const Mesh & mesh, + const class CSGeometry & geometry, + char * filename); + +/// +extern int CheckCode (); + + +/// +extern double CalcTetBadness (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, + double h, + const MeshingParameters & mp); +/// +extern double CalcTetBadnessGrad (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, + double h, int pi, + Vec<3> & grad, + const MeshingParameters & mp); + + +/** Calculates volume of an element. + The volume of the tetrahedron el is computed + */ +// extern double CalcVolume (const Array & points, +// const Element & el); + +/** The total volume of all elements is computed. + This function calculates the volume of the mesh */ +extern double CalcVolume (const Array & points, + const Array & elements); + +/// +extern int CheckSurfaceMesh (const Mesh & mesh); + +/// +extern int CheckSurfaceMesh2 (const Mesh & mesh); +/// +extern int CheckMesh3D (const Mesh & mesh); +/// +extern void RemoveProblem (Mesh & mesh, int domainnr); +#endif diff --git a/libsrc/meshing/meshtype.cpp b/libsrc/meshing/meshtype.cpp new file mode 100644 index 00000000..54842609 --- /dev/null +++ b/libsrc/meshing/meshtype.cpp @@ -0,0 +1,2650 @@ +#include + +#include "meshing.hpp" + +namespace netgen +{ + int MultiPointGeomInfo :: + AddPointGeomInfo (const PointGeomInfo & gi) + { + for (int k = 0; k < cnt; k++) + if (mgi[k].trignum == gi.trignum) + return 0; + + if (cnt < MULTIPOINTGEOMINFO_MAX) + { + mgi[cnt] = gi; + cnt++; + return 0; + } + + throw NgException ("Please report error: MPGI Size too small\n"); + } + + + +#ifdef PARALLEL + MPI_Datatype MeshPoint :: MyGetMPIType ( ) + { + static MPI_Datatype type = NULL; + static MPI_Datatype htype = NULL; + if (!type) + { + MeshPoint hp; + int blocklen[] = { 3, 1, 1 }; + MPI_Aint displ[] = { (char*)&hp.x[0] - (char*)&hp, + (char*)&hp.layer - (char*)&hp, + (char*)&hp.singular - (char*)&hp }; + MPI_Datatype types[] = { MPI_DOUBLE, MPI_INT, MPI_DOUBLE }; + *testout << "displ = " << displ[0] << ", " << displ[1] << ", " << displ[2] << endl; + *testout << "sizeof = " << sizeof (MeshPoint) << endl; + MPI_Type_create_struct (3, blocklen, displ, types, &htype); + MPI_Type_commit ( &htype ); + MPI_Aint lb, ext; + MPI_Type_get_extent (htype, &lb, &ext); + *testout << "lb = " << lb << endl; + *testout << "ext = " << ext << endl; + ext = sizeof (MeshPoint); + MPI_Type_create_resized (htype, lb, ext, &type); + MPI_Type_commit ( &type ); + + } + return type; + } +#endif + + + + + Segment :: Segment() + { + pnums[0] = -1; + pnums[1] = -1; + edgenr = -1; + + singedge_left = 0.; + singedge_right = 0.; + seginfo = 0; + + si = -1; + + domin = -1; + domout = -1; + tlosurf = -1; + + surfnr1 = -1; + surfnr2 = -1; + pnums[2] = -1; + meshdocval = 0; + /* + geominfo[0].trignum=-1; + geominfo[1].trignum=-1; + + epgeominfo[0].edgenr = 1; + epgeominfo[0].dist = 0; + epgeominfo[1].edgenr = 1; + epgeominfo[1].dist = 0; + */ + + bcname = 0; + } + + Segment::Segment (const Segment & other) + : + edgenr(other.edgenr), + singedge_left(other.singedge_left), + singedge_right(other.singedge_right), + seginfo(other.seginfo), + si(other.si), + domin(other.domin), + domout(other.domout), + tlosurf(other.tlosurf), + geominfo(), + surfnr1(other.surfnr1), + surfnr2(other.surfnr2), + epgeominfo(), + meshdocval(other.meshdocval), + hp_elnr(other.hp_elnr) + { + for (int j = 0; j < 3; j++) + pnums[j] = other.pnums[j]; + + geominfo[0] = other.geominfo[0]; + geominfo[1] = other.geominfo[1]; + epgeominfo[0] = other.epgeominfo[0]; + epgeominfo[1] = other.epgeominfo[1]; + bcname = other.bcname; + } + + Segment& Segment::operator=(const Segment & other) + { + if (&other != this) + { + pnums[0] = other[0]; + pnums[1] = other[1]; + edgenr = other.edgenr; + singedge_left = other.singedge_left; + singedge_right = other.singedge_right; + seginfo = other.seginfo; + si = other.si; + domin = other.domin; + domout = other.domout; + tlosurf = other.tlosurf; + geominfo[0] = other.geominfo[0]; + geominfo[1] = other.geominfo[1]; + surfnr1 = other.surfnr1; + surfnr2 = other.surfnr2; + epgeominfo[0] = other.epgeominfo[0]; + epgeominfo[1] = other.epgeominfo[1]; + pnums[2] = other.pnums[2]; + meshdocval = other.meshdocval; + hp_elnr = other.hp_elnr; + bcname = other.bcname; + } + + return *this; + } + + + ostream & operator<<(ostream & s, const Segment & seg) + { + s << seg[0] << "(gi=" << seg.geominfo[0].trignum << ") - " + << seg[1] << "(gi=" << seg.geominfo[1].trignum << ")" + << " domin = " << seg.domin << ", domout = " << seg.domout + << " si = " << seg.si << ", edgenr = " << seg.edgenr; + return s; + } + + + Element2d :: Element2d () + { + for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) + { + pnum[i] = 0; + geominfo[i].trignum = 0; + } + np = 3; + index = 0; + badel = 0; + deleted = 0; + visible = 1; + typ = TRIG; + orderx = ordery = 1; + refflag = 1; + strongrefflag = false; + } + + + Element2d :: Element2d (int anp) + { + for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) + { + pnum[i] = 0; + geominfo[i].trignum = 0; + } + np = anp; + index = 0; + badel = 0; + deleted = 0; + visible = 1; + switch (np) + { + case 3: typ = TRIG; break; + case 4: typ = QUAD; break; + case 6: typ = TRIG6; break; + case 8: typ = QUAD8; break; + } + orderx = ordery = 1; + refflag = 1; + strongrefflag = false; + } + + Element2d :: Element2d (ELEMENT_TYPE atyp) + { + for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) + { + pnum[i] = 0; + geominfo[i].trignum = 0; + } + + SetType (atyp); + + index = 0; + badel = 0; + deleted = 0; + visible = 1; + orderx = ordery = 1; + refflag = 1; + strongrefflag = false; + } + + + + Element2d :: Element2d (int pi1, int pi2, int pi3) + { + pnum[0] = pi1; + pnum[1] = pi2; + pnum[2] = pi3; + np = 3; + typ = TRIG; + pnum[3] = 0; + pnum[4] = 0; + pnum[5] = 0; + + for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) + geominfo[i].trignum = 0; + index = 0; + badel = 0; + refflag = 1; + strongrefflag = false; + deleted = 0; + visible = 1; + orderx = ordery = 1; + } + + Element2d :: Element2d (int pi1, int pi2, int pi3, int pi4) + { + pnum[0] = pi1; + pnum[1] = pi2; + pnum[2] = pi3; + pnum[3] = pi4; + np = 4; + typ = QUAD; + + pnum[4] = 0; + pnum[5] = 0; + + for (int i = 0; i < ELEMENT2D_MAXPOINTS; i++) + geominfo[i].trignum = 0; + index = 0; + badel = 0; + refflag = 1; + strongrefflag = false; + deleted = 0; + visible = 1; + orderx = ordery = 1; + } + + + /* + void Element2d :: SetType (ELEMENT_TYPE atyp) + { + typ = atyp; + switch (typ) + { + case TRIG: np = 3; break; + case QUAD: np = 4; break; + case TRIG6: np = 6; break; + case QUAD6: np = 6; break; + default: + PrintSysError ("Element2d::SetType, illegal type ", typ); + } + } + */ + + + void Element2d :: GetBox (const T_POINTS & points, Box3d & box) const + { + box.SetPoint (points.Get(pnum[0])); + for (unsigned i = 1; i < np; i++) + box.AddPoint (points.Get(pnum[i])); + } + + bool Element2d :: operator==(const Element2d & el2) const + { + bool retval = (el2.GetNP() == np); + for(int i= 0; retval && i ipdtrig; + Array ipdquad; + + + int Element2d :: GetNIP () const + { + int nip; + switch (np) + { + case 3: nip = 1; break; + case 4: nip = 4; break; + default: nip = 0; break; + } + return nip; + } + + void Element2d :: + GetIntegrationPoint (int ip, Point2d & p, double & weight) const + { + static double eltriqp[1][3] = + { + { 1.0/3.0, 1.0/3.0, 0.5 } + }; + + static double elquadqp[4][3] = + { + { 0, 0, 0.25 }, + { 0, 1, 0.25 }, + { 1, 0, 0.25 }, + { 1, 1, 0.25 } + }; + + double * pp = 0; + switch (typ) + { + case TRIG: pp = &eltriqp[0][0]; break; + case QUAD: pp = &elquadqp[ip-1][0]; break; + default: + PrintSysError ("Element2d::GetIntegrationPoint, illegal type ", typ); + } + + p.X() = pp[0]; + p.Y() = pp[1]; + weight = pp[2]; + } + + void Element2d :: + GetTransformation (int ip, const Array & points, + DenseMatrix & trans) const + { + int np = GetNP(); + DenseMatrix pmat(2, np), dshape(2, np); + pmat.SetSize (2, np); + dshape.SetSize (2, np); + + Point2d p; + double w; + + GetPointMatrix (points, pmat); + GetIntegrationPoint (ip, p, w); + GetDShape (p, dshape); + + CalcABt (pmat, dshape, trans); + + /* + (*testout) << "p = " << p << endl + << "pmat = " << pmat << endl + << "dshape = " << dshape << endl + << "tans = " << trans << endl; + */ + } + + void Element2d :: + GetTransformation (int ip, class DenseMatrix & pmat, + class DenseMatrix & trans) const + { + // int np = GetNP(); + +#ifdef DEBUG + if (pmat.Width() != np || pmat.Height() != 2) + { + (*testout) << "GetTransofrmation: pmat doesn't fit" << endl; + return; + } +#endif + + ComputeIntegrationPointData (); + DenseMatrix * dshapep = NULL; + switch (typ) + { + case TRIG: dshapep = &ipdtrig.Get(ip)->dshape; break; + case QUAD: dshapep = &ipdquad.Get(ip)->dshape; break; + default: + PrintSysError ("Element2d::GetTransformation, illegal type ", typ); + } + + CalcABt (pmat, *dshapep, trans); + } + + + void Element2d :: GetShape (const Point2d & p, Vector & shape) const + { + if (shape.Size() != GetNP()) + { + cerr << "Element::GetShape: Length not fitting" << endl; + return; + } + + switch (typ) + { + case TRIG: + shape(0) = 1 - p.X() - p.Y(); + shape(1) = p.X(); + shape(2) = p.Y(); + break; + case QUAD: + shape(0) = (1-p.X()) * (1-p.Y()); + shape(1) = p.X() * (1-p.Y()); + shape(2) = p.X() * p.Y(); + shape(3) = (1-p.X()) * p.Y(); + break; + default: + PrintSysError ("Element2d::GetShape, illegal type ", typ); + } + } + + + + void Element2d :: GetShapeNew (const Point<2> & p, FlatVector & shape) const + { + switch (typ) + { + case TRIG: + { + shape(0) = p(0); + shape(1) = p(1); + shape(2) = 1-p(0)-p(1); + break; + } + + case QUAD: + { + shape(0) = (1-p(0))*(1-p(1)); + shape(1) = p(0) *(1-p(1)); + shape(2) = p(0) * p(1) ; + shape(3) = (1-p(0))* p(1) ; + break; + } + } + } + + + + + + + + + + void Element2d :: + GetDShape (const Point2d & p, DenseMatrix & dshape) const + { +#ifdef DEBUG + if (dshape.Height() != 2 || dshape.Width() != np) + { + PrintSysError ("Element::DShape: Sizes don't fit"); + return; + } +#endif + + switch (typ) + { + case TRIG: + dshape.Elem(1, 1) = -1; + dshape.Elem(1, 2) = 1; + dshape.Elem(1, 3) = 0; + dshape.Elem(2, 1) = -1; + dshape.Elem(2, 2) = 0; + dshape.Elem(2, 3) = 1; + break; + case QUAD: + dshape.Elem(1, 1) = -(1-p.Y()); + dshape.Elem(1, 2) = (1-p.Y()); + dshape.Elem(1, 3) = p.Y(); + dshape.Elem(1, 4) = -p.Y(); + dshape.Elem(2, 1) = -(1-p.X()); + dshape.Elem(2, 2) = -p.X(); + dshape.Elem(2, 3) = p.X(); + dshape.Elem(2, 4) = (1-p.X()); + break; + + default: + PrintSysError ("Element2d::GetDShape, illegal type ", typ); + } + } + + + + void Element2d :: + GetDShapeNew (const Point<2> & p, MatrixFixWidth<2> & dshape) const + { + switch (typ) + { + case TRIG: + { + dshape = 0; + dshape(0,0) = 1; + dshape(1,1) = 1; + dshape(2,0) = -1; + dshape(2,1) = -1; + break; + } + case QUAD: + { + dshape(0,0) = -(1-p(1)); + dshape(0,1) = -(1-p(0)); + + dshape(1,0) = (1-p(1)); + dshape(1,1) = -p(0); + + dshape(2,0) = p(1); + dshape(2,1) = p(0); + + dshape(3,0) = -p(1); + dshape(3,1) = (1-p(0)); + break; + } + } + } + + + + + + void Element2d :: + GetPointMatrix (const Array & points, + DenseMatrix & pmat) const + { + int np = GetNP(); + +#ifdef DEBUG + if (pmat.Width() != np || pmat.Height() != 2) + { + cerr << "Element::GetPointMatrix: sizes don't fit" << endl; + return; + } +#endif + + for (int i = 1; i <= np; i++) + { + const Point2d & p = points.Get(PNum(i)); + pmat.Elem(1, i) = p.X(); + pmat.Elem(2, i) = p.Y(); + } + } + + + + + + double Element2d :: CalcJacobianBadness (const Array & points) const + { + int i, j; + int nip = GetNIP(); + DenseMatrix trans(2,2); + DenseMatrix pmat; + + pmat.SetSize (2, GetNP()); + GetPointMatrix (points, pmat); + + double err = 0; + for (i = 1; i <= nip; i++) + { + GetTransformation (i, pmat, trans); + + // Frobenius norm + double frob = 0; + for (j = 1; j <= 4; j++) + frob += sqr (trans.Get(j)); + frob = sqrt (frob); + frob /= 2; + + double det = trans.Det(); + + if (det <= 0) + err += 1e12; + else + err += frob * frob / det; + } + + err /= nip; + return err; + } + + + + static const int qip_table[4][4] = + { { 0, 1, 0, 3 }, + { 0, 1, 1, 2 }, + { 3, 2, 0, 3 }, + { 3, 2, 1, 2 } + }; + + double Element2d :: + CalcJacobianBadnessDirDeriv (const Array & points, + int pi, Vec2d & dir, double & dd) const + { + if (typ == QUAD) + { + Mat<2,2> trans, dtrans; + Mat<2,4> vmat, pmat; + + for (int j = 0; j < 4; j++) + { + const Point2d & p = points.Get( (*this)[j] ); + pmat(0, j) = p.X(); + pmat(1, j) = p.Y(); + } + + vmat = 0.0; + vmat(0, pi-1) = dir.X(); + vmat(1, pi-1) = dir.Y(); + + double err = 0; + dd = 0; + + for (int i = 0; i < 4; i++) + { + int ix1 = qip_table[i][0]; + int ix2 = qip_table[i][1]; + int iy1 = qip_table[i][2]; + int iy2 = qip_table[i][3]; + + trans(0,0) = pmat(0, ix2) - pmat(0,ix1); + trans(1,0) = pmat(1, ix2) - pmat(1,ix1); + trans(0,1) = pmat(0, iy2) - pmat(0,iy1); + trans(1,1) = pmat(1, iy2) - pmat(1,iy1); + + double det = trans(0,0)*trans(1,1)-trans(1,0)*trans(0,1); + + if (det <= 0) + { + dd = 0; + return 1e12; + } + + dtrans(0,0) = vmat(0, ix2) - vmat(0,ix1); + dtrans(1,0) = vmat(1, ix2) - vmat(1,ix1); + dtrans(0,1) = vmat(0, iy2) - vmat(0,iy1); + dtrans(1,1) = vmat(1, iy2) - vmat(1,iy1); + + + // Frobenius norm + double frob = 0; + for (int j = 0; j < 4; j++) + frob += sqr (trans(j)); + frob = sqrt (frob); + + double dfrob = 0; + for (int j = 0; j < 4; j++) + dfrob += trans(j) * dtrans(j); + dfrob = dfrob / frob; + + frob /= 2; + dfrob /= 2; + + + // ddet = \sum_j det (m_j) with m_j = trans, except col j = dtrans + double ddet + = dtrans(0,0) * trans(1,1) - trans(0,1) * dtrans(1,0) + + trans(0,0) * dtrans(1,1) - dtrans(0,1) * trans(1,0); + + err += frob * frob / det; + dd += (2 * frob * dfrob * det - frob * frob * ddet) / (det * det); + } + + err /= 4; + dd /= 4; + return err; + } + + int nip = GetNIP(); + DenseMatrix trans(2,2), dtrans(2,2); + DenseMatrix pmat, vmat; + + pmat.SetSize (2, GetNP()); + vmat.SetSize (2, GetNP()); + + GetPointMatrix (points, pmat); + + vmat = 0.0; + vmat.Elem(1, pi) = dir.X(); + vmat.Elem(2, pi) = dir.Y(); + + + double err = 0; + dd = 0; + + for (int i = 1; i <= nip; i++) + { + GetTransformation (i, pmat, trans); + GetTransformation (i, vmat, dtrans); + + // Frobenius norm + double frob = 0; + for (int j = 1; j <= 4; j++) + frob += sqr (trans.Get(j)); + frob = sqrt (frob); + + double dfrob = 0; + for (int j = 1; j <= 4; j++) + dfrob += trans.Get(j) * dtrans.Get(j); + dfrob = dfrob / frob; + + frob /= 2; + dfrob /= 2; + + double det = trans(0,0)*trans(1,1)-trans(1,0)*trans(0,1); + + // ddet = \sum_j det (m_j) with m_j = trans, except col j = dtrans + double ddet + = dtrans(0,0) * trans(1,1) - trans(0,1) * dtrans(1,0) + + trans(0,0) * dtrans(1,1) - dtrans(0,1) * trans(1,0); + + if (det <= 0) + err += 1e12; + else + { + err += frob * frob / det; + dd += (2 * frob * dfrob * det - frob * frob * ddet) / (det * det); + } + } + + err /= nip; + dd /= nip; + return err; + } + + + + double Element2d :: + CalcJacobianBadness (const T_POINTS & points, const Vec<3> & n) const + { + int i, j; + int nip = GetNIP(); + DenseMatrix trans(2,2); + DenseMatrix pmat; + + pmat.SetSize (2, GetNP()); + + Vec<3> t1, t2; + t1 = n.GetNormal(); + t2 = Cross (n, t1); + + for (i = 1; i <= GetNP(); i++) + { + Point3d p = points.Get(PNum(i)); + pmat.Elem(1, i) = p.X() * t1(0) + p.Y() * t1(1) + p.Z() * t1(2); + pmat.Elem(2, i) = p.X() * t2(0) + p.Y() * t2(1) + p.Z() * t2(2); + } + + double err = 0; + for (i = 1; i <= nip; i++) + { + GetTransformation (i, pmat, trans); + + // Frobenius norm + double frob = 0; + for (j = 1; j <= 4; j++) + frob += sqr (trans.Get(j)); + frob = sqrt (frob); + frob /= 2; + + double det = trans.Det(); + if (det <= 0) + err += 1e12; + else + err += frob * frob / det; + } + + err /= nip; + return err; + } + + + + + void Element2d :: ComputeIntegrationPointData () const + { + switch (np) + { + case 3: if (ipdtrig.Size()) return; break; + case 4: if (ipdquad.Size()) return; break; + } + + for (int i = 1; i <= GetNIP(); i++) + { + IntegrationPointData * ipd = new IntegrationPointData; + Point2d hp; + GetIntegrationPoint (i, hp, ipd->weight); + ipd->p(0) = hp.X(); + ipd->p(1) = hp.Y(); + ipd->p(2) = 0; + + ipd->shape.SetSize(GetNP()); + ipd->dshape.SetSize(2, GetNP()); + + GetShape (hp, ipd->shape); + GetDShape (hp, ipd->dshape); + + switch (np) + { + case 3: ipdtrig.Append (ipd); break; + case 4: ipdquad.Append (ipd); break; + } + } + } + + + + + + + + + + ostream & operator<<(ostream & s, const Element2d & el) + { + s << "np = " << el.GetNP(); + for (int j = 1; j <= el.GetNP(); j++) + s << " " << el.PNum(j); + return s; + } + + + ostream & operator<<(ostream & s, const Element & el) + { + s << "np = " << el.GetNP(); + for (int j = 0; j < el.GetNP(); j++) + s << " " << int(el[j]); + return s; + } + + + Element :: Element () + { + typ = TET; + np = 4; + for (int i = 0; i < ELEMENT_MAXPOINTS; i++) + pnum[i] = 0; + index = 0; + flags.marked = 1; + flags.badel = 0; + flags.reverse = 0; + flags.illegal = 0; + flags.illegal_valid = 0; + flags.badness_valid = 0; + flags.refflag = 1; + flags.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 0; + orderx = ordery = orderz = 1; + +#ifdef PARALLEL + partitionNumber = -1; +#endif + + } + + + Element :: Element (int anp) + { + np = anp; + int i; + for (i = 0; i < ELEMENT_MAXPOINTS; i++) + pnum[i] = 0; + index = 0; + flags.marked = 1; + flags.badel = 0; + flags.reverse = 0; + flags.illegal = 0; + flags.illegal_valid = 0; + flags.badness_valid = 0; + flags.refflag = 1; + flags.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 0; + + switch (np) + { + case 4: typ = TET; break; + case 5: typ = PYRAMID; break; + case 6: typ = PRISM; break; + case 8: typ = HEX; break; + case 10: typ = TET10; break; + default: cerr << "Element::Element: unknown element with " << np << " points" << endl; + } + orderx = ordery = orderz = 1; + } + + void Element :: SetOrder (const int aorder) + { + orderx = aorder; + ordery = aorder; + orderz = aorder; + } + + + void Element :: SetOrder (const int ox, const int oy, const int oz) + { + orderx = ox; + ordery = oy; + orderz = oz; + } + + + Element :: Element (ELEMENT_TYPE type) + { + SetType (type); + + int i; + for (i = 0; i < ELEMENT_MAXPOINTS; i++) + pnum[i] = 0; + index = 0; + flags.marked = 1; + flags.badel = 0; + flags.reverse = 0; + flags.illegal = 0; + flags.illegal_valid = 0; + flags.badness_valid = 0; + flags.refflag = 1; + flags.strongrefflag = false; + flags.deleted = 0; + flags.fixed = 0; + orderx = ordery = orderz = 1; + } + + + + + + Element & Element :: operator= (const Element & el2) + { + typ = el2.typ; + np = el2.np; + for (int i = 0; i < ELEMENT_MAXPOINTS; i++) + pnum[i] = el2.pnum[i]; + index = el2.index; + flags = el2.flags; + orderx = el2.orderx; + ordery = el2.ordery; + orderz = el2.orderz; + hp_elnr = el2.hp_elnr; + flags = el2.flags; + return *this; + } + + + + void Element :: SetNP (int anp) + { + np = anp; + switch (np) + { + case 4: typ = TET; break; + case 5: typ = PYRAMID; break; + case 6: typ = PRISM; break; + case 8: typ = HEX; break; + case 10: typ = TET10; break; + // + default: break; + cerr << "Element::SetNP unknown element with " << np << " points" << endl; + } + } + + + + void Element :: SetType (ELEMENT_TYPE atyp) + { + typ = atyp; + switch (atyp) + { + case TET: np = 4; break; + case PYRAMID: np = 5; break; + case PRISM: np = 6; break; + case HEX: np = 8; break; + case TET10: np = 10; break; + case PRISM12: np = 12; break; + + default: break; + cerr << "Element::SetType unknown type " << int(typ) << endl; + } + } + + + + void Element :: Invert() + { + switch (GetNP()) + { + case 4: + { + Swap (PNum(3), PNum(4)); + break; + } + case 5: + { + Swap (PNum(1), PNum(4)); + Swap (PNum(2), PNum(3)); + break; + } + case 6: + { + Swap (PNum(1), PNum(4)); + Swap (PNum(2), PNum(5)); + Swap (PNum(3), PNum(6)); + break; + } + } + } + + + void Element :: Print (ostream & ost) const + { + ost << np << " Points: "; + for (int i = 1; i <= np; i++) + ost << pnum[i-1] << " " << endl; + } + + void Element :: GetBox (const T_POINTS & points, Box3d & box) const + { + box.SetPoint (points.Get(PNum(1))); + box.AddPoint (points.Get(PNum(2))); + box.AddPoint (points.Get(PNum(3))); + box.AddPoint (points.Get(PNum(4))); + } + + double Element :: Volume (const T_POINTS & points) const + { + Vec<3> v1 = points.Get(PNum(2)) - points.Get(PNum(1)); + Vec<3> v2 = points.Get(PNum(3)) - points.Get(PNum(1)); + Vec<3> v3 = points.Get(PNum(4)) - points.Get(PNum(1)); + + return -(Cross (v1, v2) * v3) / 6; + } + + + void Element :: GetFace2 (int i, Element2d & face) const + { + static const int tetfaces[][5] = + { { 3, 2, 3, 4, 0 }, + { 3, 3, 1, 4, 0 }, + { 3, 1, 2, 4, 0 }, + { 3, 2, 1, 3, 0 } }; + + static const int tet10faces[][7] = + { { 3, 2, 3, 4, 10, 9, 8 }, + { 3, 3, 1, 4, 7, 10, 6 }, + { 3, 1, 2, 4, 9, 7, 5 }, + { 3, 2, 1, 3, 6, 8, 5 } }; + + static const int pyramidfaces[][5] = + { { 4, 1, 4, 3, 2 }, + { 3, 1, 2, 5, 0 }, + { 3, 2, 3, 5, 0 }, + { 3, 3, 4, 5, 0 }, + { 3, 4, 1, 5, 0 } }; + + static const int prismfaces[][5] = + { + { 3, 1, 3, 2, 0 }, + { 3, 4, 5, 6, 0 }, + { 4, 1, 2, 5, 4 }, + { 4, 2, 3, 6, 5 }, + { 4, 3, 1, 4, 6 } + }; + + switch (np) + { + case 4: // tet + { + face.SetType(TRIG); + for (int j = 1; j <= 3; j++) + face.PNum(j) = PNum(tetfaces[i-1][j]); + break; + } + + case 10: // tet10 + { + face.SetType(TRIG6); + for (int j = 1; j <= 6; j++) + face.PNum(j) = PNum(tet10faces[i-1][j]); + break; + } + + case 5: // pyramid + { + // face.SetNP(pyramidfaces[i-1][0]); + face.SetType ( (i == 1) ? QUAD : TRIG); + for (int j = 1; j <= face.GetNP(); j++) + face.PNum(j) = PNum(pyramidfaces[i-1][j]); + break; + } + case 6: // prism + { + // face.SetNP(prismfaces[i-1][0]); + face.SetType ( (i >= 3) ? QUAD : TRIG); + for (int j = 1; j <= face.GetNP(); j++) + face.PNum(j) = PNum(prismfaces[i-1][j]); + break; + } + } + } + + + + void Element :: GetTets (Array & locels) const + { + GetTetsLocal (locels); + int i, j; + for (i = 1; i <= locels.Size(); i++) + for (j = 1; j <= 4; j++) + locels.Elem(i).PNum(j) = PNum ( locels.Elem(i).PNum(j) ); + } + + void Element :: GetTetsLocal (Array & locels) const + { + int i, j; + locels.SetSize(0); + switch (GetType()) + { + case TET: + { + int linels[1][4] = + { { 1, 2, 3, 4 }, + }; + for (i = 0; i < 1; i++) + { + Element tet(4); + for (j = 1; j <= 4; j++) + tet.PNum(j) = linels[i][j-1]; + locels.Append (tet); + } + break; + } + case TET10: + { + int linels[8][4] = + { { 1, 5, 6, 7 }, + { 5, 2, 8, 9 }, + { 6, 8, 3, 10 }, + { 7, 9, 10, 4 }, + { 5, 6, 7, 9 }, + { 5, 6, 9, 8 }, + { 6, 7, 9, 10 }, + { 6, 8, 10, 9 } }; + for (i = 0; i < 8; i++) + { + Element tet(4); + for (j = 1; j <= 4; j++) + tet.PNum(j) = linels[i][j-1]; + locels.Append (tet); + } + break; + } + case PYRAMID: + { + int linels[2][4] = + { { 1, 2, 3, 5 }, + { 1, 3, 4, 5 } }; + for (i = 0; i < 2; i++) + { + Element tet(4); + for (j = 1; j <= 4; j++) + tet.PNum(j) = linels[i][j-1]; + locels.Append (tet); + } + break; + } + case PRISM: + case PRISM12: + { + int linels[3][4] = + { { 1, 2, 3, 4 }, + { 4, 2, 3, 5 }, + { 6, 5, 4, 3 } + }; + for (i = 0; i < 3; i++) + { + Element tet(4); + for (j = 0; j < 4; j++) + tet[j] = linels[i][j]; + locels.Append (tet); + } + break; + } + case HEX: + { + int linels[6][4] = + { { 1, 7, 2, 3 }, + { 1, 7, 3, 4 }, + { 1, 7, 4, 8 }, + { 1, 7, 8, 5 }, + { 1, 7, 5, 6 }, + { 1, 7, 6, 2 } + }; + for (i = 0; i < 6; i++) + { + Element tet(4); + for (j = 0; j < 4; j++) + tet[j] = linels[i][j]; + locels.Append (tet); + } + break; + } + default: + { + cerr << "GetTetsLocal not implemented for el with " << GetNP() << " nodes" << endl; + } + } + } + + bool Element :: operator==(const Element & el2) const + { + bool retval = (el2.GetNP() == np); + for(int i= 0; retval && i & points) const + { + const static double tetpoints[4][3] = + { { 0, 0, 0 }, + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }}; + + const static double prismpoints[6][3] = + { { 0, 0, 0 }, + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 1, 0, 1 }, + { 0, 1, 1 } }; + + const static double pyramidpoints[6][3] = + { { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 } }; + + const static double tet10points[10][3] = + { { 0, 0, 0 }, + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 0.5, 0, 0 }, + { 0, 0.5, 0 }, + { 0, 0, 0.5 }, + { 0.5, 0.5, 0 }, + { 0.5, 0, 0.5 }, + { 0, 0.5, 0.5 } }; + + const static double hexpoints[8][3] = + { + { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 0, 1, 1 } + }; + + int np, i; + const double (*pp)[3]; + switch (GetType()) + { + case TET: + { + np = 4; + pp = tetpoints; + break; + } + case PRISM: + case PRISM12: + { + np = 6; + pp = prismpoints; + break; + } + case TET10: + { + np = 10; + pp = tet10points; + break; + } + case PYRAMID: + { + np = 5; + pp = pyramidpoints; + break; + } + case HEX: + { + np = 8; + pp = hexpoints; + break; + } + default: + { + cout << "GetNodesLocal not impelemented for element " << GetType() << endl; + np = 0; + } + } + + points.SetSize(0); + for (i = 0; i < np; i++) + points.Append (Point3d (pp[i][0], pp[i][1], pp[i][2])); + } +#endif + + + + + + + void Element :: GetNodesLocalNew (Array > & points) const + { + const static double tetpoints[4][3] = + { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 0, 0, 0 } + }; + + const static double prismpoints[6][3] = + { + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 0 }, + { 1, 0, 1 }, + { 0, 1, 1 }, + { 0, 0, 1 } + }; + + const static double pyramidpoints[6][3] = + { { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 } }; + + const static double tet10points[10][3] = + { { 0, 0, 0 }, + { 1, 0, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 0.5, 0, 0 }, + { 0, 0.5, 0 }, + { 0, 0, 0.5 }, + { 0.5, 0.5, 0 }, + { 0.5, 0, 0.5 }, + { 0, 0.5, 0.5 } }; + + const static double hexpoints[8][3] = + { + { 0, 0, 0 }, + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 0, 1 }, + { 1, 0, 1 }, + { 1, 1, 1 }, + { 0, 1, 1 } + }; + + + + int np, i; + const double (*pp)[3]; + switch (GetType()) + { + case TET: + { + np = 4; + pp = tetpoints; + break; + } + case PRISM: + case PRISM12: + { + np = 6; + pp = prismpoints; + break; + } + case TET10: + { + np = 10; + pp = tet10points; + break; + } + case PYRAMID: + { + np = 5; + pp = pyramidpoints; + break; + } + case HEX: + { + np = 8; + pp = hexpoints; + break; + } + default: + { + cout << "GetNodesLocal not impelemented for element " << GetType() << endl; + np = 0; + pp = NULL; + } + } + + points.SetSize(0); + for (i = 0; i < np; i++) + points.Append (Point<3> (pp[i][0], pp[i][1], pp[i][2])); + } + + + + + + + + + + + + + + + + + + void Element :: GetSurfaceTriangles (Array & surftrigs) const + { + static int tet4trigs[][3] = + { { 2, 3, 4 }, + { 3, 1, 4 }, + { 1, 2, 4 }, + { 2, 1, 3 } }; + + static int tet10trigs[][3] = + { { 2, 8, 9 }, { 3, 10, 8}, { 4, 9, 10 }, { 9, 8, 10 }, + { 3, 6, 10 }, { 1, 7, 6 }, { 4, 10, 7 }, { 6, 7, 10 }, + { 1, 5, 7 }, { 2, 9, 5 }, { 4, 7, 9 }, { 5, 9, 7 }, + { 1, 6, 5 }, { 2, 5, 8 }, { 3, 8, 6 }, { 5, 6, 8 } + }; + + static int pyramidtrigs[][3] = + { + { 1, 3, 2 }, + { 1, 4, 3 }, + { 1, 2, 5 }, + { 2, 3, 5 }, + { 3, 4, 5 }, + { 4, 1, 5 } + }; + + static int prismtrigs[][3] = + { + { 1, 3, 2 }, + { 4, 5, 6 }, + { 1, 2, 4 }, + { 4, 2, 5 }, + { 2, 3, 5 }, + { 5, 3, 6 }, + { 3, 1, 6 }, + { 6, 1, 4 } + }; + + static int hextrigs[][3] = + { + { 1, 3, 2 }, + { 1, 4, 3 }, + { 5, 6, 7 }, + { 5, 7, 8 }, + { 1, 2, 6 }, + { 1, 6, 5 }, + { 2, 3, 7 }, + { 2, 7, 6 }, + { 3, 4, 8 }, + { 3, 8, 7 }, + { 4, 1, 8 }, + { 1, 5, 8 } + }; + + int j; + + int nf; + int (*fp)[3]; + + switch (GetType()) + { + case TET: + { + nf = 4; + fp = tet4trigs; + break; + } + case PYRAMID: + { + nf = 6; + fp = pyramidtrigs; + break; + } + case PRISM: + case PRISM12: + { + nf = 8; + fp = prismtrigs; + break; + } + case TET10: + { + nf = 16; + fp = tet10trigs; + break; + } + case HEX: + { + nf = 12; + fp = hextrigs; + break; + } + default: + { + nf = 0; + fp = NULL; + } + } + + + surftrigs.SetSize (nf); + for (j = 0; j < nf; j++) + { + surftrigs.Elem(j+1) = Element2d(TRIG); + surftrigs.Elem(j+1).PNum(1) = fp[j][0]; + surftrigs.Elem(j+1).PNum(2) = fp[j][1]; + surftrigs.Elem(j+1).PNum(3) = fp[j][2]; + } + } + + + + + + Array< AutoPtr < IntegrationPointData > > ipdtet; + Array< AutoPtr < IntegrationPointData > > ipdtet10; + + + + int Element :: GetNIP () const + { + int nip; + switch (typ) + { + case TET: nip = 1; break; + case TET10: nip = 8; break; + default: nip = 0; break; + } + return nip; + } + + void Element :: + GetIntegrationPoint (int ip, Point<3> & p, double & weight) const + { + static double eltetqp[1][4] = + { + { 0.25, 0.25, 0.25, 1.0/6.0 } + }; + + static double eltet10qp[8][4] = + { + { 0.585410196624969, 0.138196601125011, 0.138196601125011, 1.0/24.0 }, + { 0.138196601125011, 0.585410196624969, 0.138196601125011, 1.0/24.0 }, + { 0.138196601125011, 0.138196601125011, 0.585410196624969, 1.0/24.0 }, + { 0.138196601125011, 0.138196601125011, 0.138196601125011, 1.0/24.0 }, + { 1, 0, 0, 1 }, + { 0, 1, 0, 1 }, + { 0, 0, 1, 1 }, + { 0, 0, 0, 1 }, + }; + + double * pp = NULL; + switch (typ) + { + case TET: pp = &eltetqp[0][0]; break; + case TET10: pp = &eltet10qp[ip-1][0]; break; + } + + p(0) = pp[0]; + p(1) = pp[1]; + p(2) = pp[2]; + weight = pp[3]; + } + + void Element :: + GetTransformation (int ip, const T_POINTS & points, + DenseMatrix & trans) const + { + int np = GetNP(); + DenseMatrix pmat(3, np), dshape(3, np); + pmat.SetSize (3, np); + dshape.SetSize (3, np); + + Point<3> p; + double w; + + GetPointMatrix (points, pmat); + GetIntegrationPoint (ip, p, w); + GetDShape (p, dshape); + + CalcABt (pmat, dshape, trans); + + /* + (*testout) << "p = " << p << endl + << "pmat = " << pmat << endl + << "dshape = " << dshape << endl + << "tans = " << trans << endl; + */ + } + + void Element :: + GetTransformation (int ip, class DenseMatrix & pmat, + class DenseMatrix & trans) const + { + int np = GetNP(); + + if (pmat.Width() != np || pmat.Height() != 3) + { + (*testout) << "GetTransofrmation: pmat doesn't fit" << endl; + return; + } + + ComputeIntegrationPointData (); + DenseMatrix * dshapep = 0; + switch (GetType()) + { + case TET: dshapep = &ipdtet.Get(ip)->dshape; break; + case TET10: dshapep = &ipdtet10.Get(ip)->dshape; break; + default: + PrintSysError ("Element::GetTransformation, illegal type ", int(typ)); + } + + CalcABt (pmat, *dshapep, trans); + } + + + void Element :: GetShape (const Point<3> & hp, Vector & shape) const + { + Point3d p = hp; + + if (shape.Size() != GetNP()) + { + cerr << "Element::GetShape: Length not fitting" << endl; + return; + } + + switch (typ) + { + case TET: + { + shape(0) = 1 - p.X() - p.Y() - p.Z(); + shape(1) = p.X(); + shape(2) = p.Y(); + shape(3) = p.Z(); + break; + } + case TET10: + { + double lam1 = 1 - p.X() - p.Y() - p.Z(); + double lam2 = p.X(); + double lam3 = p.Y(); + double lam4 = p.Z(); + + shape(4) = 4 * lam1 * lam2; + shape(5) = 4 * lam1 * lam3; + shape(6) = 4 * lam1 * lam4; + shape(7) = 4 * lam2 * lam3; + shape(8) = 4 * lam2 * lam4; + shape(9) = 4 * lam3 * lam4; + + shape(0) = lam1 - 0.5 * (shape(4) + shape(5) + shape(6)); + shape(1) = lam2 - 0.5 * (shape(4) + shape(7) + shape(8)); + shape(2) = lam3 - 0.5 * (shape(5) + shape(7) + shape(9)); + shape(3) = lam4 - 0.5 * (shape(6) + shape(8) + shape(9)); + break; + } + + case PRISM: + { + Point<3> hp = p; + shape(0) = hp(0) * (1-hp(2)); + shape(1) = hp(1) * (1-hp(2)); + shape(2) = (1-hp(0)-hp(1)) * (1-hp(2)); + shape(3) = hp(0) * hp(2); + shape(4) = hp(1) * hp(2); + shape(5) = (1-hp(0)-hp(1)) * hp(2); + break; + } + case HEX: + { + Point<3> hp = p; + shape(0) = (1-hp(0))*(1-hp(1))*(1-hp(2)); + shape(1) = ( hp(0))*(1-hp(1))*(1-hp(2)); + shape(2) = ( hp(0))*( hp(1))*(1-hp(2)); + shape(3) = (1-hp(0))*( hp(1))*(1-hp(2)); + shape(4) = (1-hp(0))*(1-hp(1))*( hp(2)); + shape(5) = ( hp(0))*(1-hp(1))*( hp(2)); + shape(6) = ( hp(0))*( hp(1))*( hp(2)); + shape(7) = (1-hp(0))*( hp(1))*( hp(2)); + break; + } + } + } + + + + void Element :: GetShapeNew (const Point<3> & p, FlatVector & shape) const + { + /* + if (shape.Size() < GetNP()) + { + cerr << "Element::GetShape: Length not fitting" << endl; + return; + } + */ + + switch (typ) + { + case TET: + { + shape(0) = p(0); + shape(1) = p(1); + shape(2) = p(2); + shape(3) = 1-p(0)-p(1)-p(2); + break; + } + + case TET10: + { + double lam1 = p(0); + double lam2 = p(1); + double lam3 = p(2); + double lam4 = 1-p(0)-p(1)-p(2); + + shape(0) = 2 * lam1 * (lam1-0.5); + shape(1) = 2 * lam2 * (lam2-0.5); + shape(2) = 2 * lam3 * (lam3-0.5); + shape(3) = 2 * lam4 * (lam4-0.5); + + shape(4) = 4 * lam1 * lam2; + shape(5) = 4 * lam1 * lam3; + shape(6) = 4 * lam1 * lam4; + shape(7) = 4 * lam2 * lam3; + shape(8) = 4 * lam2 * lam4; + shape(9) = 4 * lam3 * lam4; + + break; + } + + + case PYRAMID: + { + double noz = 1-p(2); + if (noz == 0.0) noz = 1e-10; + + double xi = p(0) / noz; + double eta = p(1) / noz; + shape(0) = (1-xi)*(1-eta) * (noz); + shape(1) = ( xi)*(1-eta) * (noz); + shape(2) = ( xi)*( eta) * (noz); + shape(3) = (1-xi)*( eta) * (noz); + shape(4) = p(2); + break; + } + + case PRISM: + { + shape(0) = p(0) * (1-p(2)); + shape(1) = p(1) * (1-p(2)); + shape(2) = (1-p(0)-p(1)) * (1-p(2)); + shape(3) = p(0) * p(2); + shape(4) = p(1) * p(2); + shape(5) = (1-p(0)-p(1)) * p(2); + break; + } + case HEX: + { + shape(0) = (1-p(0))*(1-p(1))*(1-p(2)); + shape(1) = ( p(0))*(1-p(1))*(1-p(2)); + shape(2) = ( p(0))*( p(1))*(1-p(2)); + shape(3) = (1-p(0))*( p(1))*(1-p(2)); + shape(4) = (1-p(0))*(1-p(1))*( p(2)); + shape(5) = ( p(0))*(1-p(1))*( p(2)); + shape(6) = ( p(0))*( p(1))*( p(2)); + shape(7) = (1-p(0))*( p(1))*( p(2)); + break; + } + } + } + + + + void Element :: + GetDShape (const Point<3> & hp, DenseMatrix & dshape) const + { + Point3d p = hp; + + int np = GetNP(); + if (dshape.Height() != 3 || dshape.Width() != np) + { + cerr << "Element::DShape: Sizes don't fit" << endl; + return; + } + + double eps = 1e-6; + Vector shaper(np), shapel(np); + + for (int i = 1; i <= 3; i++) + { + Point3d pr(p), pl(p); + pr.X(i) += eps; + pl.X(i) -= eps; + + GetShape (pr, shaper); + GetShape (pl, shapel); + for (int j = 0; j < np; j++) + dshape(i-1, j) = (shaper(j) - shapel(j)) / (2 * eps); + } + } + + + void Element :: + GetDShapeNew (const Point<3> & p, MatrixFixWidth<3> & dshape) const + { + switch (typ) + { + case TET: + { + dshape = 0; + dshape(0,0) = 1; + dshape(1,1) = 1; + dshape(2,2) = 1; + dshape(3,0) = -1; + dshape(3,1) = -1; + dshape(3,2) = -1; + break; + } + case PRISM: + { + dshape = 0; + dshape(0,0) = 1-p(2); + dshape(0,2) = -p(0); + dshape(1,1) = 1-p(2); + dshape(1,2) = -p(1); + dshape(2,0) = -(1-p(2)); + dshape(2,1) = -(1-p(2)); + dshape(2,2) = -(1-p(0)-p(1)); + + dshape(3,0) = p(2); + dshape(3,2) = p(0); + dshape(4,1) = p(2); + dshape(4,2) = p(1); + dshape(5,0) = -p(2); + dshape(5,1) = -p(2); + dshape(5,2) = 1-p(0)-p(1); + break; + } + + default: + { + int np = GetNP(); + double eps = 1e-6; + Vector shaper(np), shapel(np); + + for (int i = 1; i <= 3; i++) + { + Point3d pr(p), pl(p); + pr.X(i) += eps; + pl.X(i) -= eps; + + GetShapeNew (pr, shaper); + GetShapeNew (pl, shapel); + for (int j = 0; j < np; j++) + dshape(j, i-1) = (shaper(j) - shapel(j)) / (2 * eps); + } + } + } + } + + void Element :: + GetPointMatrix (const T_POINTS & points, + DenseMatrix & pmat) const + { + int np = GetNP(); + for (int i = 1; i <= np; i++) + { + const Point3d & p = points.Get(PNum(i)); + pmat.Elem(1, i) = p.X(); + pmat.Elem(2, i) = p.Y(); + pmat.Elem(3, i) = p.Z(); + } + } + + + + + double Element :: CalcJacobianBadness (const T_POINTS & points) const + { + int nip = GetNIP(); + DenseMatrix trans(3,3); + DenseMatrix pmat; + + pmat.SetSize (3, GetNP()); + GetPointMatrix (points, pmat); + + double err = 0; + for (int i = 1; i <= nip; i++) + { + GetTransformation (i, pmat, trans); + + // Frobenius norm + double frob = 0; + for (int j = 1; j <= 9; j++) + frob += sqr (trans.Get(j)); + frob = sqrt (frob); + frob /= 3; + + double det = -trans.Det(); + + if (det <= 0) + err += 1e12; + else + err += frob * frob * frob / det; + } + + err /= nip; + return err; + } + + double Element :: + CalcJacobianBadnessDirDeriv (const T_POINTS & points, + int pi, Vec<3> & dir, double & dd) const + { + int i, j, k; + int nip = GetNIP(); + DenseMatrix trans(3,3), dtrans(3,3), hmat(3,3); + DenseMatrix pmat, vmat; + + pmat.SetSize (3, GetNP()); + vmat.SetSize (3, GetNP()); + + GetPointMatrix (points, pmat); + + for (i = 1; i <= np; i++) + for (j = 1; j <= 3; j++) + vmat.Elem(j, i) = 0; + for (j = 1; j <= 3; j++) + vmat.Elem(j, pi) = dir(j-1); + + + + double err = 0; + dd = 0; + + for (i = 1; i <= nip; i++) + { + GetTransformation (i, pmat, trans); + GetTransformation (i, vmat, dtrans); + + + // Frobenius norm + double frob = 0; + for (j = 1; j <= 9; j++) + frob += sqr (trans.Get(j)); + frob = sqrt (frob); + + double dfrob = 0; + for (j = 1; j <= 9; j++) + dfrob += trans.Get(j) * dtrans.Get(j); + dfrob = dfrob / frob; + + frob /= 3; + dfrob /= 3; + + + double det = trans.Det(); + double ddet = 0; + + for (j = 1; j <= 3; j++) + { + hmat = trans; + for (k = 1; k <= 3; k++) + hmat.Elem(k, j) = dtrans.Get(k, j); + ddet += hmat.Det(); + } + + + det *= -1; + ddet *= -1; + + + if (det <= 0) + err += 1e12; + else + { + err += frob * frob * frob / det; + dd += (3 * frob * frob * dfrob * det - frob * frob * frob * ddet) / (det * det); + } + } + + err /= nip; + dd /= nip; + return err; + } + + double Element :: + CalcJacobianBadnessGradient (const T_POINTS & points, + int pi, Vec<3> & grad) const + { + int nip = GetNIP(); + DenseMatrix trans(3,3), dtrans(3,3), hmat(3,3); + DenseMatrix pmat, vmat; + + pmat.SetSize (3, GetNP()); + vmat.SetSize (3, GetNP()); + + GetPointMatrix (points, pmat); + + for (int i = 1; i <= np; i++) + for (int j = 1; j <= 3; j++) + vmat.Elem(j, i) = 0; + for (int j = 1; j <= 3; j++) + vmat.Elem(j, pi) = 1.; + + + double err = 0; + + double dfrob[3]; + + grad = 0; + + for (int i = 1; i <= nip; i++) + { + GetTransformation (i, pmat, trans); + GetTransformation (i, vmat, dtrans); + + // Frobenius norm + double frob = 0; + for (int j = 1; j <= 9; j++) + frob += sqr (trans.Get(j)); + frob = sqrt (frob); + + for(int k = 0; k<3; k++) + { + dfrob[k] = 0; + for (int j = 1; j <= 3; j++) + dfrob[k] += trans.Get(k+1,j) * dtrans.Get(k+1,j); + dfrob[k] = dfrob[k] / (3.*frob); + } + + frob /= 3; + + double det = trans.Det(); + double ddet[3]; // = 0; + + for(int k=1; k<=3; k++) + { + int km1 = (k > 1) ? (k-1) : 3; + int kp1 = (k < 3) ? (k+1) : 1; + ddet[k-1] = 0; + for(int j=1; j<=3; j++) + { + int jm1 = (j > 1) ? (j-1) : 3; + int jp1 = (j < 3) ? (j+1) : 1; + + ddet[k-1] += (-1.)* dtrans.Get(k,j) * ( trans.Get(km1,jm1)*trans.Get(kp1,jp1) - + trans.Get(km1,jp1)*trans.Get(kp1,jm1) ); + } + } + + + det *= -1; + + if (det <= 0) + err += 1e12; + else + { + err += frob * frob * frob / det; + double fac = (frob * frob)/(det * det); + for(int j=0; j<3; j++) + grad(j) += fac * (3 * dfrob[j] * det - frob * ddet[j]); + } + } + + err /= nip; + grad *= 1./nip; + return err; + } + + + + + + void Element :: ComputeIntegrationPointData () const + { + switch (GetType()) + { + case TET: if (ipdtet.Size()) return; break; + case TET10: if (ipdtet10.Size()) return; break; + default: + PrintSysError ("Element::ComputeIntegrationPoint, illegal type ", int(typ)); + } + + switch (GetType()) + { + case TET: ipdtet.SetSize(GetNIP()); break; + case TET10: ipdtet10.SetSize(GetNIP()); break; + default: + PrintSysError ("Element::ComputeIntegrationPoint, illegal type2 ", int(typ)); + } + + + for (int i = 1; i <= GetNIP(); i++) + { + IntegrationPointData * ipd = new IntegrationPointData; + GetIntegrationPoint (i, ipd->p, ipd->weight); + ipd->shape.SetSize(GetNP()); + ipd->dshape.SetSize(3, GetNP()); + + GetShape (ipd->p, ipd->shape); + GetDShape (ipd->p, ipd->dshape); + + switch (GetType()) + { + case TET: ipdtet.Elem(i).Reset(ipd); break; + case TET10: ipdtet10.Elem(i).Reset(ipd); break; + default: + PrintSysError ("Element::ComputeIntegrationPoint(2), illegal type ", int(typ)); + } + } + } + + + + + + + + FaceDescriptor :: FaceDescriptor() + { + surfnr = domin = domout = bcprop = 0; + domin_singular = domout_singular = 0.; + // Philippose - 06/07/2009 + // Initialise surface colour + surfcolour = Vec3d(0.0,1.0,0.0); + tlosurf = -1; + bcname = 0; + firstelement = -1; + } + + FaceDescriptor :: FaceDescriptor(const FaceDescriptor& other) + : surfnr(other.surfnr), domin(other.domin), domout(other.domout), + tlosurf(other.tlosurf), bcprop(other.bcprop), + surfcolour(other.surfcolour), bcname(other.bcname), + domin_singular(other.domin_singular), domout_singular(other.domout_singular) + { + firstelement = -1; + } + + FaceDescriptor :: + FaceDescriptor(int surfnri, int domini, int domouti, int tlosurfi) + { + surfnr = surfnri; + domin = domini; + domout = domouti; + // Philippose - 06/07/2009 + // Initialise surface colour + surfcolour = Vec3d(0.0,1.0,0.0); + tlosurf = tlosurfi; + bcprop = surfnri; + domin_singular = domout_singular = 0.; + bcname = 0; + firstelement = -1; + } + + FaceDescriptor :: FaceDescriptor(const Segment & seg) + { + surfnr = seg.si; + domin = seg.domin+1; + domout = seg.domout+1; + // Philippose - 06/07/2009 + // Initialise surface colour + surfcolour = Vec3d(0.0,1.0,0.0); + tlosurf = seg.tlosurf+1; + bcprop = 0; + domin_singular = domout_singular = 0.; + bcname = 0; + firstelement = -1; + } + + int FaceDescriptor :: SegmentFits (const Segment & seg) + { + return + surfnr == seg.si && + domin == seg.domin+1 && + domout == seg.domout+1 && + tlosurf == seg.tlosurf+1; + } + + + const string & FaceDescriptor :: GetBCName () const + { + static string defaultstring = "default"; + if (bcname) return *bcname; + return defaultstring; + } + + /* + void FaceDescriptor :: SetBCName (string * bcn) + { + bcname = bcn; + } + */ + + + ostream & operator<<(ostream & s, const FaceDescriptor & fd) + { + s << "surfnr = " << fd.SurfNr() + << ", domin = " << fd.DomainIn() + << ", domout = " << fd.DomainOut() + << ", tlosurf = " << fd.TLOSurface() + << ", bcprop = " << fd.BCProperty() + << ", domin_sing = " << fd.DomainInSingular() + << ", domout_sing = " << fd.DomainOutSingular() + << ", colour = " << fd.SurfColour(); + return s; + } + + + + + + + Identifications :: Identifications (Mesh & amesh) + : mesh(amesh) + { + identifiedpoints = new INDEX_2_HASHTABLE(100); + identifiedpoints_nr = new INDEX_3_HASHTABLE(100); + maxidentnr = 0; + } + + Identifications :: ~Identifications () + { + delete identifiedpoints; + delete identifiedpoints_nr; + } + + void Identifications :: Delete () + { + delete identifiedpoints; + identifiedpoints = new INDEX_2_HASHTABLE(100); + delete identifiedpoints_nr; + identifiedpoints_nr = new INDEX_3_HASHTABLE(100); + maxidentnr = 0; + } + + void Identifications :: Add (PointIndex pi1, PointIndex pi2, int identnr) + { + // (*testout) << "Identification::Add, pi1 = " << pi1 << ", pi2 = " << pi2 << ", identnr = " << identnr << endl; + INDEX_2 pair (pi1, pi2); + identifiedpoints->Set (pair, identnr); + + INDEX_3 tripl (pi1, pi2, identnr); + identifiedpoints_nr->Set (tripl, 1); + + if (identnr > maxidentnr) maxidentnr = identnr; + + if (identnr+1 > idpoints_table.Size()) + idpoints_table.ChangeSize (identnr+1); + idpoints_table.Add (identnr, pair); + + // timestamp = NextTimeStamp(); + } + + int Identifications :: Get (PointIndex pi1, PointIndex pi2) const + { + INDEX_2 pair(pi1, pi2); + if (identifiedpoints->Used (pair)) + return identifiedpoints->Get(pair); + else + return 0; + } + + bool Identifications :: Get (PointIndex pi1, PointIndex pi2, int nr) const + { + INDEX_3 tripl(pi1, pi2, nr); + if (identifiedpoints_nr->Used (tripl)) + return 1; + else + return 0; + } + + + + int Identifications :: GetSymmetric (PointIndex pi1, PointIndex pi2) const + { + INDEX_2 pair(pi1, pi2); + if (identifiedpoints->Used (pair)) + return identifiedpoints->Get(pair); + + pair = INDEX_2 (pi2, pi1); + if (identifiedpoints->Used (pair)) + return identifiedpoints->Get(pair); + + return 0; + } + + + void Identifications :: GetMap (int identnr, Array & identmap, bool symmetric) const + { + identmap.SetSize (mesh.GetNP()); + identmap = 0; + + if (identnr) + for (int i = 0; i < idpoints_table[identnr].Size(); i++) + { + INDEX_2 pair = idpoints_table[identnr][i]; + identmap[pair.I1()] = pair.I2(); + if(symmetric) + identmap[pair.I2()] = pair.I1(); + } + + else + { + cout << "getmap, identnr = " << identnr << endl; + + for (int i = 1; i <= identifiedpoints_nr->GetNBags(); i++) + for (int j = 1; j <= identifiedpoints_nr->GetBagSize(i); j++) + { + INDEX_3 i3; + int dummy; + identifiedpoints_nr->GetData (i, j, i3, dummy); + + if (i3.I3() == identnr || !identnr) + { + identmap.Elem(i3.I1()) = i3.I2(); + if(symmetric) + identmap.Elem(i3.I2()) = i3.I1(); + } + } + } + + } + + + void Identifications :: GetPairs (int identnr, + Array & identpairs) const + { + identpairs.SetSize(0); + + if (identnr == 0) + for (int i = 1; i <= identifiedpoints->GetNBags(); i++) + for (int j = 1; j <= identifiedpoints->GetBagSize(i); j++) + { + INDEX_2 i2; + int nr; + identifiedpoints->GetData (i, j, i2, nr); + identpairs.Append (i2); + } + else + for (int i = 1; i <= identifiedpoints_nr->GetNBags(); i++) + for (int j = 1; j <= identifiedpoints_nr->GetBagSize(i); j++) + { + INDEX_3 i3; + int dummy; + identifiedpoints_nr->GetData (i, j, i3 , dummy); + + if (i3.I3() == identnr) + identpairs.Append (INDEX_2(i3.I1(), i3.I2())); + } + } + + + void Identifications :: SetMaxPointNr (int maxpnum) + { + for (int i = 1; i <= identifiedpoints->GetNBags(); i++) + for (int j = 1; j <= identifiedpoints->GetBagSize(i); j++) + { + INDEX_2 i2; + int nr; + identifiedpoints->GetData (i, j, i2, nr); + + if (i2.I1() > maxpnum || i2.I2() > maxpnum) + { + i2.I1() = i2.I2() = -1; + identifiedpoints->SetData (i, j, i2, -1); + } + } + } + + + void Identifications :: Print (ostream & ost) const + { + ost << "Identifications:" << endl; + ost << "pairs: " << endl << *identifiedpoints << endl; + ost << "pairs and nr: " << endl << *identifiedpoints_nr << endl; + ost << "table: " << endl << idpoints_table << endl; + } + + + MeshingParameters :: MeshingParameters () + { + optimize3d = "cmdmustm"; + //optimize3d = "cmdmstm"; + optsteps3d = 3; + optimize2d = "smsmsmSmSmSm"; + optsteps2d = 3; + opterrpow = 2; + blockfill = 1; + filldist = 0.1; + safety = 5; + relinnersafety = 3; + uselocalh = 1; + grading = 0.3; + delaunay = 1; + maxh = 1e10; + minh = 0; + meshsizefilename = NULL; + startinsurface = 0; + checkoverlap = 1; + checkoverlappingboundary = 1; + checkchartboundary = 1; + curvaturesafety = 2; + segmentsperedge = 1; + parthread = 0; + + elsizeweight = 0.2; + giveuptol2d = 200; + giveuptol = 10; + maxoutersteps = 10; + starshapeclass = 5; + baseelnp = 0; + sloppy = 1; + + badellimit = 175; + check_impossible = 0; + secondorder = 0; + } + + void MeshingParameters :: Print (ostream & ost) const + { + ost << "Meshing parameters: " << endl + << "optimize3d = " << optimize3d << endl + << "optsteps3d = " << optsteps3d << endl + << " optimize2d = " << optimize2d << endl + << " optsteps2d = " << optsteps2d << endl + << " opterrpow = " << opterrpow << endl + << " blockfill = " << blockfill << endl + << " filldist = " << filldist << endl + << " safety = " << safety << endl + << " relinnersafety = " << relinnersafety << endl + << " uselocalh = " << uselocalh << endl + << " grading = " << grading << endl + << " delaunay = " << delaunay << endl + << " maxh = " << maxh << endl; + if(meshsizefilename) + ost << " meshsizefilename = " << meshsizefilename << endl; + else + ost << " meshsizefilename = NULL" << endl; + ost << " startinsurface = " << startinsurface << endl + << " checkoverlap = " << checkoverlap << endl + << " checkchartboundary = " << checkchartboundary << endl + << " curvaturesafety = " << curvaturesafety << endl + << " segmentsperedge = " << segmentsperedge << endl + << " parthread = " << parthread << endl + << " elsizeweight = " << elsizeweight << endl + << " giveuptol2d = " << giveuptol2d << endl + << " giveuptol = " << giveuptol << endl + << " maxoutersteps = " << maxoutersteps << endl + << " starshapeclass = " << starshapeclass << endl + << " baseelnp = " << baseelnp << endl + << " sloppy = " << sloppy << endl + << " badellimit = " << badellimit << endl + << " secondorder = " << secondorder << endl + << " elementorder = " << elementorder << endl + << " quad = " << quad << endl + << " inverttets = " << inverttets << endl + << " inverttrigs = " << inverttrigs << endl; + } + + void MeshingParameters :: CopyFrom(const MeshingParameters & other) + { + //strcpy(optimize3d,other.optimize3d); + optimize3d = other.optimize3d; + optsteps3d = other.optsteps3d; + //strcpy(optimize2d,other.optimize2d); + optimize2d = other.optimize2d; + optsteps2d = other.optsteps2d; + opterrpow = other.opterrpow; + blockfill = other.blockfill; + filldist = other.filldist; + safety = other.safety; + relinnersafety = other.relinnersafety; + uselocalh = other.uselocalh; + grading = other.grading; + delaunay = other.delaunay; + maxh = other.maxh; + //strcpy(const_cast(meshsizefilename), other.meshsizefilename); + //const_cast(meshsizefilename) = other.meshsizefilename; //??? + startinsurface = other.startinsurface; + checkoverlap = other.checkoverlap; + checkoverlappingboundary = other.checkoverlappingboundary; + checkchartboundary = other.checkchartboundary; + curvaturesafety = other.curvaturesafety; + segmentsperedge = other.segmentsperedge; + parthread = other.parthread; + elsizeweight = other.elsizeweight; + giveuptol2d = other.giveuptol2d; + giveuptol = other.giveuptol; + maxoutersteps = other.maxoutersteps; + starshapeclass = other.starshapeclass; + baseelnp = other.baseelnp; + sloppy = other.sloppy; + badellimit = other.badellimit; + secondorder = other.secondorder; + elementorder = other.elementorder; + quad = other.quad; + inverttets = other.inverttets; + inverttrigs = other.inverttrigs; + } + + + DebugParameters :: DebugParameters () + { + slowchecks = 0; + haltsuccess = 0; + haltnosuccess = 0; + haltlargequalclass = 0; + haltsegment = 0; + haltsegmentp1 = 0; + haltsegmentp2 = 0; + }; + + + +} + diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp new file mode 100644 index 00000000..ceaed59d --- /dev/null +++ b/libsrc/meshing/meshtype.hpp @@ -0,0 +1,1301 @@ +#ifndef MESHTYPE +#define MESHTYPE + + +/**************************************************************************/ +/* File: meshtype.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 01. Okt. 95 */ +/**************************************************************************/ + +namespace netgen +{ + + /* + Classes for NETGEN + */ + + + + enum ELEMENT_TYPE { + SEGMENT = 1, SEGMENT3 = 2, + TRIG = 10, QUAD=11, TRIG6 = 12, QUAD6 = 13, QUAD8 = 14, + TET = 20, TET10 = 21, + PYRAMID = 22, PRISM = 23, PRISM12 = 24, + HEX = 25 + }; + + typedef int ELEMENT_EDGE[2]; // initial point, end point + typedef int ELEMENT_FACE[4]; // points, last one is -1 for trig + + +#define ELEMENT_MAXPOINTS 12 +#define ELEMENT2D_MAXPOINTS 8 + + + enum POINTTYPE { FIXEDPOINT = 1, EDGEPOINT = 2, SURFACEPOINT = 3, INNERPOINT = 4 }; + enum ELEMENTTYPE { FREEELEMENT, FIXEDELEMENT }; + enum OPTIMIZEGOAL { OPT_QUALITY, OPT_CONFORM, OPT_REST, OPT_WORSTCASE, OPT_LEGAL }; + + + + extern DLL_HEADER int GetTimeStamp(); + extern DLL_HEADER int NextTimeStamp(); + + class PointGeomInfo + { + public: + int trignum; // for STL Meshing + double u, v; // for OCC Meshing + + PointGeomInfo () + : trignum(-1), u(0), v(0) { ; } + }; + + inline ostream & operator<< (ostream & ost, const PointGeomInfo & gi) + { + return (ost << gi.trignum << " " << gi.u << " " << gi.v); + } + + inline istream & operator>> (istream & ist, PointGeomInfo & gi) + { + return (ist >> gi.trignum >> gi.u >> gi.v); + } + + + +#define MULTIPOINTGEOMINFO_MAX 100 + class MultiPointGeomInfo + { + int cnt; + PointGeomInfo mgi[MULTIPOINTGEOMINFO_MAX]; + public: + MultiPointGeomInfo () { cnt = 0; } + int AddPointGeomInfo (const PointGeomInfo & gi); + void Init () { cnt = 0; } + void DeleteAll () { cnt = 0; } + + int GetNPGI () const { return cnt; } + const PointGeomInfo & GetPGI (int i) const { return mgi[i-1]; } + }; + + + class EdgePointGeomInfo + { + public: + int edgenr; + int body; // for ACIS + double dist; // for 2d meshing + double u, v; // for OCC Meshing + + public: + EdgePointGeomInfo () + : edgenr(0), body(0), dist(0.0), u(0.0), v(0.0) { ; } + + + EdgePointGeomInfo & operator= (const EdgePointGeomInfo & gi2) + { + edgenr = gi2.edgenr; + body = gi2.body; + dist = gi2.dist; + u = gi2.u; v = gi2.v; + return *this; + } + }; + + inline ostream & operator<< (ostream & ost, const EdgePointGeomInfo & gi) + { + ost << "epgi: edgnr=" << gi.edgenr << ", dist=" << gi.dist; + return ost; + } + + + + + + class PointIndex + { + int i; + public: + PointIndex () { ; } + PointIndex (int ai) : i(ai) { ; } + PointIndex & operator= (const PointIndex &ai) { i = ai.i; return *this; } + // PointIndex & operator= (int ai) { i = ai; return *this; } + operator int () const { return i; } + // int GetInt () const { return i; } + // PointIndex operator+ (int i2) { return PointIndex (i+i2); } + // PointIndex operator++ (int) { int hi = i; i++; return PointIndex(hi); } + // PointIndex operator-- (int) { int hi = i; i--; return PointIndex(hi); } + PointIndex operator++ (int) { PointIndex hi(*this); i++; return hi; } + PointIndex operator-- (int) { PointIndex hi(*this); i--; return hi; } + PointIndex operator++ () { i++; return *this; } + PointIndex operator-- () { i--; return *this; } + +#ifdef BASE0 + enum { BASE = 0 }; +#else + enum { BASE = 1 }; +#endif + }; + + inline istream & operator>> (istream & ist, PointIndex & pi) + { + int i; ist >> i; pi = i; return ist; + } + + inline ostream & operator<< (ostream & ost, const PointIndex & pi) + { + return (ost << int(pi)); + } + + + + + class ElementIndex + { + int i; + public: + ElementIndex () { ; } + ElementIndex (int ai) : i(ai) { ; } + ElementIndex & operator= (const ElementIndex & ai) { i = ai.i; return *this; } + ElementIndex & operator= (int ai) { i = ai; return *this; } + operator int () const { return i; } + ElementIndex & operator++ (int) { i++; return *this; } + ElementIndex & operator-- (int) { i--; return *this; } + }; + + inline istream & operator>> (istream & ist, ElementIndex & pi) + { + int i; ist >> i; pi = i; return ist; + } + + inline ostream & operator<< (ostream & ost, const ElementIndex & pi) + { + return (ost << int(pi)); + } + + + class SurfaceElementIndex + { + int i; + public: + SurfaceElementIndex () { ; } + SurfaceElementIndex (int ai) : i(ai) { ; } + SurfaceElementIndex & operator= (const SurfaceElementIndex & ai) + { i = ai.i; return *this; } + SurfaceElementIndex & operator= (int ai) { i = ai; return *this; } + operator int () const { return i; } + SurfaceElementIndex & operator++ (int) { i++; return *this; } + SurfaceElementIndex & operator+= (int inc) { i+=inc; return *this; } + SurfaceElementIndex & operator-- (int) { i--; return *this; } + }; + + inline istream & operator>> (istream & ist, SurfaceElementIndex & pi) + { + int i; ist >> i; pi = i; return ist; + } + + inline ostream & operator<< (ostream & ost, const SurfaceElementIndex & pi) + { + return (ost << int(pi)); + } + + class SegmentIndex + { + int i; + public: + SegmentIndex () { ; } + SegmentIndex (int ai) : i(ai) { ; } + SegmentIndex & operator= (const SegmentIndex & ai) + { i = ai.i; return *this; } + SegmentIndex & operator= (int ai) { i = ai; return *this; } + operator int () const { return i; } + SegmentIndex & operator++ (int) { i++; return *this; } + SegmentIndex & operator-- (int) { i--; return *this; } + }; + + inline istream & operator>> (istream & ist, SegmentIndex & pi) + { + int i; ist >> i; pi = i; return ist; + } + + inline ostream & operator<< (ostream & ost, const SegmentIndex & pi) + { + return (ost << int(pi)); + } + + + + + /** + Point in the mesh. + Contains layer (a new feature in 4.3 for overlapping meshes. + */ + class MeshPoint : public Point<3> + { + int layer; + double singular; // singular factor for hp-refinement + POINTTYPE type; + + + public: + MeshPoint () + { + ; + } + + MeshPoint (const Point<3> & ap, int alayer = 1, POINTTYPE apt = INNERPOINT) + : Point<3> (ap), layer(alayer), singular(0.),type(apt) + { + ; + } + + void SetPoint (const Point<3> & ap) + { + Point<3>::operator= (ap); + layer = 0; + singular = 0; + } + + int GetLayer() const { return layer; } + + POINTTYPE Type() const { return type; } + void SetType(POINTTYPE at) { type = at; } + + double Singularity() const { return singular; } + void Singularity(double s) { singular = s; } + bool IsSingular() const { return (singular != 0.0); } + +#ifdef PARALLEL + static MPI_Datatype MyGetMPIType ( ); +#endif + + }; + + inline ostream & operator<<(ostream & s, const MeshPoint & pt) + { + return (s << Point<3> (pt)); + } + + + + + typedef Array T_POINTS; + + + + /** + Triangle element for surface mesh generation. + */ + class Element2d + { + /// point numbers + PointIndex pnum[ELEMENT2D_MAXPOINTS]; + /// geom info of points + PointGeomInfo geominfo[ELEMENT2D_MAXPOINTS]; + + /// surface nr + int index:16; + /// + ELEMENT_TYPE typ:6; + /// number of points + unsigned int np:4; + bool badel:1; + bool refflag:1; // marked for refinement + bool strongrefflag:1; + bool deleted:1; // element is deleted + + // Philippose - 08 August 2010 + // Set a new property for each element, to + // control whether it is visible or not + bool visible:1; // element visible + + /// order for hp-FEM + unsigned int orderx:6; + unsigned int ordery:6; + +#ifdef PARALLEL + int partitionNumber; +#endif + + /// a linked list for all segments in the same face + SurfaceElementIndex next; + + public: + /// + Element2d (); + /// + Element2d (int anp); + /// + DLL_HEADER Element2d (ELEMENT_TYPE type); + /// + Element2d (int pi1, int pi2, int pi3); + /// + Element2d (int pi1, int pi2, int pi3, int pi4); + /// + ELEMENT_TYPE GetType () const { return typ; } + /// + void SetType (ELEMENT_TYPE atyp) + { + typ = atyp; + switch (typ) + { + case TRIG: np = 3; break; + case QUAD: np = 4; break; + case TRIG6: np = 6; break; + case QUAD6: np = 6; break; + case QUAD8: np = 8; break; + default: + PrintSysError ("Element2d::SetType, illegal type ", typ); + } + } + /// + int GetNP() const { return np; } + /// + int GetNV() const + { + switch (typ) + { + case TRIG: + case TRIG6: return 3; + + case QUAD: + case QUAD8: + case QUAD6: return 4; + default: +#ifdef DEBUG + PrintSysError ("element2d::GetNV not implemented for typ", typ) +#endif + ; + } + return np; + } + + /// + PointIndex & operator[] (int i) { return pnum[i]; } + /// + const PointIndex & operator[] (int i) const { return pnum[i]; } + + FlatArray PNums () const + { return FlatArray (np, &pnum[0]); } + + /// + PointIndex & PNum (int i) { return pnum[i-1]; } + /// + const PointIndex & PNum (int i) const { return pnum[i-1]; } + /// + PointIndex & PNumMod (int i) { return pnum[(i-1) % np]; } + /// + const PointIndex & PNumMod (int i) const { return pnum[(i-1) % np]; } + /// + + /// + PointGeomInfo & GeomInfoPi (int i) { return geominfo[i-1]; } + /// + const PointGeomInfo & GeomInfoPi (int i) const { return geominfo[i-1]; } + /// + PointGeomInfo & GeomInfoPiMod (int i) { return geominfo[(i-1) % np]; } + /// + const PointGeomInfo & GeomInfoPiMod (int i) const { return geominfo[(i-1) % np]; } + + + void SetIndex (int si) { index = si; } + /// + int GetIndex () const { return index; } + + int GetOrder () const { return orderx; } + void SetOrder (int aorder) { orderx = ordery = aorder; } + + + void GetOrder (int & ox, int & oy) const { ox = orderx, oy =ordery;}; + void GetOrder (int & ox, int & oy, int & oz) const { ox = orderx; oy = ordery; oz=0; } + void SetOrder (int ox, int oy, int /* oz */) { orderx = ox; ordery = oy;} + void SetOrder (int ox, int oy) { orderx = ox; ordery = oy;} + + + /// + void GetBox (const T_POINTS & points, Box3d & box) const; + /// invert orientation + inline void Invert (); + /// + void Invert2 (); + /// first point number is smallest + inline void NormalizeNumbering (); + /// + void NormalizeNumbering2 (); + + bool BadElement() const { return badel; } + + // friend ostream & operator<<(ostream & s, const Element2d & el); + friend class Mesh; + + + /// get number of 'integration points' + int GetNIP () const; + void GetIntegrationPoint (int ip, Point2d & p, double & weight) const; + + void GetTransformation (int ip, const Array & points, + class DenseMatrix & trans) const; + void GetTransformation (int ip, class DenseMatrix & pmat, + class DenseMatrix & trans) const; + + void GetShape (const Point2d & p, class Vector & shape) const; + void GetShapeNew (const Point<2> & p, class FlatVector & shape) const; + /// matrix 2 * np + void GetDShape (const Point2d & p, class DenseMatrix & dshape) const; + void GetDShapeNew (const Point<2> & p, class MatrixFixWidth<2> & dshape) const; + /// matrix 2 * np + void GetPointMatrix (const Array & points, + class DenseMatrix & pmat) const; + + void ComputeIntegrationPointData () const; + + + double CalcJacobianBadness (const Array & points) const; + double CalcJacobianBadness (const T_POINTS & points, + const Vec<3> & n) const; + double CalcJacobianBadnessDirDeriv (const Array & points, + int pi, Vec2d & dir, double & dd) const; + + + + void Delete () { deleted = 1; pnum[0] = pnum[1] = pnum[2] = pnum[3] = PointIndex::BASE-1; } + bool IsDeleted () const + { +#ifdef DEBUG + if (pnum[0] < PointIndex::BASE && !deleted) + cerr << "Surfelement has illegal pnum, but not marked as deleted" << endl; +#endif + return deleted; + } + + // Philippose - 08 August 2010 + // Access functions for the new property: visible + void Visible(bool vis = 1) + { visible = vis; } + bool IsVisible () const + { return visible; } + + void SetRefinementFlag (bool rflag = 1) + { refflag = rflag; } + bool TestRefinementFlag () const + { return refflag; } + + void SetStrongRefinementFlag (bool rflag = 1) + { strongrefflag = rflag; } + bool TestStrongRefinementFlag () const + { return strongrefflag; } + + + SurfaceElementIndex NextElement() { return next; } + + bool operator==(const Element2d & el2) const; + + int HasFace(const Element2d& el) const; + /// + int meshdocval; + /// + int hp_elnr; + +#ifdef PARALLEL + int GetPartition () const { return partitionNumber; } + void SetPartition (int nr) { partitionNumber = nr; }; +#endif + }; + + + ostream & operator<<(ostream & s, const Element2d & el); + + + + + + class IntegrationPointData + { + public: + Point<3> p; + double weight; + Vector shape; + DenseMatrix dshape; + }; + + + + + + + + + /** + Volume element + */ + class Element + { + private: + /// point numbers + PointIndex pnum[ELEMENT_MAXPOINTS]; + /// + ELEMENT_TYPE typ:6; + /// number of points (4..tet, 5..pyramid, 6..prism, 8..hex, 10..quad tet, 12..quad prism) + int np:5; + /// + class flagstruct { + public: + bool marked:1; // marked for refinement + bool badel:1; // angles worse then limit + bool reverse:1; // for refinement a la Bey + bool illegal:1; // illegal, will be split or swaped + bool illegal_valid:1; // is illegal-flag valid ? + bool badness_valid:1; // is badness valid ? + bool refflag:1; // mark element for refinement + bool strongrefflag:1; + bool deleted:1; // element is deleted, will be removed from array + bool fixed:1; // don't change element in optimization + }; + + /// sub-domain index + short int index; + /// order for hp-FEM + unsigned int orderx:6; + unsigned int ordery:6; + unsigned int orderz:6; + /* unsigned int levelx:6; + unsigned int levely:6; + unsigned int levelz:6; */ + /// stored shape-badness of element + float badness; + +#ifdef PARALLEL + /// number of partition for parallel computation + int partitionNumber; + +#endif + + public: + flagstruct flags; + + /// + Element (); + /// + Element (int anp); + /// + Element (ELEMENT_TYPE type); + /// + Element & operator= (const Element & el2); + + /// + void SetNP (int anp); + /// + void SetType (ELEMENT_TYPE atyp); + /// + int GetNP () const { return np; } + /// + int GetNV() const + { + switch (typ) + { + case TET: + case TET10: + return 4; + case PRISM12: + case PRISM: + return 6; + case PYRAMID: + return 5; + case HEX: + return 8; + default: +#ifdef DEBUG + PrintSysError ("Element3d::GetNV not implemented for typ ", typ) +#endif + ; + } + return np; + } + + bool operator==(const Element & el2) const; + + // old style: + int NP () const { return np; } + + /// + ELEMENT_TYPE GetType () const { return typ; } + + /// + PointIndex & operator[] (int i) { return pnum[i]; } + /// + const PointIndex & operator[] (int i) const { return pnum[i]; } + + FlatArray PNums () const + { return FlatArray (np, &pnum[0]); } + + /// + PointIndex & PNum (int i) { return pnum[i-1]; } + /// + const PointIndex & PNum (int i) const { return pnum[i-1]; } + /// + PointIndex & PNumMod (int i) { return pnum[(i-1) % np]; } + /// + const PointIndex & PNumMod (int i) const { return pnum[(i-1) % np]; } + + /// + void SetIndex (int si) { index = si; } + /// + int GetIndex () const { return index; } + + int GetOrder () const { return orderx; } + void SetOrder (const int aorder) ; + + void GetOrder (int & ox, int & oy, int & oz) const { ox = orderx; oy = ordery; oz = orderz; } + void SetOrder (const int ox, const int oy, const int oz); + // void GetLevel (int & ox, int & oy, int & oz) const { ox = levelx; oy = levely; oz = levelz; } + // void SetLevel (int ox, int oy, int oz) { levelx = ox; levely = oy; levelz = oz; } + + + /// + void GetBox (const T_POINTS & points, Box3d & box) const; + /// Calculates Volume of elemenet + double Volume (const T_POINTS & points) const; + /// + virtual void Print (ostream & ost) const; + /// + int GetNFaces () const + { + switch (typ) + { + case TET: + case TET10: return 4; + case PYRAMID: return 5; + case PRISM: + case PRISM12: return 5; + default: +#ifdef DEBUG + PrintSysError ("element3d::GetNFaces not implemented for typ", typ) +#endif + ; + } + return 0; + } + /// + inline void GetFace (int i, Element2d & face) const; + /// + void GetFace2 (int i, Element2d & face) const; + /// + void Invert (); + + /// split into 4 node tets + void GetTets (Array & locels) const; + /// split into 4 node tets, local point nrs + void GetTetsLocal (Array & locels) const; + /// returns coordinates of nodes + // void GetNodesLocal (Array > & points) const; + void GetNodesLocalNew (Array > & points) const; + + /// split surface into 3 node trigs + void GetSurfaceTriangles (Array & surftrigs) const; + + + /// get number of 'integration points' + int GetNIP () const; + void GetIntegrationPoint (int ip, Point<3> & p, double & weight) const; + + void GetTransformation (int ip, const T_POINTS & points, + class DenseMatrix & trans) const; + void GetTransformation (int ip, class DenseMatrix & pmat, + class DenseMatrix & trans) const; + + void GetShape (const Point<3> & p, class Vector & shape) const; + void GetShapeNew (const Point<3> & p, class FlatVector & shape) const; + /// matrix 2 * np + void GetDShape (const Point<3> & p, class DenseMatrix & dshape) const; + void GetDShapeNew (const Point<3> & p, class MatrixFixWidth<3> & dshape) const; + /// matrix 3 * np + void GetPointMatrix (const T_POINTS & points, + class DenseMatrix & pmat) const; + + void ComputeIntegrationPointData () const; + + + double CalcJacobianBadness (const T_POINTS & points) const; + double CalcJacobianBadnessDirDeriv (const T_POINTS & points, + int pi, Vec<3> & dir, double & dd) const; + double CalcJacobianBadnessGradient (const T_POINTS & points, + int pi, Vec<3> & grad) const; + + /// + // friend ostream & operator<<(ostream & s, const Element & el); + + void SetRefinementFlag (bool rflag = 1) + { flags.refflag = rflag; } + int TestRefinementFlag () const + { return flags.refflag; } + + void SetStrongRefinementFlag (bool rflag = 1) + { flags.strongrefflag = rflag; } + int TestStrongRefinementFlag () const + { return flags.strongrefflag; } + + int Illegal () const + { return flags.illegal; } + int IllegalValid () const + { return flags.illegal_valid; } + void SetIllegal (int aillegal) + { + flags.illegal = aillegal ? 1 : 0; + flags.illegal_valid = 1; + } + void SetLegal (int alegal) + { + flags.illegal = alegal ? 0 : 1; + flags.illegal_valid = 1; + } + + void Delete () { flags.deleted = 1; } + bool IsDeleted () const + { +#ifdef DEBUG + if (pnum[0] < PointIndex::BASE && !flags.deleted) + cerr << "Volelement has illegal pnum, but not marked as deleted" << endl; +#endif + + return flags.deleted; + } + + + +#ifdef PARALLEL + int GetPartition () const { return partitionNumber; } + void SetPartition (int nr) { partitionNumber = nr; }; +#else + int GetPartition () const { return 0; } +#endif + + int hp_elnr; + }; + + ostream & operator<<(ostream & s, const Element & el); + + + + + + + /** + Edge segment. + */ + class Segment + { + public: + /// + DLL_HEADER Segment(); + DLL_HEADER Segment (const Segment& other); + + ~Segment() + { ; } + + // friend ostream & operator<<(ostream & s, const Segment & seg); + + PointIndex pnums[3]; // p1, p2, pmid + + int edgenr; + /// + double singedge_left; + double singedge_right; + + /// 0.. not first segment of segs, 1..first of class, 2..first of class, inverse + unsigned int seginfo:2; + + /// surface decoding index + int si; + /// domain number inner side + int domin; + /// domain number outer side + int domout; + /// top-level object number of surface + int tlosurf; + /// + PointGeomInfo geominfo[2]; + + /// surfaces describing edge + int surfnr1, surfnr2; + /// + EdgePointGeomInfo epgeominfo[2]; + /// + // int pmid; // for second order + /// + int meshdocval; + +#ifdef PARALLEL + /// number of partition for parallel computation + int partitionNumber; +#endif + + private: + string* bcname; + + public: + /* + PointIndex operator[] (int i) const + { return (i == 0) ? p1 : p2; } + + PointIndex & operator[] (int i) + { return (i == 0) ? p1 : p2; } + */ + + Segment& operator=(const Segment & other); + + + int hp_elnr; + + void SetBCName ( string * abcname ) + { + bcname = abcname; + } + + string * BCNamePtr () + { return bcname; } + + const string * BCNamePtr () const + { return bcname; } + + const string & GetBCName () const + { + static string defaultstring = "default"; + if (! bcname ) return defaultstring; + return *bcname; + } + + int GetNP() const + { + return (pnums[2] < 0) ? 2 : 3; + } + + ELEMENT_TYPE GetType() const + { + return (pnums[2] < 0) ? SEGMENT : SEGMENT3; + } + + PointIndex & operator[] (int i) { return pnums[i]; } + const PointIndex & operator[] (int i) const { return pnums[i]; } + +#ifdef PARALLEL + int GetPartition () const { return partitionNumber; } + void SetPartition (int nr) { partitionNumber = nr; }; +#else + int GetPartition () const { return 0; } +#endif + }; + + ostream & operator<<(ostream & s, const Segment & seg); + + + + + // class Surface; + // class FaceDescriptor; + + /// + class FaceDescriptor + { + /// which surface, 0 if not available + int surfnr; + /// domain nr inside + int domin; + /// domain nr outside + int domout; + /// top level object number of surface + int tlosurf; + /// boundary condition property + int bcprop; + // Philippose - 06/07/2009 + // Add capability to store surface colours along with + // other face data + /// surface colour (Default: R=0.0 ; G=1.0 ; B=0.0) + Vec3d surfcolour; + + /// + string * bcname; + /// root of linked list + SurfaceElementIndex firstelement; + + double domin_singular; + double domout_singular; + + public: + DLL_HEADER FaceDescriptor(); + DLL_HEADER FaceDescriptor(int surfnri, int domini, int domouti, int tlosurfi); + DLL_HEADER FaceDescriptor(const Segment & seg); + DLL_HEADER FaceDescriptor(const FaceDescriptor& other); + DLL_HEADER ~FaceDescriptor() { ; } + + DLL_HEADER int SegmentFits (const Segment & seg); + + int SurfNr () const { return surfnr; } + int DomainIn () const { return domin; } + int DomainOut () const { return domout; } + int TLOSurface () const { return tlosurf; } + int BCProperty () const { return bcprop; } + + + double DomainInSingular() const { return domin_singular; } + double DomainOutSingular() const { return domout_singular; } + + // Philippose - 06/07/2009 + // Get Surface colour + Vec3d SurfColour () const { return surfcolour; } + const string & GetBCName () const; + // string * BCNamePtr () { return bcname; } + // const string * BCNamePtr () const { return bcname; } + void SetSurfNr (int sn) { surfnr = sn; } + void SetDomainIn (int di) { domin = di; } + void SetDomainOut (int dom) { domout = dom; } + void SetBCProperty (int bc) { bcprop = bc; } + void SetBCName (string * bcn) { bcname = bcn; } + // Philippose - 06/07/2009 + // Set the surface colour + void SetSurfColour (Vec3d colour) { surfcolour = colour; } + + void SetDomainInSingular (double v) { domin_singular = v; } + void SetDomainOutSingular (double v) { domout_singular = v; } + + SurfaceElementIndex FirstElement() { return firstelement; } + // friend ostream & operator<<(ostream & s, const FaceDescriptor & fd); + friend class Mesh; + }; + + ostream & operator<< (ostream & s, const FaceDescriptor & fd); + + + class EdgeDescriptor + { + int tlosurf; + int surfnr[2]; + public: + EdgeDescriptor () + : tlosurf(-1) + { surfnr[0] = surfnr[1] = -1; } + + int SurfNr (int i) const { return surfnr[i]; } + void SetSurfNr (int i, int nr) { surfnr[i] = nr; } + + int TLOSurface() const { return tlosurf; } + void SetTLOSurface (int nr) { tlosurf = nr; } + }; + + + + class DLL_HEADER MeshingParameters + { + public: + /** + 3d optimization strategy: + // m .. move nodes + // M .. move nodes, cheap functional + // s .. swap faces + // c .. combine elements + // d .. divide elements + // p .. plot, no pause + // P .. plot, Pause + // h .. Histogramm, no pause + // H .. Histogramm, pause + */ + const char * optimize3d; + /// number of 3d optimization steps + int optsteps3d; + /** + 2d optimization strategy: + // s .. swap, opt 6 lines/node + // S .. swap, optimal elements + // m .. move nodes + // p .. plot, no pause + // P .. plot, pause + // c .. combine + **/ + const char * optimize2d; + /// number of 2d optimization steps + int optsteps2d; + /// power of error (to approximate max err optimization) + double opterrpow; + /// do block filling ? + int blockfill; + /// block filling up to distance + double filldist; + /// radius of local environment (times h) + double safety; + /// radius of active environment (times h) + double relinnersafety; + /// use local h ? + int uselocalh; + /// grading for local h + double grading; + /// use delaunay meshing + int delaunay; + /// maximal mesh size + double maxh; + /// minimal mesh size + double minh; + /// file for meshsize + const char * meshsizefilename; + /// start surfacemeshing from everywhere in surface + int startinsurface; + /// check overlapping surfaces (debug) + int checkoverlap; + /// check overlapping surface mesh before volume meshing + int checkoverlappingboundary; + /// check chart boundary (sometimes too restrictive) + int checkchartboundary; + /// safty factor for curvatures (elemetns per radius) + double curvaturesafety; + /// minimal number of segments per edge + double segmentsperedge; + /// use parallel threads + int parthread; + /// weight of element size w.r.t element shape + double elsizeweight; + /// init with default values + + + /// from mp3: + /// give up quality class, 2d meshing + int giveuptol2d; + /// give up quality class, 3d meshing + int giveuptol; + /// maximal outer steps + int maxoutersteps; + /// class starting star-shape filling + int starshapeclass; + /// if non-zero, baseelement must have baseelnp points + int baseelnp; + /// quality tolerances are handled less careful + int sloppy; + + /// limit for max element angle (150-180) + double badellimit; + + bool check_impossible; + + /// + int secondorder; + /// high order element curvature + int elementorder; + /// quad-dominated surface meshing + int quad; + /// + int inverttets; + /// + int inverttrigs; + /// + int autozrefine; + /// + MeshingParameters (); + /// + void Print (ostream & ost) const; + + void CopyFrom(const MeshingParameters & other); + }; + + + + class DebugParameters + { + public: + /// + int debugoutput; + /// use slow checks + int slowchecks; + /// + int haltsuccess; + /// + int haltnosuccess; + /// + int haltlargequalclass; + /// + int haltsegment; + /// + int haltnode; + /// + int haltsegmentp1; + /// + int haltsegmentp2; + /// + int haltexistingline; + /// + int haltoverlap; + /// + int haltface; + /// + int haltfacenr; + /// + DebugParameters (); + }; + + + + + inline void Element2d :: Invert() + { + if (typ == TRIG) + Swap (PNum(2), PNum(3)); + else + Invert2(); + } + + + + + inline void Element2d :: NormalizeNumbering () + { + if (GetNP() == 3) + { + if (PNum(1) < PNum(2) && PNum(1) < PNum(3)) + return; + else + { + if (PNum(2) < PNum(3)) + { + PointIndex pi1 = PNum(2); + PNum(2) = PNum(3); + PNum(3) = PNum(1); + PNum(1) = pi1; + } + else + { + PointIndex pi1 = PNum(3); + PNum(3) = PNum(2); + PNum(2) = PNum(1); + PNum(1) = pi1; + } + } + } + else + NormalizeNumbering2(); + } + + + + static const int gftetfacesa[4][3] = + { { 1, 2, 3 }, + { 2, 0, 3 }, + { 0, 1, 3 }, + { 1, 0, 2 } }; + + inline void Element :: GetFace (int i, Element2d & face) const + { + if (typ == TET) + { + face.SetType(TRIG); + face[0] = pnum[gftetfacesa[i-1][0]]; + face[1] = pnum[gftetfacesa[i-1][1]]; + face[2] = pnum[gftetfacesa[i-1][2]]; + } + else + GetFace2 (i, face); + } + + + + + + + + /** + Identification of periodic surfaces, close surfaces, etc. + */ + class Identifications + { + public: + enum ID_TYPE { UNDEFINED = 1, PERIODIC = 2, CLOSESURFACES = 3, CLOSEEDGES = 4}; + + + private: + class Mesh & mesh; + + /// identify points (thin layers, periodic b.c.) + INDEX_2_HASHTABLE * identifiedpoints; + + /// the same, with info about the id-nr + INDEX_3_HASHTABLE * identifiedpoints_nr; + + /// sorted by identification nr + TABLE idpoints_table; + + Array type; + + /// number of identifications (or, actually used identifications ?) + int maxidentnr; + + public: + /// + DLL_HEADER Identifications (class Mesh & amesh); + /// + DLL_HEADER ~Identifications (); + + DLL_HEADER void Delete (); + + /* + Identify points pi1 and pi2, due to + identification nr identnr + */ + DLL_HEADER void Add (PointIndex pi1, PointIndex pi2, int identnr); + + + int Get (PointIndex pi1, PointIndex pi2) const; + int GetSymmetric (PointIndex pi1, PointIndex pi2) const; + + bool Get (PointIndex pi1, PointIndex pi2, int identnr) const; + bool GetSymmetric (PointIndex pi1, PointIndex pi2, int identnr) const; + + /// + INDEX_2_HASHTABLE & GetIdentifiedPoints () + { + return *identifiedpoints; + } + + bool Used (PointIndex pi1, PointIndex pi2) + { + return identifiedpoints->Used (INDEX_2 (pi1, pi2)); + } + + bool UsedSymmetric (PointIndex pi1, PointIndex pi2) + { + return + identifiedpoints->Used (INDEX_2 (pi1, pi2)) || + identifiedpoints->Used (INDEX_2 (pi2, pi1)); + } + + /// + void GetMap (int identnr, Array & identmap, bool symmetric = false) const; + /// + ID_TYPE GetType(int identnr) const + { + if(identnr <= type.Size()) + return type[identnr-1]; + else + return UNDEFINED; + } + void SetType(int identnr, ID_TYPE t) + { + while(type.Size() < identnr) + type.Append(UNDEFINED); + type[identnr-1] = t; + } + + /// + void GetPairs (int identnr, Array & identpairs) const; + /// + int GetMaxNr () const { return maxidentnr; } + + /// remove secondorder + void SetMaxPointNr (int maxpnum); + + void Print (ostream & ost) const; + }; + + +} + + + + +#endif + diff --git a/libsrc/meshing/msghandler.cpp b/libsrc/meshing/msghandler.cpp new file mode 100644 index 00000000..20393c78 --- /dev/null +++ b/libsrc/meshing/msghandler.cpp @@ -0,0 +1,228 @@ +//File for handling warnings, errors, messages +#include + +namespace netgen +{ +int printmessage_importance = 5; +int printwarnings = 1; +int printerrors = 1; +int printdots = 1; +int printfnstart = 0; + +// extern void Ng_PrintDest(const MyStr& s); +extern void Ng_PrintDest(const char * s); + +//the dots for progression of program +void PrintDot(char ch) +{ + if (printdots) + { + char st[2]; + st[0] = ch; + st[1] = 0; + Ng_PrintDest(st); + } +} + +void PrintMessage(int importance, + const MyStr& s1, const MyStr& s2) +{ + if (importance <= printmessage_importance) + { + Ng_PrintDest(MyStr(" ")+s1+s2+MyStr("\n")); + } +} + +void PrintMessage(int importance, + const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4) +{ + if (importance <= printmessage_importance) + { + Ng_PrintDest(MyStr(" ")+s1+s2+s3+s4+MyStr("\n")); + } +} + +void PrintMessage(int importance, + const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (importance <= printmessage_importance) + { + Ng_PrintDest(MyStr(" ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); + } +} + +void PrintMessageCR(int importance, + const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (importance <= printmessage_importance) + { + Ng_PrintDest(MyStr(" ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\r")); + } +} + +void PrintFnStart(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (printfnstart) + Ng_PrintDest(MyStr(" Start Function: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); +} + +void PrintWarning(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (printwarnings) + Ng_PrintDest(MyStr(" WARNING: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); +} + +void PrintError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (printerrors) + Ng_PrintDest(MyStr(" ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); +} + +void PrintFileError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (printerrors) + Ng_PrintDest(MyStr(" FILE ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); +} + +void PrintUserError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + Ng_PrintDest(MyStr(" USER ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); +} + +void PrintSysError(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (printerrors) + Ng_PrintDest(MyStr(" SYSTEM ERROR: ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); +} + +void PrintTime(const MyStr& s1, const MyStr& s2, const MyStr& s3, const MyStr& s4, + const MyStr& s5, const MyStr& s6, const MyStr& s7, const MyStr& s8) +{ + if (printmessage_importance >= 3) + Ng_PrintDest(MyStr(" Time = ")+s1+s2+s3+s4+s5+s6+s7+s8+MyStr("\n")); +} + + +static Array msgstatus_stack(0); +static Array threadpercent_stack(0); +static MyStr msgstatus = ""; + + + + +void ResetStatus() +{ + SetStatMsg("idle"); + + for (int i = 0; i < msgstatus_stack.Size(); i++) + delete msgstatus_stack[i]; + msgstatus_stack.SetSize(0); + threadpercent_stack.SetSize(0); + + // multithread.task = ""; + multithread.percent = 100.; +} + +void PushStatus(const MyStr& s) +{ + msgstatus_stack.Append(new MyStr (s)); + SetStatMsg(s); + threadpercent_stack.Append(0); +} + +void PushStatusF(const MyStr& s) +{ + msgstatus_stack.Append(new MyStr (s)); + SetStatMsg(s); + threadpercent_stack.Append(0); + PrintFnStart(s); +} + +void PopStatus() +{ + if (msgstatus_stack.Size()) + { + if (msgstatus_stack.Size() > 1) + // SetStatMsg (*msgstatus_stack.Last()); + SetStatMsg (*msgstatus_stack[msgstatus_stack.Size()-2]); + else + SetStatMsg (""); + delete msgstatus_stack.Last(); + msgstatus_stack.DeleteLast(); + threadpercent_stack.DeleteLast(); + if(threadpercent_stack.Size() > 0) + multithread.percent = threadpercent_stack.Last(); + else + multithread.percent = 100.; + } + else + { + PrintSysError("PopStatus failed"); + } +} + + + +/* +void SetStatMsgF(const MyStr& s) +{ + PrintFnStart(s); + SetStatMsg(s); +} +*/ + +void SetStatMsg(const MyStr& s) +{ + msgstatus = s; + multithread.task = msgstatus.c_str(); +} + +void SetThreadPercent(double percent) +{ + multithread.percent = percent; + if(threadpercent_stack.Size() > 0) + threadpercent_stack.Last() = percent; +} + + +void GetStatus(MyStr & s, double & percentage) +{ + if(threadpercent_stack.Size() > 0) + percentage = threadpercent_stack.Last(); + else + percentage = multithread.percent; + + if ( msgstatus_stack.Size() ) + s = *msgstatus_stack.Last(); + else + s = "idle"; +} + +/* +#ifdef SMALLLIB +#define SMALLLIBORNOTCL +#endif +#ifdef NOTCL +#define SMALLLIBORNOTCL +#endif + +#ifdef SMALLLIBORNOTCL +void Ng_PrintDest(const char * s){cout << s < +#include "meshing.hpp" + +namespace netgen +{ + +netrule :: netrule () +{ + name = new char[1]; + name[0] = char(0); + quality = 0; +} + +netrule :: ~netrule() +{ + delete [] name; + for(int i = 0; i < oldutofreearea_i.Size(); i++) + delete oldutofreearea_i[i]; + for(int i = 0; i < freezone_i.Size(); i++) + delete freezone_i[i]; +} + + + +void netrule :: SetFreeZoneTransformation (const Vector & devp, int tolclass) +{ + double lam1 = 1.0/tolclass; + double lam2 = 1.-lam1; + + double mem1[100], mem2[100], mem3[100]; + + int vs = oldutofreearea.Height(); + FlatVector devfree(vs, mem1); + + int fzs = freezone.Size(); + transfreezone.SetSize (fzs); + + if (tolclass <= oldutofreearea_i.Size()) + { + oldutofreearea_i[tolclass-1] -> Mult (devp, devfree); + + Array & fzi = *freezone_i[tolclass-1]; + for (int i = 0; i < fzs; i++) + { + transfreezone[i].X() = fzi[i].X() + devfree[2*i]; + transfreezone[i].Y() = fzi[i].Y() + devfree[2*i+1]; + } + } + else + { + FlatVector devfree1(vs, mem2); + FlatVector devfree2(vs, mem3); + + oldutofreearea.Mult (devp, devfree1); + oldutofreearealimit.Mult (devp, devfree2); + devfree.Set2 (lam1, devfree1, lam2, devfree2); + + for (int i = 0; i < fzs; i++) + { + transfreezone[i].X() = lam1 * freezone[i].X() + lam2 * freezonelimit[i].X() + devfree[2*i]; + transfreezone[i].Y() = lam1 * freezone[i].Y() + lam2 * freezonelimit[i].Y() + devfree[2*i+1]; + } + } + + + if (fzs > 0) + { + fzmaxx = fzminx = transfreezone[0].X(); + fzmaxy = fzminy = transfreezone[0].Y(); + } + + for (int i = 1; i < fzs; i++) + { + if (transfreezone[i].X() > fzmaxx) fzmaxx = transfreezone[i].X(); + if (transfreezone[i].X() < fzminx) fzminx = transfreezone[i].X(); + if (transfreezone[i].Y() > fzmaxy) fzmaxy = transfreezone[i].Y(); + if (transfreezone[i].Y() < fzminy) fzminy = transfreezone[i].Y(); + } + + for (int i = 0; i < fzs; i++) + { + Point2d p1 = transfreezone[i]; + Point2d p2 = transfreezone[(i+1) % fzs]; + + Vec2d vn (p2.Y() - p1.Y(), p1.X() - p2.X()); + + double len2 = vn.Length2(); + + if (len2 < 1e-10) + { + freesetinequ(i, 0) = 0; + freesetinequ(i, 1) = 0; + freesetinequ(i, 2) = -1; + } + else + { + vn /= sqrt (len2); // scaling necessary ? + + freesetinequ(i,0) = vn.X(); + freesetinequ(i,1) = vn.Y(); + freesetinequ(i,2) = -(p1.X() * vn.X() + p1.Y() * vn.Y()); + } + } +} + + +/* +int netrule :: IsInFreeZone2 (const Point2d & p) const +{ + for (int i = 0; i < transfreezone.Size(); i++) + { + if (freesetinequ(i, 0) * p.X() + + freesetinequ(i, 1) * p.Y() + + freesetinequ(i, 2) > 0) return 0; + } + return 1; +} +*/ + +int netrule :: IsLineInFreeZone2 (const Point2d & p1, const Point2d & p2) const +{ + int left, right, allleft, allright; + + if ( (p1.X() > fzmaxx && p2.X() > fzmaxx) || + (p1.X() < fzminx && p2.X() < fzminx) || + (p1.Y() > fzmaxy && p2.Y() > fzmaxy) || + (p1.Y() < fzminy && p2.Y() < fzminy) ) return 0; + + for (int i = 1; i <= transfreezone.Size(); i++) + { + if (freesetinequ.Get(i, 1) * p1.X() + freesetinequ.Get(i, 2) * p1.Y() + + freesetinequ.Get(i, 3) > -1e-8 && // -1e-6 + freesetinequ.Get(i, 1) * p2.X() + freesetinequ.Get(i, 2) * p2.Y() + + freesetinequ.Get(i, 3) > -1e-8 // -1e-6 + ) return 0; + } + + double nx = (p2.Y() - p1.Y()); + double ny = -(p2.X() - p1.X()); + double nl = sqrt (nx * nx + ny * ny); + if (nl > 1e-8) + { + nx /= nl; + ny /= nl; + double c = - (p1.X() * nx + p1.Y() * ny); + + allleft = 1; + allright = 1; + + for (int i = 1; i <= transfreezone.Size(); i++) + { + left = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() + c < 1e-7; + right = transfreezone.Get(i).X() * nx + transfreezone.Get(i).Y() + c > -1e-7; + + if (!left) allleft = 0; + if (!right) allright = 0; + } + if (allleft || allright) return 0; + } + + return 1; +} + +int netrule :: ConvexFreeZone () const +{ + int n = transfreezone.Size(); + for (int i = 1; i <= n; i++) + { + const bool counterclockwise = CCW (transfreezone.Get(i), + transfreezone.Get(i % n + 1), + transfreezone.Get( (i+1) % n + 1 ), + 1e-7); + //(*testout) << "ccw " << counterclockwise << endl << " p1 " << transfreezone.Get(i) << " p2 " << transfreezone.Get(i % n + 1) + // << " p3 " << transfreezone.Get( (i+1) % n + 1 ) << endl; + if (!counterclockwise ) + return 0; + } + return 1; +} + + +/* +float netrule :: CalcPointDist (int pi, const Point2d & p) const +{ + float dx = p.X() - points.Get(pi).X(); + float dy = p.Y() - points.Get(pi).Y(); + const threefloat * tf = &tolerances.Get(pi); + + return tf->f1 * dx * dx + tf->f2 * dx * dy + tf->f3 * dy * dy; +} +*/ + +float netrule :: CalcLineError (int li, const Vec2d & v) const +{ + float dx = v.X() - linevecs.Get(li).X(); + float dy = v.Y() - linevecs.Get(li).Y(); + + const threefloat * ltf = &linetolerances.Get(li); + return ltf->f1 * dx * dx + ltf->f2 * dx * dy + ltf->f3 * dy * dy; +} + + + + +/* +int GetNRules () + { + return rules.Size(); + } +*/ + + + + + + + + + + + +} diff --git a/libsrc/meshing/netrule3.cpp b/libsrc/meshing/netrule3.cpp new file mode 100644 index 00000000..de0e35e4 --- /dev/null +++ b/libsrc/meshing/netrule3.cpp @@ -0,0 +1,1138 @@ +#include +#include "meshing.hpp" + + + +namespace netgen +{ + + +vnetrule :: vnetrule () +{ + name = new char[1]; + name[0] = char(0); + quality = 0; +} + +vnetrule :: ~vnetrule () +{ + // if (strlen(name)) + delete [] name; + for (int i = 1; i <= freefaces.Size(); i++) + delete freefaces.Elem(i); + for (int i = 1; i <= freesets.Size(); i++) + delete freesets.Elem(i); + for (int i = 1; i <= freeedges.Size(); i++) + delete freeedges.Elem(i); + for (int i = 1; i <= freefaceinequ.Size(); i++) + delete freefaceinequ.Elem(i); + delete oldutofreezone; + delete oldutofreezonelimit; +} + +int vnetrule :: TestFlag (char flag) const +{ + for (int i = 1; i <= flags.Size(); i++) + if (flags.Get(i) == flag) return 1; + return 0; +} + + +void vnetrule :: SetFreeZoneTransformation (const Vector & allp, int tolclass) +{ + int i, j; + // double nx, ny, nz, v1x, v1y, v1z, v2x, v2y, v2z; + double nl; + const threeint * ti; + int fs; + + double lam1 = 1.0/(2 * tolclass - 1); + double lam2 = 1-lam1; + + transfreezone.SetSize (freezone.Size()); + + int np = points.Size(); + int nfp = freezone.Size(); + Vector vp(np), vfp1(nfp), vfp2(nfp); + + + for (i = 1; i <= 3; i++) + { + for (j = 1; j <= np; j++) + vp(j-1) = allp(i+3*j-3-1); + + oldutofreezone->Mult (vp, vfp1); + oldutofreezonelimit->Mult (vp, vfp2); + + vfp1 *= lam1; + vfp1.Add (lam2, vfp2); + + for (j = 1; j <= nfp; j++) + transfreezone.Elem(j).X(i) = vfp1(j-1); + } + + // MARK(setfz2); + + + fzbox.SetPoint (transfreezone.Elem(1)); + for (i = 2; i <= freezone.Size(); i++) + fzbox.AddPoint (transfreezone.Elem(i)); + + + // MARK(setfz3); + + + for (fs = 1; fs <= freesets.Size(); fs++) + { + Array & freesetfaces = *freefaces.Get(fs); + DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); + + for (i = 1; i <= freesetfaces.Size(); i++) + { + ti = &freesetfaces.Get(i); + const Point3d & p1 = transfreezone.Get(ti->i1); + const Point3d & p2 = transfreezone.Get(ti->i2); + const Point3d & p3 = transfreezone.Get(ti->i3); + + Vec3d v1(p1, p2); + Vec3d v2(p1, p3); + Vec3d n; + Cross (v1, v2, n); + + nl = n.Length(); + + if (nl < 1e-10) + { + freesetinequ.Set(1, 1, 0); + freesetinequ.Set(1, 2, 0); + freesetinequ.Set(1, 3, 0); + freesetinequ.Set(1, 4, -1); + } + else + { + // n /= nl; + + freesetinequ.Set(i, 1, n.X()/nl); + freesetinequ.Set(i, 2, n.Y()/nl); + freesetinequ.Set(i, 3, n.Z()/nl); + freesetinequ.Set(i, 4, + -(p1.X() * n.X() + p1.Y() * n.Y() + p1.Z() * n.Z()) / nl); + } + } + } + + /* + (*testout) << "Transformed freezone: " << endl; + for (i = 1; i <= transfreezone.Size(); i++) + (*testout) << transfreezone.Get(i) << " "; + (*testout) << endl; + */ +} + +int vnetrule :: ConvexFreeZone () const +{ + int i, j, k, fs; + + // (*mycout) << "Convex free zone...\n"; + + int ret1=1; + // int ret2=1; + + for (fs = 1; fs <= freesets.Size(); fs++) + { + const DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); + + // const Array & freeset = *freesets.Get(fs); + const Array & freesetedges = *freeedges.Get(fs); + // const Array & freesetfaces = *freefaces.Get(fs); + + for (i = 1; i <= freesetedges.Size(); i++) + { + j = freesetedges.Get(i).i1; //triangle j with opposite point k + k = freesetedges.Get(i).i2; + + if ( freesetinequ.Get(j, 1) * transfreezone.Get(k).X() + + freesetinequ.Get(j, 2) * transfreezone.Get(k).Y() + + freesetinequ.Get(j, 3) * transfreezone.Get(k).Z() + + freesetinequ.Get(j, 4) > 0 ) + { + ret1=0; + } + } + + } + + return ret1; +} + + +int vnetrule :: IsInFreeZone (const Point3d & p) const +{ + int i, fs; + char inthis; + + + for (fs = 1; fs <= freesets.Size(); fs++) + { + inthis = 1; + Array & freesetfaces = *freefaces.Get(fs); + DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); + + for (i = 1; i <= freesetfaces.Size() && inthis; i++) + { + if (freesetinequ.Get(i, 1) * p.X() + freesetinequ.Get(i, 2) * p.Y() + + freesetinequ.Get(i, 3) * p.Z() + freesetinequ.Get(i, 4) > 0) + inthis = 0; + } + + if (inthis) return 1; + } + + return 0; +} + + +int vnetrule :: IsTriangleInFreeZone (const Point3d & p1, + const Point3d & p2, + const Point3d & p3, + const Array & pi, int newone) +{ + int fs; + int infreeset, cannot = 0; + + + ArrayMem pfi(3), pfi2(3); + + // convert from local index to freeset index + int i, j; + for (i = 1; i <= 3; i++) + { + pfi.Elem(i) = 0; + if (pi.Get(i)) + { + for (j = 1; j <= freezonepi.Size(); j++) + if (freezonepi.Get(j) == pi.Get(i)) + pfi.Elem(i) = j; + } + } + + for (fs = 1; fs <= freesets.Size(); fs++) + { + const Array & freeseti = *freesets.Get(fs); + for (i = 1; i <= 3; i++) + { + pfi2.Elem(i) = 0; + for (j = 1; j <= freeseti.Size(); j++) + if (pfi.Get(i) == freeseti.Get(j)) + pfi2.Elem(i) = pfi.Get(i); + } + + infreeset = IsTriangleInFreeSet(p1, p2, p3, fs, pfi2, newone); + if (infreeset == 1) return 1; + if (infreeset == -1) cannot = -1; + } + + return cannot; +} + + + +int vnetrule :: IsTriangleInFreeSet (const Point3d & p1, const Point3d & p2, + const Point3d & p3, int fs, + const Array & pi, int newone) +{ + int i, ii; + Vec3d n; + int allleft, allright; + int hos1, hos2, hos3, os1, os2, os3; + double hf, lam1, lam2, f, c1, c2, alpha; + double v1n, v2n, h11, h12, h22, dflam1, dflam2; + double lam1old, lam2old, fold; + double hpx, hpy, hpz, v1x, v1y, v1z, v2x, v2y, v2z; + int act1, act2, act3, it; + int cntout; + Array activefaces; + int isin; + + + // MARK(triinfz); + + Array & freesetfaces = *freefaces.Get(fs); + DenseMatrix & freesetinequ = *freefaceinequ.Get(fs); + + + int cnt = 0; + for (i = 1; i <= 3; i++) + if (pi.Get(i)) cnt++; + + /* + (*testout) << "trig in free set : " << p1 << " - " << p2 << " - " << p3 << endl; + (*testout) << "common points: " << cnt << endl; + */ + if (!newone) + cnt = 0; + + if (cnt == 1) + { + // MARK(triinfz1); + + int upi = 0, lpiu = 0; + for (i = 1; i <= 3; i++) + if (pi.Get(i)) + { + upi = i; + lpiu = pi.Get(i); + } + + Vec3d v1, v2; + switch (upi) + { + case 1: + { + v1 = p2 - p1; + v2 = p3 - p1; + break; + } + case 2: + { + v1 = p3 - p2; + v2 = p1 - p2; + break; + } + case 3: + { + v1 = p1 - p3; + v2 = p2 - p3; + break; + } + } + + v1 /= v1.Length(); + v2 /= v2.Length(); + Cross (v1, v2, n); + n /= n.Length(); + + // (*testout) << "Test new: " << endl; + for (i = 1; i <= freesetfaces.Size(); i++) + { + if ( (freesetfaces.Get(i).i1 == lpiu) || + (freesetfaces.Get(i).i2 == lpiu) || + (freesetfaces.Get(i).i3 == lpiu) ) + { + // freeface has point + + + Vec3d a (freesetinequ.Get(i, 1), + freesetinequ.Get(i, 2), + freesetinequ.Get(i, 3)); + + // if (1 - fabs (a * n) < 1e-8 ) + // continue; + + Vec3d an; + Cross (a, n, an); + double lan = an.Length(); + if (lan < 1e-10) + continue; + + an /= lan; + + int out1 = (a * v1) > 0; + int out2 = (a * v2) > 0; + // (*testout) << "out1, out2 = " << out1 << ", " << out2 << endl; + if (out1 && out2) + return 0; + + if (!out1 && !out2) + continue; + + + // if ( ( (an * v1) < 0) && ( (an * v2) < 0) ) // falsch !!!! + // an *= -1; + + // solve an = lam1 v1 + lam2 v2 + double vii11 = v1 * v1; + double vii12 = v1 * v2; + double vii22 = v2 * v2; + double det = vii11 * vii22 - vii12 * vii12; + if ( fabs (det) < 1e-10 ) + continue; + double rs1 = an * v1; + double rs2 = an * v2; + + double lambda1 = rs1 * vii22 - rs2 * vii12; + double lambda2 = rs2 * vii11 - rs1 * vii12; + + if (fabs (lambda1) > fabs (lambda2)) + { + if (lambda1 < 0) + an *= -1; + } + else + { + if (lambda2 < 0) + an *= -1; + } + + + if (lambda1 * lambda2 < 0 && 0) + { + if (fabs (lambda1) > 1e-14 && fabs (lambda2) > 1e-14) + { + // (*mycout) << "lambda1 lambda2 < 0" << endl; + (*testout) << "lambdai different" << endl; + (*testout) << "v1 = " << v1 << endl; + (*testout) << "v2 = " << v2 << endl; + (*testout) << "n = " << n << endl; + (*testout) << "a = " << a << endl; + (*testout) << "an = " << an << endl; + (*testout) << "a * v1 = " << (a * v1) << endl; + (*testout) << "a * v2 = " << (a * v2) << endl; + (*testout) << "an * v1 = " << (an * v1) << endl; + (*testout) << "an * v2 = " << (an * v2) << endl; + + (*testout) << "vii = " << vii11 << ", " << vii12 << ", " << vii22 << endl; + (*testout) << "lambdai = " << lambda1 << ", " << lambda2 << endl; + (*testout) << "rs = " << rs1 << ", " << rs2 << endl; + continue; + } + } + + if (out1) + v1 = an; + else + v2 = an; + } + } + + return 1; + + /* + (*testout) << "overlap trig " << p1 << p2 << p3 << endl; + (*testout) << "upi = " << upi << endl; + (*testout) << "v1 = " << v1 << " v2 = " << v2 << endl; + */ + + switch (upi) + { + case 1: + { + v1 = p2 - p1; + v2 = p3 - p1; + break; + } + case 2: + { + v1 = p3 - p2; + v2 = p1 - p2; + break; + } + case 3: + { + v1 = p1 - p3; + v2 = p2 - p3; + break; + } + } + + v1 /= v1.Length(); + v2 /= v2.Length(); + Cross (v1, v2, n); + n /= n.Length(); + + // (*testout) << "orig v1, v2 = " << v1 << ", " << v2 << endl; + + + for (i = 1; i <= freesetfaces.Size(); i++) + { + if ( (freesetfaces.Get(i).i1 == lpiu) || + (freesetfaces.Get(i).i2 == lpiu) || + (freesetfaces.Get(i).i3 == lpiu) ) + { + /* + (*testout) << "v1, v2, now = " << v1 << ", " << v2 << endl; + + // freeface has point + (*testout) << "freesetface: " + << freesetfaces.Get(i).i1 << " " + << freesetfaces.Get(i).i2 << " " + << freesetfaces.Get(i).i3 << " "; + */ + + Vec3d a (freesetinequ.Get(i, 1), + freesetinequ.Get(i, 2), + freesetinequ.Get(i, 3)); + // (*testout) << "a = " << a << endl; + + + Vec3d an; + Cross (a, n, an); + double lan = an.Length(); + + // (*testout) << "an = " << an << endl; + + if (lan < 1e-10) + continue; + + an /= lan; + + // (*testout) << "a*v1 = " << (a*v1) << " a*v2 = " << (a*v2) << endl; + + int out1 = (a * v1) > 0; + // int out2 = (a * v2) > 0; + + + // (*testout) << "out1, 2 = " << out1 << ", " << out2 << endl; + + + double vii11 = v1 * v1; + double vii12 = v1 * v2; + double vii22 = v2 * v2; + double det = vii11 * vii22 - vii12 * vii12; + if ( fabs (det) < 1e-10 ) + continue; + double rs1 = an * v1; + double rs2 = an * v2; + + double lambda1 = rs1 * vii22 - rs2 * vii12; + double lambda2 = rs2 * vii11 - rs1 * vii12; + + // (*testout) << "lambda1, lambda2 = " << lambda1 << ", " << lambda2 << endl; + + + if (fabs (lambda1) > fabs (lambda2)) + { + if (lambda1 < 0) + an *= -1; + } + else + { + if (lambda2 < 0) + an *= -1; + } + + + if (lambda1 * lambda2 < 0) + { + if (fabs (lambda1) > 1e-14 && fabs (lambda2) > 1e-14) + { + // (*mycout) << "lambda1 lambda2 < 0" << endl; + (*testout) << "lambdai different" << endl; + (*testout) << "v1 = " << v1 << endl; + (*testout) << "v2 = " << v2 << endl; + (*testout) << "n = " << n << endl; + (*testout) << "a = " << a << endl; + (*testout) << "an = " << an << endl; + (*testout) << "a * v1 = " << (a * v1) << endl; + (*testout) << "a * v2 = " << (a * v2) << endl; + (*testout) << "an * v1 = " << (an * v1) << endl; + (*testout) << "an * v2 = " << (an * v2) << endl; + + (*testout) << "vii = " << vii11 << ", " << vii12 << ", " << vii22 << endl; + (*testout) << "lambdai = " << lambda1 << ", " << lambda2 << endl; + (*testout) << "rs = " << rs1 << ", " << rs2 << endl; + continue; + } + } + + if (out1) + v1 = an; + else + v2 = an; + + + + } + } + + return 1; + } + + + + if (cnt == 2) + { + // (*testout) << "tripoitns: " << p1 << " " << p2 << " " << p3 << endl; + + // MARK(triinfz2); + + int pi1 = 0, pi2 = 0, pi3 = 0; + Vec3d a1, a2; // outer normals + Vec3d trivec; // vector from common edge to third point of triangle + for (i = 1; i <= 3; i++) + if (pi.Get(i)) + { + pi2 = pi1; + pi1 = pi.Get(i); + } + else + pi3 = i; + + switch (pi3) + { + case 1: trivec = (p1 - p2); break; + case 2: trivec = (p2 - p3); break; + case 3: trivec = (p3 - p2); break; + } + + Array lpi(freezonepi.Size()); + for (i = 1; i <= lpi.Size(); i++) + lpi.Elem(i) = 0; + lpi.Elem(pi1) = 1; + lpi.Elem(pi2) = 1; + + int ff1 = 0, ff2 = 0; + for (i = 1; i <= freesetfaces.Size(); i++) + { + if (lpi.Get(freesetfaces.Get(i).i1) + + lpi.Get(freesetfaces.Get(i).i2) + + lpi.Get(freesetfaces.Get(i).i3) == 2) + { + ff2 = ff1; + ff1 = i; + } + } + + if (ff2 == 0) + return 1; + + a1 = Vec3d (freesetinequ.Get(ff1, 1), + freesetinequ.Get(ff1, 2), + freesetinequ.Get(ff1, 3)); + a2 = Vec3d (freesetinequ.Get(ff2, 1), + freesetinequ.Get(ff2, 2), + freesetinequ.Get(ff2, 3)); + + if ( ( (a1 * trivec) > 0) || ( (a2 * trivec) > 0)) + return 0; + + return 1; + } + + + if (cnt == 3) + { + // MARK(triinfz3); + + Array lpi(freezonepi.Size()); + for (i = 1; i <= lpi.Size(); i++) + lpi.Elem(i) = 0; + + for (i = 1; i <= 3; i++) + lpi.Elem(pi.Get(i)) = 1; + + for (i = 1; i <= freesetfaces.Size(); i++) + { + if (lpi.Get(freesetfaces.Get(i).i1) + + lpi.Get(freesetfaces.Get(i).i2) + + lpi.Get(freesetfaces.Get(i).i3) == 3) + { + return 0; + } + } + return 1; + } + + // MARK(triinfz0); + + + os1 = os2 = os3 = 0; + activefaces.SetSize(0); + + // is point inside ? + + for (i = 1; i <= freesetfaces.Size(); i++) + { + hos1 = freesetinequ.Get(i, 1) * p1.X() + + freesetinequ.Get(i, 2) * p1.Y() + + freesetinequ.Get(i, 3) * p1.Z() + + freesetinequ.Get(i, 4) > -1E-5; + + hos2 = freesetinequ.Get(i, 1) * p2.X() + + freesetinequ.Get(i, 2) * p2.Y() + + freesetinequ.Get(i, 3) * p2.Z() + + freesetinequ.Get(i, 4) > -1E-5; + + hos3 = freesetinequ.Get(i, 1) * p3.X() + + freesetinequ.Get(i, 2) * p3.Y() + + freesetinequ.Get(i, 3) * p3.Z() + + freesetinequ.Get(i, 4) > -1E-5; + + if (hos1 && hos2 && hos3) return 0; + + if (hos1) os1 = 1; + if (hos2) os2 = 1; + if (hos3) os3 = 1; + + if (hos1 || hos2 || hos3) activefaces.Append (i); + } + + if (!os1 || !os2 || !os3) return 1; + + v1x = p2.X() - p1.X(); + v1y = p2.Y() - p1.Y(); + v1z = p2.Z() - p1.Z(); + + v2x = p3.X() - p1.X(); + v2y = p3.Y() - p1.Y(); + v2z = p3.Z() - p1.Z(); + + n.X() = v1y * v2z - v1z * v2y; + n.Y() = v1z * v2x - v1x * v2z; + n.Z() = v1x * v2y - v1y * v2x; + n /= n.Length(); + + allleft = allright = 1; + for (i = 1; i <= transfreezone.Size() && (allleft || allright); i++) + { + const Point3d & p = transfreezone.Get(i); + float scal = (p.X() - p1.X()) * n.X() + + (p.Y() - p1.Y()) * n.Y() + + (p.Z() - p1.Z()) * n.Z(); + + if ( scal > 1E-8 ) allleft = 0; + if ( scal < -1E-8 ) allright = 0; + } + + if (allleft || allright) return 0; + + + lam1old = lam2old = lam1 = lam2 = 1.0 / 3.0; + + + // testout << endl << endl << "Start minimizing" << endl; + + it = 0; + int minit; + minit = 1000; + fold = 1E10; + + + + while (1) + { + it++; + + if (it > 1000) return -1; + + if (lam1 < 0) lam1 = 0; + if (lam2 < 0) lam2 = 0; + if (lam1 + lam2 > 1) lam1 = 1 - lam2; + + if (it > minit) + { + (*testout) << "it = " << it << endl; + (*testout) << "lam1/2 = " << lam1 << " " << lam2 << endl; + } + + hpx = p1.X() + lam1 * v1x + lam2 * v2x; + hpy = p1.Y() + lam1 * v1y + lam2 * v2y; + hpz = p1.Z() + lam1 * v1z + lam2 * v2z; + + f = 0; + + h11 = h12 = h22 = dflam1 = dflam2 = 0; + cntout = 0; + + isin = 1; + + for (i = 1; i <= activefaces.Size(); i++) + { + ii = activefaces.Get(i); + + hf = freesetinequ.Get(ii, 1) * hpx + + freesetinequ.Get(ii, 2) * hpy + + freesetinequ.Get(ii, 3) * hpz + + freesetinequ.Get(ii, 4); + + if (hf > -1E-7) isin = 0; + + hf += 1E-4; + if (hf > 0) + { + f += hf * hf; + + v1n = freesetinequ.Get(ii, 1) * v1x + + freesetinequ.Get(ii, 2) * v1y + + freesetinequ.Get(ii, 3) * v1z; + v2n = freesetinequ.Get(ii, 1) * v2x + + freesetinequ.Get(ii, 2) * v2y + + freesetinequ.Get(ii, 3) * v2z; + + h11 += 2 * v1n * v1n; + h12 += 2 * v1n * v2n; + h22 += 2 * v2n * v2n; + dflam1 += 2 * hf * v1n; + dflam2 += 2 * hf * v2n; + cntout++; + } + } + + if (isin) return 1; + + if (it > minit) + { + (*testout) << "f = " << f + << " dfdlam = " << dflam1 << " " << dflam2 << endl; + (*testout) << "h = " << h11 << " " << h12 << " " << h22 << endl; + (*testout) << "active: " << cntout << endl; + (*testout) << "lam1-lam1old = " << (lam1 - lam1old) << endl; + (*testout) << "lam2-lam2old = " << (lam2 - lam2old) << endl; + } + + + if (f >= fold) + { + lam1 = 0.100000000000000 * lam1 + 0.9000000000000000 * lam1old; + lam2 = 0.100000000000000 * lam2 + 0.9000000000000000 * lam2old; + } + else + { + lam1old = lam1; + lam2old = lam2; + fold = f; + + + if (f < 1E-9) return 1; + + h11 += 1E-10; + h22 += 1E-10; + c1 = - ( h22 * dflam1 - h12 * dflam2) / (h11 * h22 - h12 * h12); + c2 = - (-h12 * dflam1 + h11 * dflam2) / (h11 * h22 - h12 * h12); + alpha = 1; + + + if (it > minit) + (*testout) << "c1/2 = " << c1 << " " << c2 << endl; + + act1 = lam1 <= 1E-6 && c1 <= 0; + act2 = lam2 <= 1E-6 && c2 <= 0; + act3 = lam1 + lam2 >= 1 - 1E-6 && c1 + c2 >= 0; + + if (it > minit) + (*testout) << "act1,2,3 = " << act1 << act2 << act3 << endl; + + if ( (act1 && act2) || (act1 && act3) || (act2 && act3) ) return 0; + + if (act1) + { + c1 = 0; + c2 = - dflam2 / h22; + } + + if (act2) + { + c1 = - dflam1 / h11; + c2 = 0; + } + + if (act3) + { + c1 = - (dflam1 - dflam2) / (h11 + h22 - 2 * h12); + c2 = -c1; + } + + if (it > minit) + (*testout) << "c1/2 now = " << c1 << " " << c2 << endl; + + + if (f > 100 * sqrt (sqr (c1) + sqr (c2))) return 0; + + + if (lam1 + alpha * c1 < 0 && !act1) + alpha = -lam1 / c1; + if (lam2 + alpha * c2 < 0 && !act2) + alpha = -lam2 / c2; + if (lam1 + lam2 + alpha * (c1 + c2) > 1 && !act3) + alpha = (1 - lam1 - lam2) / (c1 + c2); + + if (it > minit) + (*testout) << "alpha = " << alpha << endl; + + lam1 += alpha * c1; + lam2 += alpha * c2; + } + } +} + + + + +int vnetrule :: IsQuadInFreeZone (const Point3d & p1, + const Point3d & p2, + const Point3d & p3, + const Point3d & p4, + const Array & pi, int newone) +{ + int fs; + int infreeset, cannot = 0; + + + ArrayMem pfi(4), pfi2(4); + + // convert from local index to freeset index + int i, j; + for (i = 1; i <= 4; i++) + { + pfi.Elem(i) = 0; + if (pi.Get(i)) + { + for (j = 1; j <= freezonepi.Size(); j++) + if (freezonepi.Get(j) == pi.Get(i)) + pfi.Elem(i) = j; + } + } + + for (fs = 1; fs <= freesets.Size(); fs++) + { + const Array & freeseti = *freesets.Get(fs); + for (i = 1; i <= 4; i++) + { + pfi2.Elem(i) = 0; + for (j = 1; j <= freeseti.Size(); j++) + if (pfi.Get(i) == freeseti.Get(j)) + pfi2.Elem(i) = pfi.Get(i); + } + + infreeset = IsQuadInFreeSet(p1, p2, p3, p4, fs, pfi2, newone); + if (infreeset == 1) return 1; + if (infreeset == -1) cannot = -1; + } + + return cannot; +} + + +int vnetrule :: IsQuadInFreeSet (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, + int fs, const Array & pi, int newone) +{ + int i; + + int cnt = 0; + for (i = 1; i <= 4; i++) + if (pi.Get(i)) cnt++; + + /* + (*testout) << "test quad in freeset: " << p1 << " - " << p2 << " - " << p3 << " - " << p4 << endl; + (*testout) << "pi = "; + for (i = 1; i <= pi.Size(); i++) + (*testout) << pi.Get(i) << " "; + (*testout) << endl; + (*testout) << "cnt = " << cnt << endl; + */ + if (cnt == 4) + { + return 1; + } + + if (cnt == 3) + { + return 1; + } + + ArrayMem pi3(3); + int res; + + pi3.Elem(1) = pi.Get(1); + pi3.Elem(2) = pi.Get(2); + pi3.Elem(3) = pi.Get(3); + res = IsTriangleInFreeSet (p1, p2, p3, fs, pi3, newone); + if (res) return res; + + + pi3.Elem(1) = pi.Get(2); + pi3.Elem(2) = pi.Get(3); + pi3.Elem(3) = pi.Get(4); + res = IsTriangleInFreeSet (p2, p3, p4, fs, pi3, newone); + if (res) return res; + + pi3.Elem(1) = pi.Get(3); + pi3.Elem(2) = pi.Get(4); + pi3.Elem(3) = pi.Get(1); + res = IsTriangleInFreeSet (p3, p4, p1, fs, pi3, newone); + if (res) return res; + + pi3.Elem(1) = pi.Get(4); + pi3.Elem(2) = pi.Get(1); + pi3.Elem(3) = pi.Get(2); + res = IsTriangleInFreeSet (p4, p1, p2, fs, pi3, newone); + return res; +} + + + + + + + + + + + + +float vnetrule :: CalcPointDist (int pi, const Point3d & p) const +{ + float dx = p.X() - points.Get(pi).X(); + float dy = p.Y() - points.Get(pi).Y(); + float dz = p.Z() - points.Get(pi).Z(); + + // const threefloat * tf = &tolerances.Get(pi); + // return tf->f1 * dx * dx + tf->f2 * dx * dy + tf->f3 * dy * dy; + return tolerances.Get(pi) * (dx * dx + dy * dy + dz * dz); +} + + +int vnetrule :: TestOk () const +{ + Array cntpused(points.Size()); + Array edge1, edge2; + Array delf(faces.Size()); + int i, j, k; + int pi1, pi2; + int found; + + for (i = 1; i <= cntpused.Size(); i++) + cntpused.Elem(i) = 0; + for (i = 1; i <= faces.Size(); i++) + delf.Elem(i) = 0; + for (i = 1; i <= delfaces.Size(); i++) + delf.Elem(delfaces.Get(i)) = 1; + + + for (i = 1; i <= faces.Size(); i++) + if (delf.Get(i) || i > noldf) + for (j = 1; j <= faces.Get(i).GetNP(); j++) + cntpused.Elem(faces.Get(i).PNum(j))++; + + for (i = 1; i <= cntpused.Size(); i++) + if (cntpused.Get(i) > 0 && cntpused.Get(i) < 2) + { + return 0; + } + + + // (*testout) << endl; + for (i = 1; i <= faces.Size(); i++) + { + // (*testout) << "face " << i << endl; + for (j = 1; j <= faces.Get(i).GetNP(); j++) + { + pi1 = 0; pi2 = 0; + if (delf.Get(i)) + { + pi1 = faces.Get(i).PNumMod(j); + pi2 = faces.Get(i).PNumMod(j+1); + } + if (i > noldf) + { + pi1 = faces.Get(i).PNumMod(j+1); + pi2 = faces.Get(i).PNumMod(j); + } + + found = 0; + if (pi1) + { + for (k = 1; k <= edge1.Size(); k++) + if (edge1.Get(k) == pi1 && edge2.Get(k) == pi2) + { + found = 1; + edge1.DeleteElement(k); + edge2.DeleteElement(k); + k--; + // (*testout) << "Del edge " << pi1 << "-" << pi2 << endl; + } + if (!found) + { + edge1.Append (pi2); + edge2.Append (pi1); + // (*testout) << "Add edge " << pi1 << "-" << pi2 << endl; + } + } + } + } + + + if (edge1.Size() > 0) + { + return 0; + } + + /* + cntpused.SetSize(freezone.Size()); + for (i = 1; i <= cntpused.Size(); i++) + cntpused[i] = 0; + + for (i = 1; i <= freefaces.Size(); i++) + { + cntpused[freefaces[i].i1]++; + cntpused[freefaces[i].i2]++; + cntpused[freefaces[i].i3]++; + } + + for (i = 1; i <= cntpused.Size(); i++) + if (cntpused[i] < 3) + { + (*mycout) << "Fall 3" << endl; + return 0; + } + + + + for (i = 1; i <= freefaces.Size(); i++) + { + for (j = 1; j <= 3; j++) + { + if (j == 1) + { + pi1 = freefaces[i].i1; + pi2 = freefaces[i].i2; + } + if (j == 2) + { + pi1 = freefaces[i].i2; + pi2 = freefaces[i].i3; + } + if (j == 3) + { + pi1 = freefaces[i].i3; + pi2 = freefaces[i].i1; + } + + found = 0; + for (k = 1; k <= edge1.Size(); k++) + if (edge1[k] == pi1 && edge2[k] == pi2) + { + found = 1; + edge1.DeleteElement(k); + edge2.DeleteElement(k); + k--; + } + + if (!found) + { + edge1.Append (pi2); + edge2.Append (pi1); + } + } + } + + if (edge1.Size() > 0) + { + (*mycout) << "Fall 4" << endl; + return 0; + } + */ + return 1; +} + + +int vnetrule :: IsDelFace (int fn) const +{ + int i; + for (i = 1; i <= GetNDelF(); i++) + if (GetDelFace(i) == fn) return 1; + return 0; +} + +} diff --git a/libsrc/meshing/parallelmesh.cpp b/libsrc/meshing/parallelmesh.cpp new file mode 100644 index 00000000..07e8124d --- /dev/null +++ b/libsrc/meshing/parallelmesh.cpp @@ -0,0 +1,1526 @@ +#ifdef PARALLEL + +#include +#include "paralleltop.hpp" + +// #define METIS4 + + +#ifdef METIS +namespace metis { + extern "C" { + +#include + +#if METIS_VER_MAJOR >= 5 +#define METIS5 + typedef idx_t idxtype; +#else +#define METIS4 + typedef idxtype idx_t; +#endif + } +} + +using namespace metis; +#endif + +namespace netgen +{ + + template <> + inline MPI_Datatype MyGetMPIType ( ) + { return MPI_INT; } + + + void Mesh :: SendRecvMesh () + { + if (id == 0) + PrintMessage (1, "Send/Receive mesh"); + + { + // distribute global information + int nelglob, nseglob, nvglob; + if (id == 0) + { + paralleltop -> SetNV (GetNV()); + paralleltop -> SetNE (GetNE()); + paralleltop -> SetNSegm (GetNSeg()); + paralleltop -> SetNSE (GetNSE()); + + nelglob = GetNE(); + nseglob = GetNSE(); + nvglob = GetNV(); + } + + MyMPI_Bcast (dimension); + MyMPI_Bcast (nelglob); + MyMPI_Bcast (nseglob); + MyMPI_Bcast (nvglob); + } + + + + { + // distribute number of local elements + if (id == 0) + { + Array num_els_on_proc(ntasks); + num_els_on_proc = 0; + for (ElementIndex ei = 0; ei < GetNE(); ei++) + num_els_on_proc[(*this)[ei].GetPartition()]++; + + MPI_Scatter (&num_els_on_proc[0], 1, MPI_INT, + MPI_IN_PLACE, -1, MPI_INT, 0, MPI_COMM_WORLD); + } + else + { + int nelloc; + MPI_Scatter (NULL, 0, MPI_INT, + &nelloc, 1, MPI_INT, 0, MPI_COMM_WORLD); + + paralleltop -> SetNE (nelloc); + } + } + + if (id == 0) + SendMesh (); + else + ReceiveParallelMesh(); + + paralleltop -> UpdateCoarseGrid(); + } + + + + + + + + void Mesh :: SendMesh () const + { + Array sendrequests; + + PrintMessage ( 3, "Sending vertices"); + + + Array num_els_on_proc(ntasks); + num_els_on_proc = 0; + for (ElementIndex ei = 0; ei < GetNE(); ei++) + num_els_on_proc[(*this)[ei].GetPartition()]++; + + TABLE els_of_proc (num_els_on_proc); + for (ElementIndex ei = 0; ei < GetNE(); ei++) + els_of_proc.Add ( (*this)[ei].GetPartition(), ei); + + + Array num_sels_on_proc(ntasks); + num_sels_on_proc = 0; + for (SurfaceElementIndex ei = 0; ei < GetNSE(); ei++) + num_sels_on_proc[(*this)[ei].GetPartition()]++; + + TABLE sels_of_proc (num_sels_on_proc); + for (SurfaceElementIndex ei = 0; ei < GetNSE(); ei++) + sels_of_proc.Add ( (*this)[ei].GetPartition(), ei); + + Array num_segs_on_proc(ntasks); + num_segs_on_proc = 0; + for (SegmentIndex ei = 0; ei < GetNSeg(); ei++) + num_segs_on_proc[(*this)[ei].GetPartition()]++; + + TABLE segs_of_proc (num_segs_on_proc); + for (SegmentIndex ei = 0; ei < GetNSeg(); ei++) + segs_of_proc.Add ( (*this)[ei].GetPartition(), ei); + + + + + Array vert_flag (GetNV()); + Array num_procs_on_vert (GetNV()); + Array num_verts_on_proc (ntasks); + + num_verts_on_proc = 0; + num_procs_on_vert = 0; + vert_flag = -1; + + + for (int dest = 1; dest < ntasks; dest++) + { + FlatArray els = els_of_proc[dest]; + for (int hi = 0; hi < els.Size(); hi++) + { + const Element & el = (*this) [ els[hi] ]; + for (int i = 0; i < el.GetNP(); i++) + { + PointIndex epi = el[i]; + if (vert_flag[epi] < dest) + { + vert_flag[epi] = dest; + + num_verts_on_proc[dest]++; + num_procs_on_vert[epi]++; + + paralleltop -> SetDistantPNum (dest, epi); + } + } + } + + + FlatArray sels = sels_of_proc[dest]; + for (int hi = 0; hi < sels.Size(); hi++) + { + const Element2d & el = (*this) [ sels[hi] ]; + for (int i = 0; i < el.GetNP(); i++) + { + PointIndex epi = el[i]; + if (vert_flag[epi] < dest) + { + vert_flag[epi] = dest; + + num_verts_on_proc[dest]++; + num_procs_on_vert[epi]++; + + paralleltop -> SetDistantPNum (dest, epi); + } + } + } + + FlatArray segs = segs_of_proc[dest]; + for (int hi = 0; hi < segs.Size(); hi++) + { + const Segment & el = (*this) [segs[hi]]; + for (int i = 0; i < 2; i++) + { + PointIndex epi = el[i]; + if (vert_flag[epi] < dest) + { + vert_flag[epi] = dest; + + num_verts_on_proc[dest]++; + num_procs_on_vert[epi]++; + + paralleltop -> SetDistantPNum (dest, epi); + } + } + } + } + + TABLE verts_of_proc (num_verts_on_proc); + TABLE procs_of_vert (num_procs_on_vert); + TABLE loc_num_of_vert (num_procs_on_vert); + + vert_flag = -1; + for (int dest = 1; dest < ntasks; dest++) + { + FlatArray els = els_of_proc[dest]; + for (int hi = 0; hi < els.Size(); hi++) + { + const Element & el = (*this) [ els[hi] ]; + for (int i = 0; i < el.GetNP(); i++) + { + PointIndex epi = el[i]; + if (vert_flag[epi] < dest) + { + vert_flag[epi] = dest; + procs_of_vert.Add (epi, dest); + } + } + } + + FlatArray sels = sels_of_proc[dest]; + for (int hi = 0; hi < sels.Size(); hi++) + { + const Element2d & el = (*this) [ sels[hi] ]; + for (int i = 0; i < el.GetNP(); i++) + { + PointIndex epi = el[i]; + if (vert_flag[epi] < dest) + { + vert_flag[epi] = dest; + procs_of_vert.Add (epi, dest); + } + } + } + + FlatArray segs = segs_of_proc[dest]; + for (int hi = 0; hi < segs.Size(); hi++) + { + const Segment & el = (*this) [ segs[hi] ]; + for (int i = 0; i < 2; i++) + { + PointIndex epi = el[i]; + if (vert_flag[epi] < dest) + { + vert_flag[epi] = dest; + procs_of_vert.Add (epi, dest); + } + } + } + + } + + for (int vert = 1; vert <= GetNP(); vert++ ) + { + FlatArray procs = procs_of_vert[vert]; + for (int j = 0; j < procs.Size(); j++) + { + int dest = procs[j]; + verts_of_proc.Add (dest, vert); + loc_num_of_vert.Add (vert, verts_of_proc[dest].Size()); + } + } + + for (int dest = 1; dest < ntasks; dest++) + { + FlatArray verts = verts_of_proc[dest]; + sendrequests.Append (MyMPI_ISend (verts, dest, MPI_TAG_MESH+1)); + + MPI_Datatype mptype = MeshPoint::MyGetMPIType(); + + int numv = verts.Size(); + + MPI_Datatype newtype; + Array blocklen (numv); + blocklen = 1; + + MPI_Type_indexed (numv, &blocklen[0], + reinterpret_cast (&verts[0]), + mptype, &newtype); + MPI_Type_commit (&newtype); + + MPI_Request request; + MPI_Isend( &points[0], 1, newtype, dest, MPI_TAG_MESH+1, MPI_COMM_WORLD, &request); + sendrequests.Append (request); + } + + Array num_distpnums(ntasks); + num_distpnums = 0; + + for (int vert = 1; vert <= GetNP(); vert++) + { + FlatArray procs = procs_of_vert[vert]; + for (int j = 0; j < procs.Size(); j++) + num_distpnums[procs[j]] += 3 * (procs.Size()-1); + } + + TABLE distpnums (num_distpnums); + + for (int vert = 1; vert <= GetNP(); vert++) + { + FlatArray procs = procs_of_vert[vert]; + for (int j = 0; j < procs.Size(); j++) + for (int k = 0; k < procs.Size(); k++) + if (j != k) + { + distpnums.Add (procs[j], loc_num_of_vert[vert][j]); + distpnums.Add (procs[j], procs_of_vert[vert][k]); + distpnums.Add (procs[j], loc_num_of_vert[vert][k]); + } + } + + for ( int dest = 1; dest < ntasks; dest ++ ) + sendrequests.Append (MyMPI_ISend (distpnums[dest], dest, MPI_TAG_MESH+1)); + + + + PrintMessage ( 3, "Sending elements" ); + + Array elarraysize (ntasks); + elarraysize = 0; + for ( int ei = 1; ei <= GetNE(); ei++) + { + const Element & el = VolumeElement (ei); + int dest = el.GetPartition(); + elarraysize[dest] += 3 + el.GetNP(); + } + + TABLE elementarrays(elarraysize); + + for (int ei = 1; ei <= GetNE(); ei++) + { + const Element & el = VolumeElement (ei); + int dest = el.GetPartition(); + + elementarrays.Add (dest, ei); + elementarrays.Add (dest, el.GetIndex()); + elementarrays.Add (dest, el.GetNP()); + for (int i = 0; i < el.GetNP(); i++) + elementarrays.Add (dest, el[i]); + } + + for (int dest = 1; dest < ntasks; dest ++ ) + sendrequests.Append (MyMPI_ISend (elementarrays[dest], dest, MPI_TAG_MESH+2)); + + + PrintMessage ( 3, "Sending Face Descriptors" ); + + Array fddata (6 * GetNFD()); + for (int fdi = 1; fdi <= GetNFD(); fdi++) + { + fddata[6*fdi-6] = GetFaceDescriptor(fdi).SurfNr(); + fddata[6*fdi-5] = GetFaceDescriptor(fdi).DomainIn(); + fddata[6*fdi-4] = GetFaceDescriptor(fdi).DomainOut(); + fddata[6*fdi-3] = GetFaceDescriptor(fdi).BCProperty(); + fddata[6*fdi-2] = GetFaceDescriptor(fdi).domin_singular; + fddata[6*fdi-1] = GetFaceDescriptor(fdi).domout_singular; + + } + for (int dest = 1; dest < ntasks; dest++) + sendrequests.Append (MyMPI_ISend (fddata, dest, MPI_TAG_MESH+3)); + + PrintMessage ( 3, "Sending Surface elements" ); + + Array nlocsel(ntasks), bufsize(ntasks); + nlocsel = 0; + bufsize = 1; + + for (int sei = 1; sei <= GetNSE(); sei++ ) + { + const Element2d & sel = SurfaceElement (sei); + int dest = sel.GetPartition(); + nlocsel[dest] ++; + bufsize[dest] += 4 + 2*sel.GetNP(); + } + + TABLE selbuf(bufsize); + + for (int dest = 1; dest < ntasks; dest++ ) + selbuf.Add (dest, nlocsel[dest]); + + for (int sei = 1; sei <= GetNSE(); sei ++ ) + { + const Element2d & sel = SurfaceElement (sei); + int dest = sel.GetPartition(); + + selbuf.Add (dest, sei); + selbuf.Add (dest, sel.GetIndex()); + selbuf.Add (dest, 0); + selbuf.Add (dest, sel.GetNP()); + + for ( int ii = 1; ii <= sel.GetNP(); ii++) + { + selbuf.Add (dest, sel.PNum(ii)); + selbuf.Add (dest, sel.GeomInfoPi(ii).trignum); + } + } + + for (int dest = 1; dest < ntasks; dest++) + sendrequests.Append (MyMPI_ISend(selbuf[dest], dest, MPI_TAG_MESH+4)); + + + PrintMessage ( 3, "Sending Edge Segments"); + + + Array nloc(ntasks); + nloc = 0; + bufsize = 1; + + for (int i = 1; i <= GetNSeg(); i++ ) + { + const Segment & seg = LineSegment (i); + int dest = seg.GetPartition(); + nloc[dest] ++; + bufsize[dest] += 14; + } + + TABLE segm_buf(bufsize); + + /* + for (int dest = 1; dest < ntasks; dest++ ) + segm_buf.Add (dest, nloc[dest]); + */ + for (int i = 1; i <= GetNSeg(); i++ ) + { + const Segment & seg = LineSegment (i); + int dest = seg.GetPartition(); + + segm_buf.Add (dest, i); + segm_buf.Add (dest, seg.si); + segm_buf.Add (dest, seg.pnums[0]); + segm_buf.Add (dest, seg.pnums[1]); + segm_buf.Add (dest, seg.geominfo[0].trignum); + segm_buf.Add (dest, seg.geominfo[1].trignum); + segm_buf.Add (dest, seg.surfnr1); + segm_buf.Add (dest, seg.surfnr2); + segm_buf.Add (dest, seg.edgenr); + segm_buf.Add (dest, seg.epgeominfo[0].dist); + segm_buf.Add (dest, seg.epgeominfo[1].edgenr); + segm_buf.Add (dest, seg.epgeominfo[1].dist); + segm_buf.Add (dest, seg.singedge_right); + segm_buf.Add (dest, seg.singedge_left); + } + + for (int dest = 1; dest < ntasks; dest++) + sendrequests.Append (MyMPI_ISend(segm_buf[dest], dest, MPI_TAG_MESH+5)); + + /* + Array nlocseg(ntasks), segi(ntasks); + for ( int i = 0; i < ntasks; i++) + { + nlocseg[i] = 0; + bufsize[i] = 0; + segi[i] = 0; + } + + for (int segi = 1; segi <= GetNSeg(); segi ++ ) + { + Array volels; + const MeshTopology & topol = GetTopology(); + topol . GetSegmentSurfaceElements ( segi, volels ); + for (int j = 0; j < volels.Size(); j++) + { + int ei = volels[j]; + if ( ei > 0 && ei <= GetNSE() ) + { + const Element2d & el = SurfaceElement (ei); + int dest = el.GetPartition(); + nlocseg[dest] ++; + bufsize[dest] += 14; + } + } + } + + TABLE segmbuf(bufsize); + + for ( int ls=1; ls <= GetNSeg(); ls++) + { + Array volels; + GetTopology().GetSegmentSurfaceElements ( ls, volels ); + const Segment & seg = LineSegment (ls); + + for (int j = 0; j < volels.Size(); j++) + { + int ei = volels[j]; + if ( ei > 0 && ei <= GetNSE() ) + { + const Element2d & el = SurfaceElement (ei); + int dest = el.GetPartition(); + + if ( dest > 0 ) + { + segmbuf.Add (dest, ls); + segmbuf.Add (dest, seg.si); + segmbuf.Add (dest, seg.pnums[0]); + segmbuf.Add (dest, seg.pnums[1]); + segmbuf.Add (dest, seg.geominfo[0].trignum); + segmbuf.Add (dest, seg.geominfo[1].trignum); + segmbuf.Add (dest, seg.surfnr1); + segmbuf.Add (dest, seg.surfnr2); + segmbuf.Add (dest, seg.edgenr); + segmbuf.Add (dest, seg.epgeominfo[0].dist); + segmbuf.Add (dest, seg.epgeominfo[1].edgenr); + segmbuf.Add (dest, seg.epgeominfo[1].dist); + segmbuf.Add (dest, seg.singedge_right); + segmbuf.Add (dest, seg.singedge_left); + segi[dest] += 14; + } + // paralleltop -> SetDistantSegm ( dest, ls, int ( segi[dest] / 14 ) ); + } + } + } + + for ( int dest = 1; dest < ntasks; dest++) + sendrequests.Append (MyMPI_ISend(segmbuf[dest], dest, MPI_TAG_MESH+5)); + */ + + PrintMessage ( 3, "now wait ..."); + + MPI_Waitall (sendrequests.Size(), &sendrequests[0], MPI_STATUS_IGNORE); + + MPI_Barrier(MPI_COMM_WORLD); + } + + + + + + + + + // slaves receive the mesh from the master + void Mesh :: ReceiveParallelMesh ( ) + { + int timer = NgProfiler::CreateTimer ("ReceiveParallelMesh"); + int timer_pts = NgProfiler::CreateTimer ("Receive points"); + int timer_els = NgProfiler::CreateTimer ("Receive elements"); + int timer_sels = NgProfiler::CreateTimer ("Receive surface elements"); + NgProfiler::RegionTimer reg(timer); + + + // string st; + + // receive vertices + NgProfiler::StartTimer (timer_pts); + + Array verts; + MyMPI_Recv (verts, 0, MPI_TAG_MESH+1); + + int numvert = verts.Size(); + paralleltop -> SetNV (numvert); + + // INDEX_CLOSED_HASHTABLE glob2loc_vert_ht (3*numvert+1); + INDEX_HASHTABLE glob2loc_vert_ht (3*numvert+1); + + for (int vert = 0; vert < numvert; vert++) + { + int globvert = verts[vert]; + paralleltop->SetLoc2Glob_Vert ( vert+1, globvert ); + glob2loc_vert_ht.Set (globvert, vert+1); + } + + for (int i = 0; i < numvert; i++) + AddPoint (netgen::Point<3> (0,0,0)); + + MPI_Datatype mptype = MeshPoint::MyGetMPIType(); + MPI_Status status; + MPI_Recv( &points[1], numvert, mptype, 0, MPI_TAG_MESH+1, MPI_COMM_WORLD, &status); + + Array dist_pnums; + MyMPI_Recv (dist_pnums, 0, MPI_TAG_MESH+1); + + for (int hi = 0; hi < dist_pnums.Size(); hi += 3) + paralleltop -> + SetDistantPNum (dist_pnums[hi+1], dist_pnums[hi]); // , dist_pnums[hi+2]); + + NgProfiler::StopTimer (timer_pts); + *testout << "got " << numvert << " vertices" << endl; + + { + Element el; + + Array elarray; + MyMPI_Recv (elarray, 0, MPI_TAG_MESH+2); + + NgProfiler::RegionTimer reg(timer_els); + + for (int ind = 0, elnum = 1; ind < elarray.Size(); elnum++) + { + paralleltop->SetLoc2Glob_VolEl ( elnum, elarray[ind++]); + + el.SetIndex(elarray[ind++]); + el.SetNP(elarray[ind++]); + + for ( int j = 0; j < el.GetNP(); j++) + el[j] = glob2loc_vert_ht.Get (elarray[ind++]); + + AddVolumeElement (el); + } + } + + { + Array fddata; + MyMPI_Recv (fddata, 0, MPI_TAG_MESH+3); + for (int i = 0; i < fddata.Size(); i += 6) + { + int faceind = AddFaceDescriptor + (FaceDescriptor(int(fddata[i]), int(fddata[i+1]), int(fddata[i+2]), 0)); + GetFaceDescriptor(faceind).SetBCProperty (int(fddata[i+3])); + GetFaceDescriptor(faceind).domin_singular = fddata[i+4]; + GetFaceDescriptor(faceind).domout_singular = fddata[i+5]; + } + } + + { + NgProfiler::RegionTimer reg(timer_sels); + Array selbuf; + + MyMPI_Recv ( selbuf, 0, MPI_TAG_MESH+4); + + int ii = 0; + int sel = 0; + + int nlocsel = selbuf[ii++]; + paralleltop -> SetNSE ( nlocsel ); + + while (ii < selbuf.Size()-1) + { + int globsel = selbuf[ii++]; + int faceind = selbuf[ii++]; + bool isghost = selbuf[ii++]; + int nep = selbuf[ii++]; + Element2d tri(nep); + tri.SetIndex(faceind); + for(int j = 1; j <= nep; j++) + { + tri.PNum(j) = glob2loc_vert_ht.Get (selbuf[ii++]); + tri.GeomInfoPi(j).trignum = selbuf[ii++]; + } + + paralleltop->SetLoc2Glob_SurfEl ( sel+1, globsel ); + AddSurfaceElement (tri); + sel ++; + } + } + + + + { + Array segmbuf; + MyMPI_Recv ( segmbuf, 0, MPI_TAG_MESH+5); + + Segment seg; + int globsegi; + int ii = 0; + int segi = 1; + int nsegloc = int ( segmbuf.Size() / 14 ) ; + paralleltop -> SetNSegm ( nsegloc ); + + while ( ii < segmbuf.Size() ) + { + globsegi = int (segmbuf[ii++]); + seg.si = int (segmbuf[ii++]); + + seg.pnums[0] = glob2loc_vert_ht.Get (int(segmbuf[ii++])); + seg.pnums[1] = glob2loc_vert_ht.Get (int(segmbuf[ii++])); + seg.geominfo[0].trignum = int( segmbuf[ii++] ); + seg.geominfo[1].trignum = int ( segmbuf[ii++]); + seg.surfnr1 = int ( segmbuf[ii++]); + seg.surfnr2 = int ( segmbuf[ii++]); + seg.edgenr = int ( segmbuf[ii++]); + seg.epgeominfo[0].dist = segmbuf[ii++]; + seg.epgeominfo[1].edgenr = int (segmbuf[ii++]); + seg.epgeominfo[1].dist = segmbuf[ii++]; + + seg.singedge_left = segmbuf[ii++]; + seg.singedge_right = segmbuf[ii++]; + + seg.epgeominfo[0].edgenr = seg.epgeominfo[1].edgenr; + + seg.domin = seg.surfnr1; + seg.domout = seg.surfnr2; + if ( seg.pnums[0] >0 && seg.pnums[1] > 0 ) + { + paralleltop-> SetLoc2Glob_Segm ( segi, globsegi ); + + AddSegment (seg); + segi++; + } + + } + } + + MPI_Barrier(MPI_COMM_WORLD); + + int timerloc = NgProfiler::CreateTimer ("Update local mesh"); + int timerloc2 = NgProfiler::CreateTimer ("CalcSurfacesOfNode"); + + NgProfiler::RegionTimer regloc(timerloc); + stringstream str; + str << "p" << id << ": got " << GetNE() << " elements and " + << GetNSE() << " surface elements"; + cout << str.str() << endl; + // PrintMessage (2, "Got ", GetNE(), " elements and ", GetNSE(), " surface elements"); + // PrintMessage (2, "Got ", GetNSE(), " surface elements"); + + NgProfiler::StartTimer (timerloc2); + + CalcSurfacesOfNode (); + + NgProfiler::StopTimer (timerloc2); + + topology -> Update(); + clusters -> Update(); + + // paralleltop -> UpdateCoarseGrid(); + + SetNextMajorTimeStamp(); + } + + + + + + // distribute the mesh to the slave processors + // call it only for the master ! + void Mesh :: Distribute () + { + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + + if (id != 0 || ntasks == 1 ) return; + +#ifdef METIS + ParallelMetis (); +#else + for (ElementIndex ei = 0; ei < GetNE(); ei++) + (*this)[ei].SetPartition(ntasks * ei/GetNE() + 1); +#endif + + /* + for (ElementIndex ei = 0; ei < GetNE(); ei++) + *testout << "el(" << ei << ") is in part " << (*this)[ei].GetPartition() << endl; + for (SurfaceElementIndex ei = 0; ei < GetNSE(); ei++) + *testout << "sel(" << int(ei) << ") is in part " << (*this)[ei].GetPartition() << endl; + */ + + // MyMPI_SendCmd ("mesh"); + SendRecvMesh (); + } + + +#ifdef METIS5 + void Mesh :: ParallelMetis ( ) + { + PrintMessage (3, "call metis 5 ..."); + + int timer = NgProfiler::CreateTimer ("Mesh::Partition"); + NgProfiler::RegionTimer reg(timer); + + idx_t ne = GetNE() + GetNSE() + GetNSeg(); + idx_t nn = GetNP(); + + Array eptr, eind; + for (int i = 0; i < GetNE(); i++) + { + eptr.Append (eind.Size()); + const Element & el = VolumeElement(i+1); + for (int j = 0; j < el.GetNP(); j++) + eind.Append (el[j]-1); + } + for (int i = 0; i < GetNSE(); i++) + { + eptr.Append (eind.Size()); + const Element2d & el = SurfaceElement(i+1); + for (int j = 0; j < el.GetNP(); j++) + eind.Append (el[j]-1); + } + for (int i = 0; i < GetNSeg(); i++) + { + eptr.Append (eind.Size()); + const Segment & el = LineSegment(i+1); + eind.Append (el[0]); + eind.Append (el[1]); + } + eptr.Append (eind.Size()); + Array epart(ne), npart(nn); + + int nparts = ntasks-1; + int edgecut; + + int ncommon = 3; + METIS_PartMeshDual (&ne, &nn, &eptr[0], &eind[0], NULL, NULL, &ncommon, &nparts, + NULL, NULL, + &edgecut, &epart[0], &npart[0]); + + /* + METIS_PartMeshNodal (&ne, &nn, &eptr[0], &eind[0], NULL, NULL, &nparts, + NULL, NULL, + &edgecut, &epart[0], &npart[0]); + */ + PrintMessage (3, "metis complete"); + // cout << "done" << endl; + + for (int i = 0; i < GetNE(); i++) + VolumeElement(i+1).SetPartition(epart[i] + 1); + for (int i = 0; i < GetNSE(); i++) + SurfaceElement(i+1).SetPartition(epart[i+GetNE()] + 1); + for (int i = 0; i < GetNSeg(); i++) + LineSegment(i+1).SetPartition(epart[i+GetNE()+GetNSE()] + 1); + + + + if (GetDimension() == 3) + { + + // surface elements attached to volume elements + Array boundarypoints (GetNP()); + boundarypoints = false; + + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + const Element2d & el = (*this)[sei]; + for (int j = 0; j < el.GetNP(); j++) + boundarypoints[el[j]] = true; + } + // Build Pnt2Element table, boundary points only + Array cnt(GetNP()); + cnt = 0; + for (ElementIndex ei = 0; ei < GetNE(); ei++) + { + const Element & el = (*this)[ei]; + for (int j = 0; j < el.GetNP(); j++) + if (boundarypoints[el[j]]) + cnt[el[j]]++; + } + TABLE pnt2el(cnt); + cnt = 0; + for (ElementIndex ei = 0; ei < GetNE(); ei++) + { + const Element & el = (*this)[ei]; + for (int j = 0; j < el.GetNP(); j++) + if (boundarypoints[el[j]]) + pnt2el.Add (el[j], ei); + } + + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + { + Element2d & sel = (*this)[sei]; + PointIndex pi1 = sel[0]; + FlatArray els = pnt2el[pi1]; + + sel.SetPartition (-1); + + for (int j = 0; j < els.Size(); j++) + { + const Element & el = (*this)[els[j]]; + + bool hasall = true; + + for (int k = 0; k < sel.GetNP(); k++) + { + bool haspi = false; + for (int l = 0; l < el.GetNP(); l++) + if (sel[k] == el[l]) + haspi = true; + + if (!haspi) hasall = false; + } + + if (hasall) + { + sel.SetPartition (el.GetPartition()); + break; + } + } + if (sel.GetPartition() == -1) + cerr << "no volume element found" << endl; + } + + + for (SegmentIndex si = 0; si < GetNSeg(); si++) + { + Segment & sel = (*this)[si]; + PointIndex pi1 = sel[0]; + FlatArray els = pnt2el[pi1]; + + sel.SetPartition (-1); + + for (int j = 0; j < els.Size(); j++) + { + const Element & el = (*this)[els[j]]; + + bool haspi[9] = { false }; // max surfnp + + for (int k = 0; k < 2; k++) + for (int l = 0; l < el.GetNP(); l++) + if (sel[k] == el[l]) + haspi[k] = true; + + bool hasall = true; + for (int k = 0; k < sel.GetNP(); k++) + if (!haspi[k]) hasall = false; + + if (hasall) + { + sel.SetPartition (el.GetPartition()); + break; + } + } + if (sel.GetPartition() == -1) + cerr << "no volume element found" << endl; + } + + + } + } + +#endif + + + + + +//========================== weights ================================================================= + + + + // distribute the mesh to the slave processors + // call it only for the master ! + void Mesh :: Distribute (Array & volume_weights , Array & surface_weights, Array & segment_weights) + { + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + + if (id != 0 || ntasks == 1 ) return; + +#ifdef METIS + ParallelMetis (volume_weights, surface_weights, segment_weights); +#else + for (ElementIndex ei = 0; ei < GetNE(); ei++) + (*this)[ei].SetPartition(ntasks * ei/GetNE() + 1); +#endif + + /* + for (ElementIndex ei = 0; ei < GetNE(); ei++) + *testout << "el(" << ei << ") is in part " << (*this)[ei].GetPartition() << endl; + for (SurfaceElementIndex ei = 0; ei < GetNSE(); ei++) + *testout << "sel(" << int(ei) << ") is in part " << (*this)[ei].GetPartition() << endl; + */ + + // MyMPI_SendCmd ("mesh"); + SendRecvMesh (); + } + + +#ifdef METIS5 + void Mesh :: ParallelMetis (Array & volume_weights , Array & surface_weights, Array & segment_weights) + { + PrintMessage (3, "call metis 5 with weights ..."); + + // cout << "segment_weights " << segment_weights << endl; + // cout << "surface_weights " << surface_weights << endl; + // cout << "volume_weights " << volume_weights << endl; + + int timer = NgProfiler::CreateTimer ("Mesh::Partition"); + NgProfiler::RegionTimer reg(timer); + + idx_t ne = GetNE() + GetNSE() + GetNSeg(); + idx_t nn = GetNP(); + + Array eptr, eind , nwgt; + for (int i = 0; i < GetNE(); i++) + { + eptr.Append (eind.Size()); + + const Element & el = VolumeElement(i+1); + + int ind = el.GetIndex(); + if (volume_weights.Size() epart(ne), npart(nn); + + int nparts = ntasks-1; + int edgecut; + + + int ncommon = 3; + METIS_PartMeshDual (&ne, &nn, &eptr[0], &eind[0], &nwgt[0], NULL, &ncommon, &nparts, + NULL, NULL, + &edgecut, &epart[0], &npart[0]); + /* + METIS_PartMeshNodal (&ne, &nn, &eptr[0], &eind[0], NULL, NULL, &nparts, + NULL, NULL, + &edgecut, &epart[0], &npart[0]); + */ + PrintMessage (3, "metis complete"); + // cout << "done" << endl; + + for (int i = 0; i < GetNE(); i++) + VolumeElement(i+1).SetPartition(epart[i] + 1); + for (int i = 0; i < GetNSE(); i++) + SurfaceElement(i+1).SetPartition(epart[i+GetNE()] + 1); + for (int i = 0; i < GetNSeg(); i++) + LineSegment(i+1).SetPartition(epart[i+GetNE()+GetNSE()] + 1); + } +#endif + + + +//=========================================================================================== + + + + + + + + + +#ifdef METIS4 + void Mesh :: ParallelMetis ( ) + { + int timer = NgProfiler::CreateTimer ("Mesh::Partition"); + NgProfiler::RegionTimer reg(timer); + + PrintMessage (3, "Metis called"); + + if (GetDimension() == 2) + { + PartDualHybridMesh2D ( ); // neloc ); + return; + } + + + idx_t ne = GetNE(); + idx_t nn = GetNP(); + + if (ntasks <= 2 || ne <= 1) + { + if (ntasks == 1) return; + + for (int i=1; i<=ne; i++) + VolumeElement(i).SetPartition(1); + + for (int i=1; i<=GetNSE(); i++) + SurfaceElement(i).SetPartition(1); + + return; + } + + + bool uniform_els = true; + + ELEMENT_TYPE elementtype = TET; + for (int el = 1; el <= GetNE(); el++) + if (VolumeElement(el).GetType() != elementtype) + { + uniform_els = false; + break; + } + + + if (!uniform_els) + { + PartHybridMesh (); + } + else + { + + // uniform (TET) mesh, JS + int npe = VolumeElement(1).GetNP(); + Array elmnts(ne*npe); + + int etype; + if (elementtype == TET) + etype = 2; + else if (elementtype == HEX) + etype = 3; + + + for (int i=1; i<=ne; i++) + for (int j=1; j<=npe; j++) + elmnts[(i-1)*npe+(j-1)] = VolumeElement(i).PNum(j)-1; + + int numflag = 0; + int nparts = ntasks-1; + int ncommon = 3; + int edgecut; + Array epart(ne), npart(nn); + + // if ( ntasks == 1 ) + // { + // (*this) = *mastermesh; + // nparts = 4; + // metis :: METIS_PartMeshDual (&ne, &nn, elmnts, &etype, &numflag, &nparts, + // &edgecut, epart, npart); + // cout << "done" << endl; + + // cout << "edge-cut: " << edgecut << ", balance: " << metis :: ComputeElementBalance(ne, nparts, epart) << endl; + + // for (int i=1; i<=ne; i++) + // { + // mastermesh->VolumeElement(i).SetPartition(epart[i-1]); + // } + + // return; + // } + + + int timermetis = NgProfiler::CreateTimer ("Metis itself"); + NgProfiler::StartTimer (timermetis); + +#ifdef METIS4 + cout << "call metis(4)_PartMeshDual ... " << flush; + METIS_PartMeshDual (&ne, &nn, &elmnts[0], &etype, &numflag, &nparts, + &edgecut, &epart[0], &npart[0]); +#else + cout << "call metis(5)_PartMeshDual ... " << endl; + // idx_t options[METIS_NOPTIONS]; + + Array eptr(ne+1); + for (int j = 0; j < ne+1; j++) + eptr[j] = 4*j; + + METIS_PartMeshDual (&ne, &nn, &eptr[0], &elmnts[0], NULL, NULL, &ncommon, &nparts, + NULL, NULL, + &edgecut, &epart[0], &npart[0]); +#endif + + NgProfiler::StopTimer (timermetis); + + cout << "complete" << endl; +#ifdef METIS4 + cout << "edge-cut: " << edgecut << ", balance: " + << ComputeElementBalance(ne, nparts, &epart[0]) << endl; +#endif + + // partition numbering by metis : 0 ... ntasks - 1 + // we want: 1 ... ntasks + for (int i=1; i<=ne; i++) + VolumeElement(i).SetPartition(epart[i-1] + 1); + } + + + for (int sei = 1; sei <= GetNSE(); sei++ ) + { + int ei1, ei2; + GetTopology().GetSurface2VolumeElement (sei, ei1, ei2); + Element2d & sel = SurfaceElement (sei); + + for (int j = 0; j < 2; j++) + { + int ei = (j == 0) ? ei1 : ei2; + if ( ei > 0 && ei <= GetNE() ) + { + sel.SetPartition (VolumeElement(ei).GetPartition()); + break; + } + } + } + + } +#endif + + + void Mesh :: PartHybridMesh () + { +#ifdef METIS + int ne = GetNE(); + + int nn = GetNP(); + int nedges = topology->GetNEdges(); + + idxtype *xadj, * adjacency, *v_weights = NULL, *e_weights = NULL; + + int weightflag = 0; + int numflag = 0; + int nparts = ntasks - 1; + + int options[5]; + options[0] = 0; + int edgecut; + idxtype * part; + + xadj = new idxtype[nn+1]; + part = new idxtype[nn]; + + Array cnt(nn+1); + cnt = 0; + + for ( int edge = 1; edge <= nedges; edge++ ) + { + int v1, v2; + topology->GetEdgeVertices ( edge, v1, v2); + cnt[v1-1] ++; + cnt[v2-1] ++; + } + + xadj[0] = 0; + for ( int n = 1; n <= nn; n++ ) + { + xadj[n] = idxtype(xadj[n-1] + cnt[n-1]); + } + + adjacency = new idxtype[xadj[nn]]; + cnt = 0; + + for ( int edge = 1; edge <= nedges; edge++ ) + { + int v1, v2; + topology->GetEdgeVertices ( edge, v1, v2); + adjacency[ xadj[v1-1] + cnt[v1-1] ] = v2-1; + adjacency[ xadj[v2-1] + cnt[v2-1] ] = v1-1; + cnt[v1-1]++; + cnt[v2-1]++; + } + + for ( int vert = 0; vert < nn; vert++ ) + { + FlatArray array ( cnt[vert], &adjacency[ xadj[vert] ] ); + BubbleSort(array); + } + +#ifdef METIS4 + METIS_PartGraphKway ( &nn, xadj, adjacency, v_weights, e_weights, &weightflag, + &numflag, &nparts, options, &edgecut, part ); +#else + cout << "currently not supported (metis5), A" << endl; +#endif + + Array nodesinpart(ntasks); + + for ( int el = 1; el <= ne; el++ ) + { + Element & volel = VolumeElement(el); + nodesinpart = 0; + + + int el_np = volel.GetNP(); + int partition = 0; + for ( int i = 0; i < el_np; i++ ) + nodesinpart[ part[volel[i]-1]+1 ] ++; + + for ( int i = 1; i < ntasks; i++ ) + if ( nodesinpart[i] > nodesinpart[partition] ) + partition = i; + + volel.SetPartition(partition); + } + + delete [] xadj; + delete [] part; + delete [] adjacency; +#else + cout << "parthybridmesh not available" << endl; +#endif + } + + + void Mesh :: PartDualHybridMesh ( ) // Array & neloc ) + { +#ifdef METIS + int ne = GetNE(); + + // int nn = GetNP(); + // int nedges = topology->GetNEdges(); + int nfaces = topology->GetNFaces(); + + idxtype *xadj, * adjacency, *v_weights = NULL, *e_weights = NULL; + + int weightflag = 0; + int numflag = 0; + int nparts = ntasks - 1; + + int options[5]; + options[0] = 0; + int edgecut; + idxtype * part; + + Array facevolels1(nfaces), facevolels2(nfaces); + facevolels1 = -1; + facevolels2 = -1; + + Array elfaces; + xadj = new idxtype[ne+1]; + part = new idxtype[ne]; + + Array cnt(ne+1); + cnt = 0; + + for ( int el=1; el <= ne; el++ ) + { + Element volel = VolumeElement(el); + topology->GetElementFaces(el, elfaces); + for ( int i = 0; i < elfaces.Size(); i++ ) + { + if ( facevolels1[elfaces[i]-1] == -1 ) + facevolels1[elfaces[i]-1] = el; + else + { + facevolels2[elfaces[i]-1] = el; + cnt[facevolels1[elfaces[i]-1]-1]++; + cnt[facevolels2[elfaces[i]-1]-1]++; + } + } + } + + xadj[0] = 0; + for ( int n = 1; n <= ne; n++ ) + { + xadj[n] = idxtype(xadj[n-1] + cnt[n-1]); + } + + adjacency = new idxtype[xadj[ne]]; + cnt = 0; + + for ( int face = 1; face <= nfaces; face++ ) + { + int e1, e2; + e1 = facevolels1[face-1]; + e2 = facevolels2[face-1]; + if ( e2 == -1 ) continue; + adjacency[ xadj[e1-1] + cnt[e1-1] ] = e2-1; + adjacency[ xadj[e2-1] + cnt[e2-1] ] = e1-1; + cnt[e1-1]++; + cnt[e2-1]++; + } + + for ( int el = 0; el < ne; el++ ) + { + FlatArray array ( cnt[el], &adjacency[ xadj[el] ] ); + BubbleSort(array); + } + + int timermetis = NgProfiler::CreateTimer ("Metis itself"); + NgProfiler::StartTimer (timermetis); + +#ifdef METIS4 + METIS_PartGraphKway ( &ne, xadj, adjacency, v_weights, e_weights, &weightflag, + &numflag, &nparts, options, &edgecut, part ); +#else + cout << "currently not supported (metis5), B" << endl; +#endif + + + NgProfiler::StopTimer (timermetis); + + Array nodesinpart(ntasks); + + for ( int el = 1; el <= ne; el++ ) + { + // Element & volel = VolumeElement(el); + nodesinpart = 0; + + VolumeElement(el).SetPartition(part[el-1 ] + 1); + + } + + /* + for ( int i=1; i<=ne; i++) + { + neloc[ VolumeElement(i).GetPartition() ] ++; + } + */ + + delete [] xadj; + delete [] part; + delete [] adjacency; +#else + cout << "partdualmesh not available" << endl; +#endif + + } + + + + + + void Mesh :: PartDualHybridMesh2D ( ) + { +#ifdef METIS + int ne = GetNSE(); + int nv = GetNV(); + + Array xadj(ne+1); + Array adjacency(ne*4); + + // first, build the vertex 2 element table: + Array cnt(nv); + cnt = 0; + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + for (int j = 0; j < (*this)[sei].GetNP(); j++) + cnt[ (*this)[sei][j] ] ++; + + TABLE vert2els(cnt); + for (SurfaceElementIndex sei = 0; sei < GetNSE(); sei++) + for (int j = 0; j < (*this)[sei].GetNP(); j++) + vert2els.Add ((*this)[sei][j], sei); + + + // find all neighbour elements + int cntnb = 0; + Array marks(ne); // to visit each neighbour just once + marks = -1; + for (SurfaceElementIndex sei = 0; sei < ne; sei++) + { + xadj[sei] = cntnb; + for (int j = 0; j < (*this)[sei].GetNP(); j++) + { + PointIndex vnr = (*this)[sei][j]; + + // all elements with at least one common vertex + for (int k = 0; k < vert2els[vnr].Size(); k++) + { + SurfaceElementIndex sei2 = vert2els[vnr][k]; + if (sei == sei2) continue; + if (marks[sei2] == sei) continue; + + // neighbour, if two common vertices + int common = 0; + for (int m1 = 0; m1 < (*this)[sei].GetNP(); m1++) + for (int m2 = 0; m2 < (*this)[sei2].GetNP(); m2++) + if ( (*this)[sei][m1] == (*this)[sei2][m2]) + common++; + + if (common >= 2) + { + marks[sei2] = sei; // mark as visited + adjacency[cntnb++] = sei2; + } + } + } + } + xadj[ne] = cntnb; + + idxtype *v_weights = NULL, *e_weights = NULL; + + int weightflag = 0; + int numflag = 0; + int nparts = ntasks - 1; + + int options[5]; + options[0] = 0; + int edgecut; + Array part(ne); + + for ( int el = 0; el < ne; el++ ) + BubbleSort (adjacency.Range (xadj[el], xadj[el+1])); + +#ifdef METIS4 + METIS_PartGraphKway ( &ne, &xadj[0], &adjacency[0], v_weights, e_weights, &weightflag, + &numflag, &nparts, options, &edgecut, &part[0] ); +#else + idx_t ncon = 1; + METIS_PartGraphKway ( &ne, &ncon, &xadj[0], &adjacency[0], + v_weights, NULL, e_weights, + &nparts, + NULL, NULL, NULL, + &edgecut, &part[0] ); +#endif + + + for (SurfaceElementIndex sei = 0; sei < ne; sei++) + (*this) [sei].SetPartition (part[sei]+1); +#else + cout << "partdualmesh not available" << endl; +#endif + + } + + + +} + + + +#endif diff --git a/libsrc/meshing/paralleltop.cpp b/libsrc/meshing/paralleltop.cpp new file mode 100644 index 00000000..138b339a --- /dev/null +++ b/libsrc/meshing/paralleltop.cpp @@ -0,0 +1,436 @@ +#ifdef PARALLEL + + +#include +#include "paralleltop.hpp" + + +namespace netgen +{ + + ParallelMeshTopology :: ParallelMeshTopology (const Mesh & amesh) + : mesh(amesh) + { + is_updated = false; + } + + + ParallelMeshTopology :: ~ParallelMeshTopology () + { + ; + } + + + void ParallelMeshTopology :: Reset () + { + *testout << "ParallelMeshTopology::Reset" << endl; + + if ( ntasks == 1 ) return; + + int ned = mesh.GetTopology().GetNEdges(); + int nfa = mesh.GetTopology().GetNFaces(); + + if (glob_edge.Size() != ned) + { + glob_edge.SetSize(ned); + glob_face.SetSize(nfa); + glob_edge = -1; + glob_face = -1; + + loc2distedge.ChangeSize (ned); + loc2distface.ChangeSize (nfa); + } + + if (glob_vert.Size() != mesh.GetNV()) + { + SetNV(mesh.GetNV()); + SetNE(mesh.GetNE()); + } + } + + + void ParallelMeshTopology :: Print() const + { + ; + } + + + void ParallelMeshTopology :: SetDistantFaceNum (int dest, int locnum) + { + for ( int i = 0; i < loc2distface[locnum-1].Size(); i+=1 ) + if ( loc2distface[locnum-1][i] == dest ) + return; + loc2distface.Add(locnum-1, dest); + } + + void ParallelMeshTopology :: SetDistantPNum (int dest, int locnum) + { + for ( int i = 0; i < loc2distvert[locnum-1].Size(); i+=1 ) + if ( loc2distvert[locnum-1][i] == dest ) + return; + loc2distvert.Add (locnum-1, dest); + } + + + void ParallelMeshTopology :: SetDistantEdgeNum (int dest, int locnum) + { + for ( int i = 0; i < loc2distedge[locnum-1].Size(); i+=1 ) + if ( loc2distedge[locnum-1][i] == dest ) + return; + loc2distedge.Add (locnum-1, dest); + } + + void ParallelMeshTopology :: SetNV (int anv) + { + glob_vert.SetSize(anv); + glob_vert = -1; + loc2distvert.ChangeSize (anv); + } + + void ParallelMeshTopology :: SetNE ( int ane ) + { + glob_el.SetSize (ane); + glob_el = -1; + } + + void ParallelMeshTopology :: SetNSE ( int anse ) + { + glob_surfel.SetSize(anse); + glob_surfel = -1; + } + + void ParallelMeshTopology :: SetNSegm ( int anseg ) + { + glob_segm.SetSize (anseg); + glob_segm = -1; + } + + + + + + + void ParallelMeshTopology :: UpdateCoarseGridGlobal () + { + if (id == 0) + PrintMessage ( 3, "UPDATE GLOBAL COARSEGRID STARTS" ); + + int timer = NgProfiler::CreateTimer ("UpdateCoarseGridGlobal"); + NgProfiler::RegionTimer reg(timer); + + *testout << "ParallelMeshTopology :: UpdateCoarseGridGlobal" << endl; + + const MeshTopology & topology = mesh.GetTopology(); + + if ( id == 0 ) + { + Array*> sendarrays(ntasks); + for (int dest = 1; dest < ntasks; dest++) + sendarrays[dest] = new Array; + + Array edges, faces; + for (int el = 1; el <= mesh.GetNE(); el++) + { + topology.GetElementFaces (el, faces); + topology.GetElementEdges (el, edges); + const Element & volel = mesh.VolumeElement (el); + + Array & sendarray = *sendarrays[volel.GetPartition()]; + + for ( int i = 0; i < edges.Size(); i++ ) + sendarray.Append (edges[i]); + for ( int i = 0; i < faces.Size(); i++ ) + sendarray.Append (faces[i]); + } + + for (int el = 1; el <= mesh.GetNSE(); el++) + { + topology.GetSurfaceElementEdges (el, edges); + const Element2d & surfel = mesh.SurfaceElement (el); + Array & sendarray = *sendarrays[surfel.GetPartition()]; + + for ( int i = 0; i < edges.Size(); i++ ) + sendarray.Append (edges[i]); + sendarray.Append (topology.GetSurfaceElementFace (el)); + } + + Array sendrequests; + for (int dest = 1; dest < ntasks; dest++) + sendrequests.Append (MyMPI_ISend (*sendarrays[dest], dest, MPI_TAG_MESH+10)); + MPI_Waitall (sendrequests.Size(), &sendrequests[0], MPI_STATUS_IGNORE); + + for (int dest = 1; dest < ntasks; dest++) + delete sendarrays[dest]; + } + + else + + { + Array recvarray; + MyMPI_Recv (recvarray, 0, MPI_TAG_MESH+10); + + int ii = 0; + + Array faces, edges; + + for (int volel = 1; volel <= mesh.GetNE(); volel++) + { + topology.GetElementEdges ( volel, edges); + for ( int i = 0; i < edges.Size(); i++) + SetLoc2Glob_Edge ( edges[i], recvarray[ii++]); + + topology.GetElementFaces( volel, faces); + for ( int i = 0; i < faces.Size(); i++) + SetLoc2Glob_Face ( faces[i], recvarray[ii++]); + } + + for (int surfel = 1; surfel <= mesh.GetNSE(); surfel++) + { + topology.GetSurfaceElementEdges (surfel, edges); + for (int i = 0; i < edges.Size(); i++) + SetLoc2Glob_Edge (edges[i], recvarray[ii++]); + int face = topology.GetSurfaceElementFace (surfel); + SetLoc2Glob_Face ( face, recvarray[ii++]); + } + } + + is_updated = true; + } + + + + + void ParallelMeshTopology :: UpdateCoarseGrid () + { + if (is_updated) return; + + Reset(); + static int timer = NgProfiler::CreateTimer ("UpdateCoarseGrid"); + NgProfiler::RegionTimer reg(timer); + + + (*testout) << "UPDATE COARSE GRID PARALLEL TOPOLOGY " << endl; + if (id == 0) + PrintMessage (1, "update parallel topology"); + + + // UpdateCoarseGridGlobal(); + + + + // MPI_Barrier (MPI_COMM_WORLD); + + MPI_Group MPI_GROUP_WORLD; + MPI_Group MPI_LocalGroup; + MPI_Comm MPI_LocalComm; + + int process_ranks[] = { 0 }; + MPI_Comm_group (MPI_COMM_WORLD, &MPI_GROUP_WORLD); + MPI_Group_excl (MPI_GROUP_WORLD, 1, process_ranks, &MPI_LocalGroup); + MPI_Comm_create (MPI_COMM_WORLD, MPI_LocalGroup, &MPI_LocalComm); + + if (id == 0) return; + + + + Array sendarray, recvarray; + + + static int timerv = NgProfiler::CreateTimer ("UpdateCoarseGrid - ex vertices"); + static int timere = NgProfiler::CreateTimer ("UpdateCoarseGrid - ex edges"); + static int timerf = NgProfiler::CreateTimer ("UpdateCoarseGrid - ex faces"); + + + Array cnt_send(ntasks-1); + + NgProfiler::StartTimer (timere); + + + const MeshTopology & topology = mesh.GetTopology(); + int nfa = topology . GetNFaces(); + int ned = topology . GetNEdges(); + + + // exchange edges + cnt_send = 0; + int v1, v2; + for (int edge = 1; edge <= ned; edge++) + { + topology.GetEdgeVertices (edge, v1, v2); + for (int dest = 1; dest < ntasks; dest++) + if (IsExchangeVert (dest, v1) && IsExchangeVert (dest, v2)) + cnt_send[dest-1]+=2; + } + + TABLE send_edges(cnt_send); + INDEX_2_HASHTABLE gv2e(2*ned); + + for (int edge = 1; edge <= ned; edge++) + { + topology.GetEdgeVertices (edge, v1, v2); + INDEX_2 es(GetGlobalPNum(v1), GetGlobalPNum(v2)); + es.Sort(); + + gv2e.Set (es, edge); + + for (int dest = 1; dest < ntasks; dest++) + if (IsExchangeVert (dest, v1) && IsExchangeVert (dest, v2)) + { + send_edges.Add (dest-1, es[0]); + send_edges.Add (dest-1, es[1]); + } + } + + TABLE recv_edges(ntasks-1); + MyMPI_ExchangeTable (send_edges, recv_edges, MPI_TAG_MESH+9, MPI_LocalComm); + + for (int sender = 1; sender < ntasks; sender ++) + if (id != sender) + { + FlatArray recvarray = recv_edges[sender-1]; + for (int ii = 0; ii < recvarray.Size(); ii+=2) + { + INDEX_2 gv12 (recvarray[ii],recvarray[ii+1]); + if (gv2e.Used (gv12)) + SetDistantEdgeNum (sender, gv2e.Get(gv12)); + } + } + + + NgProfiler::StopTimer (timere); + + // MPI_Barrier (MPI_LocalComm); + + + if (mesh.GetDimension() == 3) + { + NgProfiler::StartTimer (timerf); + + // exchange faces + cnt_send = 0; + Array verts; + for (int face = 1; face <= nfa; face++) + { + topology.GetFaceVertices (face, verts); + for (int dest = 1; dest < ntasks; dest++) + if (IsExchangeVert (dest, verts[0]) && + IsExchangeVert (dest, verts[1]) && + IsExchangeVert (dest, verts[2])) + cnt_send[dest-1]+=3; + } + + TABLE send_faces(cnt_send); + INDEX_3_HASHTABLE gv2f(2*nfa); + + for (int face = 1; face <= nfa; face++) + { + topology.GetFaceVertices (face, verts); + INDEX_3 fs (GetGlobalPNum(verts[0]), + GetGlobalPNum(verts[1]), + GetGlobalPNum(verts[2])); + fs.Sort(); + + gv2f.Set (fs, face); + + for (int dest = 1; dest < ntasks; dest++) + if (IsExchangeVert (dest, verts[0]) && + IsExchangeVert (dest, verts[1]) && + IsExchangeVert (dest, verts[2])) + { + send_faces.Add (dest-1, fs[0]); + send_faces.Add (dest-1, fs[1]); + send_faces.Add (dest-1, fs[2]); + } + } + + TABLE recv_faces(ntasks-1); + MyMPI_ExchangeTable (send_faces, recv_faces, MPI_TAG_MESH+9, MPI_LocalComm); + + for (int sender = 1; sender < ntasks; sender ++) + if (id != sender) + { + FlatArray recvarray = recv_faces[sender-1]; + for (int ii = 0; ii < recvarray.Size(); ii+=3) + { + INDEX_3 gv123 (recvarray[ii],recvarray[ii+1],recvarray[ii+2]); + if (gv2f.Used (gv123)) + SetDistantFaceNum (sender, gv2f.Get(gv123)); + } + } + + + /* + Array glob2loc; + + int maxface = 0; + for (int face = 1; face <= nfa; face++) + maxface = max (maxface, GetGlobalFaceNum (face)); + + // glob2loc.SetSize (nfaglob); + glob2loc.SetSize (maxface); + glob2loc = -1; + + for (int loc = 1; loc <= nfa; loc++) + glob2loc[GetGlobalFaceNum(loc)] = loc; + + cnt_send = 0; + Array verts; + for (int face = 1; face <= nfa; face++) + { + topology.GetFaceVertices (face, verts); + for (int dest = 1; dest < ntasks; dest++) + if (IsExchangeVert (dest, verts[0]) && + IsExchangeVert (dest, verts[1]) && + IsExchangeVert (dest, verts[2])) + { + cnt_send[dest-1]+=2; + } + } + + TABLE send_faces(cnt_send); + for (int face = 1; face <= nfa; face++) + { + topology.GetFaceVertices (face, verts); + for (int dest = 1; dest < ntasks; dest++) + { + if (IsExchangeVert (dest, verts[0]) && + IsExchangeVert (dest, verts[1]) && + IsExchangeVert (dest, verts[2])) + { + send_faces.Add (dest-1, GetGlobalFaceNum(face)); + send_faces.Add (dest-1, face); + } + } + } + TABLE recv_faces(ntasks-1); + MyMPI_ExchangeTable (send_faces, recv_faces, MPI_TAG_MESH+8, MPI_LocalComm); + + for (int sender = 1; sender < ntasks; sender ++) + if (id != sender) + { + FlatArray recvarray = recv_faces[sender-1]; + + for (int ii = 0; ii < recvarray.Size(); ) + { + int globf = recvarray[ii++]; + int distf = recvarray[ii++]; + + if (globf <= maxface) + { + int locf = glob2loc[globf]; + if (locf != -1) + SetDistantFaceNum (sender, locf); + } + } + } + */ + + NgProfiler::StopTimer (timerf); + } + + is_updated = true; + } +} + + +#endif diff --git a/libsrc/meshing/paralleltop.hpp b/libsrc/meshing/paralleltop.hpp new file mode 100644 index 00000000..a12d60cf --- /dev/null +++ b/libsrc/meshing/paralleltop.hpp @@ -0,0 +1,108 @@ +#ifndef FILE_PARALLELTOP +#define FILE_PARALLELTOP + +namespace netgen +{ + + + class ParallelMeshTopology + { + const Mesh & mesh; + + /** + mapping from local to distant vertex number + each row of the table corresponds to one vertex + each row contains a list of pairs (procnr, dist_vnum) + */ + + TABLE loc2distvert, loc2distedge, loc2distface; + + Array glob_vert, glob_edge, glob_face; + Array glob_el, glob_surfel, glob_segm; + + bool is_updated; + + public: + + ParallelMeshTopology (const Mesh & amesh); + ~ParallelMeshTopology (); + + void Reset (); + void Print() const; + + void UpdateCoarseGrid(); + void UpdateCoarseGridGlobal(); + // bool DoCoarseUpdate() const { return !coarseupdate; } + + + + /// set number of local vertices, reset sizes of loc2dist_vert, isexchangevert... + void SetNV (int anv); + void SetNE (int ane); + void SetNSE (int anse); + void SetNSegm (int anseg); + + + void SetLoc2Glob_Vert (int locnum, int globnum) { glob_vert[locnum-1] = globnum; } + void SetLoc2Glob_Edge (int locnum, int globnum) { glob_edge[locnum-1] = globnum; } + void SetLoc2Glob_Face (int locnum, int globnum) { glob_face[locnum-1] = globnum; } + void SetLoc2Glob_VolEl (int locnum, int globnum) { glob_el[locnum-1] = globnum; } + void SetLoc2Glob_SurfEl (int locnum, int globnum) { glob_surfel[locnum-1] = globnum; } + void SetLoc2Glob_Segm (int locnum, int globnum) { glob_segm[locnum-1] = globnum; } + + int GetGlobalPNum (int locnum) const { return glob_vert[locnum-1]; } + int GetGlobalEdgeNum (int locnum) const { return glob_edge[locnum-1]; } + int GetGlobalFaceNum (int locnum) const { return glob_face[locnum-1]; } + int GetGlobalElNum (int locnum) const { return glob_el[locnum-1]; } + int GetGlobalSElNum (int locnum) const { return glob_surfel[locnum-1]; } + + + void SetDistantFaceNum (int dest, int locnum); + void SetDistantPNum (int dest, int locnum); + void SetDistantEdgeNum (int dest, int locnum); + + int GetNDistantPNums (int locpnum) const { return loc2distvert[locpnum-1].Size(); } + int GetNDistantFaceNums (int locfacenum) const { return loc2distface[locfacenum-1].Size(); } + int GetNDistantEdgeNums ( int locedgenum) const { return loc2distedge[locedgenum-1].Size(); } + + void GetDistantPNums (int locpnum, int * distpnums ) const + { + for (int i = 0; i < loc2distvert[locpnum-1].Size(); i++ ) + distpnums[i] = loc2distvert[locpnum-1][i]; + } + + void GetDistantFaceNums (int locfacenum, int * distfacenums ) const + { + for ( int i = 0; i < loc2distface[locfacenum-1].Size(); i++ ) + distfacenums[i] = loc2distface[locfacenum-1][i]; + } + + void GetDistantFaceNums (int locfacenum, Array & distfacenums ) const + { + distfacenums = loc2distface[locfacenum-1]; + } + + void GetDistantEdgeNums (int locedgenum, int * distedgenums ) const + { + for (int i = 0; i < loc2distedge[locedgenum-1].Size(); i++ ) + distedgenums[i] = loc2distedge[locedgenum-1][i]; + } + + void GetDistantEdgeNums (int locedgenum, Array & distedgenums ) const + { + distedgenums = loc2distedge[locedgenum-1]; + } + + bool IsExchangeVert (int dest, int vnum) const + { + return loc2distvert[vnum-1].Contains (dest); + } + }; + + +} + + + + +#endif diff --git a/libsrc/meshing/parser2.cpp b/libsrc/meshing/parser2.cpp new file mode 100644 index 00000000..55bd1a5d --- /dev/null +++ b/libsrc/meshing/parser2.cpp @@ -0,0 +1,605 @@ +#include +#include "meshing.hpp" + +#ifdef WIN32 +#define COMMASIGN ':' +#else +#define COMMASIGN ',' +#endif + + +namespace netgen +{ + + +void LoadMatrixLine (istream & ist, DenseMatrix & m, int line) +{ + char ch; + int pnum; + float f; + + ist >> ch; + while (ch != '}') + { + ist.putback (ch); + ist >> f; + ist >> ch; + ist >> pnum; + + if (ch == 'x' || ch == 'X') + m.Elem(line, 2 * pnum - 1) = f; + if (ch == 'y' || ch == 'Y') + m.Elem(line, 2 * pnum) = f; + + ist >> ch; + if (ch == COMMASIGN) + ist >> ch; + } +} + + +void netrule :: LoadRule (istream & ist) +{ + char buf[256]; + char ch; + Point2d p; + INDEX_2 lin; + int i, j; + DenseMatrix tempoldutonewu(20, 20), tempoldutofreearea(20, 20), + tempoldutofreearealimit(20, 20); + + tempoldutonewu = 0; + tempoldutofreearea = 0; + tempoldutofreearealimit = 0; + + noldp = 0; + noldl = 0; + + ist.get (buf, sizeof(buf), '"'); + ist.get (ch); + ist.get (buf, sizeof(buf), '"'); + ist.get (ch); + + // if(name != NULL) + delete [] name; + name = new char[strlen (buf) + 1]; + strcpy (name, buf); + //(*testout) << "name " << name << endl; + // (*mycout) << "Rule " << name << " found." << endl; + + do + { + ist >> buf; + + //(*testout) << "buf " << buf << endl; + + if (strcmp (buf, "quality") == 0) + + { + ist >> quality; + } + + else if (strcmp (buf, "mappoints") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> p.X(); + ist >> ch; // ',' + ist >> p.Y(); + ist >> ch; // ')' + + points.Append (p); + noldp++; + + tolerances.SetSize (noldp); + tolerances.Elem(noldp).f1 = 1.0; + tolerances.Elem(noldp).f2 = 0; + tolerances.Elem(noldp).f3 = 1.0; + + ist >> ch; + while (ch != ';') + { + if (ch == '{') + { + ist >> tolerances.Elem(noldp).f1; + ist >> ch; // ',' + ist >> tolerances.Elem(noldp).f2; + ist >> ch; // ',' + ist >> tolerances.Elem(noldp).f3; + ist >> ch; // '}' + } + else if (ch == 'd') + { + // delpoints.Append (noldp); + ist >> ch; // 'e' + ist >> ch; // 'l' + } + + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + + else if (strcmp (buf, "maplines") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> lin.I1(); + ist >> ch; // ',' + ist >> lin.I2(); + ist >> ch; // ')' + + + //(*testout) << "read line " << lin.I1() << " " << lin.I2() << endl; + lines.Append (lin); + linevecs.Append (points.Get(lin.I2()) - points.Get(lin.I1())); + noldl++; + linetolerances.SetSize (noldl); + linetolerances.Elem(noldl).f1 = 0; + linetolerances.Elem(noldl).f2 = 0; + linetolerances.Elem(noldl).f3 = 0; + + //(*testout) << "mapl1" << endl; + ist >> ch; + while (ch != ';') + { + //(*testout) << "working on character \""<> linetolerances.Elem(noldl).f1; + ist >> ch; // ',' + ist >> linetolerances.Elem(noldl).f2; + ist >> ch; // ',' + ist >> linetolerances.Elem(noldl).f3; + ist >> ch; // '}' + } + else if (ch == 'd') + { + dellines.Append (noldl); + ist >> ch; // 'e' + ist >> ch; // 'l' + //(*testout) << "read del" << endl; + } + + ist >> ch; + //(*testout) << "read character \""<> ch; + //(*testout) << "read next character \""<> ch; + + while (ch == '(') + { + ist >> p.X(); + ist >> ch; // ',' + ist >> p.Y(); + ist >> ch; // ')' + + points.Append (p); + + ist >> ch; + while (ch != ';') + { + if (ch == '{') + { + LoadMatrixLine (ist, tempoldutonewu, + 2 * (points.Size()-noldp) - 1); + + ist >> ch; // '{' + LoadMatrixLine (ist, tempoldutonewu, + 2 * (points.Size()-noldp)); + } + + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "newlines") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> lin.I1(); + ist >> ch; // ',' + ist >> lin.I2(); + ist >> ch; // ')' + + lines.Append (lin); + linevecs.Append (points.Get(lin.I2()) - points.Get(lin.I1())); + + ist >> ch; + while (ch != ';') + { + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "freearea") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> p.X(); + ist >> ch; // ',' + ist >> p.Y(); + ist >> ch; // ')' + + freezone.Append (p); + freezonelimit.Append (p); + + ist >> ch; + while (ch != ';') + { + if (ch == '{') + { + LoadMatrixLine (ist, tempoldutofreearea, + 2 * freezone.Size() - 1); + + ist >> ch; // '{' + LoadMatrixLine (ist, tempoldutofreearea, + 2 * freezone.Size()); + } + + ist >> ch; + } + + ist >> ch; + } + + for (i = 1; i <= tempoldutofreearealimit.Height(); i++) + for (j = 1; j <= tempoldutofreearealimit.Width(); j++) + tempoldutofreearealimit.Elem(i,j) = + tempoldutofreearea.Elem(i,j); + + + ist.putback (ch); + } + else if (strcmp (buf, "freearea2") == 0) + { + ist >> ch; + int freepi = 0; + tempoldutofreearealimit = 0; + + while (ch == '(') + { + freepi++; + + ist >> p.X(); + ist >> ch; // ',' + ist >> p.Y(); + ist >> ch; // ')' + + freezonelimit.Elem(freepi) = p; + + ist >> ch; + while (ch != ';') + { + if (ch == '{') + { + LoadMatrixLine (ist, tempoldutofreearealimit, + 2 * freepi - 1); + + ist >> ch; // '{' + LoadMatrixLine (ist, tempoldutofreearealimit, + 2 * freepi); + } + + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "elements") == 0) + { + ist >> ch; + + while (ch == '(') + { + elements.Append (Element2d()); + + ist >> elements.Last().PNum(1); + ist >> ch; // ',' + + if (ch == COMMASIGN) + { + ist >> elements.Last().PNum(2); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + ist >> elements.Last().PNum(3); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + elements.Last().SetType (QUAD); + ist >> elements.Last().PNum(4); + ist >> ch; // ',' + + // const Element2d & el = elements.Last(); + /* + orientations.Append (threeint(el.PNum(1), el.PNum(2), el.PNum(3))); + orientations.Append (threeint(el.PNum(2), el.PNum(3), el.PNum(4))); + orientations.Append (threeint(el.PNum(3), el.PNum(4), el.PNum(1))); + orientations.Append (threeint(el.PNum(4), el.PNum(1), el.PNum(2))); + */ + } + + ist >> ch; + while (ch != ';') + { + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "orientations") == 0) + + { + ist >> ch; + + while (ch == '(') + { + // threeint a = threeint(); + orientations.Append (threeint()); + + ist >> orientations.Last().i1; + ist >> ch; // ',' + ist >> orientations.Last().i2; + ist >> ch; // ',' + ist >> orientations.Last().i3; + ist >> ch; // ',' + + ist >> ch; + while (ch != ';') + { + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "endrule") != 0) + { + PrintSysError ("Parser error, unknown token ", buf); + } + } + while (!ist.eof() && strcmp (buf, "endrule") != 0); + + oldutonewu.SetSize (2 * (points.Size() - noldp), 2 * noldp); + oldutofreearea.SetSize (2 * freezone.Size(), 2 * noldp); + oldutofreearealimit.SetSize (2 * freezone.Size(), 2 * noldp); + + for (i = 1; i <= oldutonewu.Height(); i++) + for (j = 1; j <= oldutonewu.Width(); j++) + oldutonewu.Elem(i, j) = tempoldutonewu.Elem(i, j); + + for (i = 1; i <= oldutofreearea.Height(); i++) + for (j = 1; j <= oldutofreearea.Width(); j++) + oldutofreearea.Elem(i, j) = tempoldutofreearea.Elem(i, j); + + for (i = 1; i <= oldutofreearea.Height(); i++) + for (j = 1; j <= oldutofreearea.Width(); j++) + oldutofreearealimit.Elem(i, j) = tempoldutofreearealimit.Elem(i, j); + + freesetinequ.SetSize (freezone.Size()); + + + { + char ok; + int minn; + Array pnearness (noldp); + + for (i = 1; i <= pnearness.Size(); i++) + pnearness.Elem(i) = 1000; + + for (j = 1; j <= 2; j++) + pnearness.Elem(GetPointNr (1, j)) = 0; + + do + { + ok = 1; + + for (i = 1; i <= noldl; i++) + { + minn = 1000; + for (j = 1; j <= 2; j++) + minn = min2 (minn, pnearness.Get(GetPointNr (i, j))); + + for (j = 1; j <= 2; j++) + if (pnearness.Get(GetPointNr (i, j)) > minn+1) + { + ok = 0; + pnearness.Elem(GetPointNr (i, j)) = minn+1; + } + } + } + while (!ok); + + lnearness.SetSize (noldl); + + for (i = 1; i <= noldl; i++) + { + lnearness.Elem(i) = 0; + for (j = 1; j <= 2; j++) + lnearness.Elem(i) += pnearness.Get(GetPointNr (i, j)); + } + } + + oldutofreearea_i.SetSize (10); + freezone_i.SetSize (10); + + for (i = 0; i < oldutofreearea_i.Size(); i++) + { + double lam1 = 1.0/(i+1); + + oldutofreearea_i[i] = new DenseMatrix (oldutofreearea.Height(), oldutofreearea.Width()); + DenseMatrix & mati = *oldutofreearea_i[i]; + for (j = 0; j < oldutofreearea.Height(); j++) + for (int k = 0; k < oldutofreearea.Width(); k++) + mati(j,k) = lam1 * oldutofreearea(j,k) + (1 - lam1) * oldutofreearealimit(j,k); + + freezone_i[i] = new Array (freezone.Size()); + Array & fzi = *freezone_i[i]; + for (int j = 0; j < freezone.Size(); j++) + fzi[j] = freezonelimit[j] + lam1 * (freezone[j] - freezonelimit[j]); + } +} + + + + +extern const char * triarules[]; +extern const char * quadrules[]; + +void Meshing2 :: LoadRules (const char * filename, bool quad) +{ + char buf[256]; + istream * ist; + //char *tr1 = NULL; + string tr1; + + /* + ifstream ist (filename); + if (!ist.good()) + { + cerr << "Rule description file " << filename << " not found" << endl; + exit (1); + } + */ + + + if (filename) + { + // (*mycout) << "rule-filename = " << filename << endl; + ist = new ifstream (filename); + } + else + { + /* connect tetrules to one string */ + const char ** hcp; + + // if (!mparam.quad) + if (!quad) + { + hcp = triarules; + PrintMessage (3, "load internal triangle rules"); + } + else + { + hcp = quadrules; + PrintMessage (3, "load internal quad rules"); + // LoadRules ("rules/quad.rls"); + } + + size_t len = 0; + while (*hcp) + { + // (*testout) << "POS2 *hcp " << *hcp << endl; + len += strlen (*hcp); + hcp++; + } + //tr1 = new char[len+1]; + //tr1[0] = 0; + tr1.reserve(len+1); + + + // if (!mparam.quad) + if (!quad) + hcp = triarules; + else + hcp = quadrules; + + + //char * tt1 = tr1; + while (*hcp) + { + //strcat (tt1, *hcp); + //tt1 += strlen (*hcp); + tr1.append(*hcp); + hcp++; + } + +#ifdef WIN32 + // VC++ 2005 workaround + for(string::size_type i=0; igood()) + { + cerr << "Rule description file " << filename << " not found" << endl; + delete ist; + exit (1); + } + + while (!ist->eof()) + { + buf[0] = 0; + (*ist) >> buf; + + if (strcmp (buf, "rule") == 0) + { + //(*testout) << "found rule" << endl; + netrule * rule = new netrule; + //(*testout) << "fr1" << endl; + rule -> LoadRule(*ist); + //(*testout) << "fr2" << endl; + + rules.Append (rule); + } + //(*testout) << "loop" << endl; + } + //(*testout) << "POS3" << endl; + + delete ist; + //delete [] tr1; +} + +} diff --git a/libsrc/meshing/parser3.cpp b/libsrc/meshing/parser3.cpp new file mode 100644 index 00000000..c6ccba4a --- /dev/null +++ b/libsrc/meshing/parser3.cpp @@ -0,0 +1,1019 @@ +#include +#include "meshing.hpp" + +#ifdef WIN32 +#define COMMASIGN ':' +#else +#define COMMASIGN ',' +#endif + + +namespace netgen +{ + +extern const char * tetrules[]; + +void LoadVMatrixLine (istream & ist, DenseMatrix & m, int line) +{ + char ch; + int pnum; + float f; + + ist >> ch; + while (ch != '}') + { + ist.putback (ch); + ist >> f; + ist >> ch; + ist >> pnum; + + if (ch == 'x' || ch == 'X') + m.Elem(line, 3 * pnum - 2) = f; + if (ch == 'y' || ch == 'Y') + m.Elem(line, 3 * pnum - 1) = f; + if (ch == 'z' || ch == 'Z') + m.Elem(line, 3 * pnum ) = f; + + if (ch == 'p' || ch == 'P') + { + m.Elem(line , 3 * pnum-2) = f; + m.Elem(line+1, 3 * pnum-1) = f; + m.Elem(line+2, 3 * pnum ) = f; + } + + ist >> ch; + if (ch == COMMASIGN) + ist >> ch; + } +} + + + + + +int vnetrule :: NeighbourTrianglePoint (const threeint & t1, const threeint & t2) const +{ + Array tr1(3); + Array tr2(3); + tr1.Elem(1)=t1.i1; + tr1.Elem(2)=t1.i2; + tr1.Elem(3)=t1.i3; + tr2.Elem(1)=t2.i1; + tr2.Elem(2)=t2.i2; + tr2.Elem(3)=t2.i3; + + + int ret=0; + + for (int i=1; i<=3; i++) + { + for (int j=1; j<=3; j++) + { + if ((tr1.Get(i)==tr2.Get(j) && tr1.Get((i%3)+1)==tr2.Get((j%3)+1)) || + (tr1.Get(i)==tr2.Get((j%3)+1) && tr1.Get((i%3)+1)==tr2.Get(j))) + {ret = tr2.Get((j+1)%3+1);} + } + } + + return ret; + +} + +void vnetrule :: LoadRule (istream & ist) +{ + char buf[256]; + char ch, ok; + Point3d p; + Element2d face; + int i, j, i1, i2, i3, fs, ii, ii1, ii2, ii3; + twoint edge; + DenseMatrix tempoldutonewu(30, 20), + tempoldutofreezone(30, 20), + tempoldutofreezonelimit(30, 20), + tfz(20, 20), + tfzl(20, 20); + + tempoldutonewu = 0; + tempoldutofreezone = 0; + tfz = 0; + tfzl = 0; + + + noldp = 0; + noldf = 0; + + ist.get (buf, sizeof(buf), '"'); + ist.get (ch); + ist.get (buf, sizeof(buf), '"'); + ist.get (ch); + + delete [] name; + name = new char[strlen (buf) + 1]; + strcpy (name, buf); + // (*mycout) << "Rule " << name << " found." << endl; + + do + { + ist >> buf; + + if (strcmp (buf, "quality") == 0) + + { + ist >> quality; + } + + else if (strcmp (buf, "flags") == 0) + { + ist >> ch; + while (ch != ';') + { + flags.Append (ch); + ist >> ch; + } + } + + else if (strcmp (buf, "mappoints") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> p.X(); + ist >> ch; // ',' + ist >> p.Y(); + ist >> ch; // ',' + ist >> p.Z(); + ist >> ch; // ')' + + points.Append (p); + noldp++; + + tolerances.SetSize (noldp); + tolerances.Elem(noldp) = 1; + + ist >> ch; + while (ch != ';') + { + if (ch == '{') + { + ist >> tolerances.Elem(noldp); + ist >> ch; // '}' + } + + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + + else if (strcmp (buf, "mapfaces") == 0) + { + ist >> ch; + + while (ch == '(') + { + face.SetType(TRIG); + ist >> face.PNum(1); + ist >> ch; // ',' + ist >> face.PNum(2); + ist >> ch; // ',' + ist >> face.PNum(3); + ist >> ch; // ')' or ',' + if (ch == COMMASIGN) + { + face.SetType(QUAD); + ist >> face.PNum(4); + ist >> ch; // ')' + } + faces.Append (face); + noldf++; + + ist >> ch; + while (ch != ';') + { + if (ch == 'd') + { + delfaces.Append (noldf); + ist >> ch; // 'e' + ist >> ch; // 'l' + } + + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "mapedges") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> edge.i1; + ist >> ch; // ',' + ist >> edge.i2; + ist >> ch; // ')' + + edges.Append (edge); + + ist >> ch; + while (ch != ';') + { + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + + else if (strcmp (buf, "newpoints") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> p.X(); + ist >> ch; // ',' + ist >> p.Y(); + ist >> ch; // ',' + ist >> p.Z(); + ist >> ch; // ')' + + points.Append (p); + + ist >> ch; + while (ch != ';') + { + if (ch == '{') + { + LoadVMatrixLine (ist, tempoldutonewu, + 3 * (points.Size()-noldp) - 2); + + ist >> ch; // '{' + LoadVMatrixLine (ist, tempoldutonewu, + 3 * (points.Size()-noldp) - 1); + + ist >> ch; // '{' + LoadVMatrixLine (ist, tempoldutonewu, + 3 * (points.Size()-noldp) ); + } + + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "newfaces") == 0) + { + ist >> ch; + + while (ch == '(') + { + face.SetType(TRIG); + ist >> face.PNum(1); + ist >> ch; // ',' + ist >> face.PNum(2); + ist >> ch; // ',' + ist >> face.PNum(3); + ist >> ch; // ')' or ',' + if (ch == COMMASIGN) + { + face.SetType(QUAD); + ist >> face.PNum(4); + ist >> ch; // ')' + } + faces.Append (face); + + ist >> ch; + while (ch != ';') + { + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "freezone") == 0) + { + ist >> ch; + + while (ch == '(') + { + ist >> p.X(); + ist >> ch; // ',' + ist >> p.Y(); + ist >> ch; // ',' + ist >> p.Z(); + ist >> ch; // ')' + + freezone.Append (p); + + ist >> ch; + while (ch != ';') + { + if (ch == '{') + { + LoadVMatrixLine (ist, tempoldutofreezone, + 3 * freezone.Size() - 2); + + ist >> ch; // '{' + LoadVMatrixLine (ist, tempoldutofreezone, + 3 * freezone.Size() - 1); + + ist >> ch; // '{' + LoadVMatrixLine (ist, tempoldutofreezone, + 3 * freezone.Size() ); + } + + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + else if (strcmp (buf, "freezone2") == 0) + { + int k, nfp; + + nfp = 0; + ist >> ch; + + DenseMatrix hm1(3, 50), hm2(50, 50), hm3(50, 50); + hm3 = 0; + + while (ch == '{') + { + hm1 = 0; + nfp++; + LoadVMatrixLine (ist, hm1, 1); + + for (i = 1; i <= points.Size(); i++) + tfz.Elem(nfp, i) = hm1.Get(1, 3*i-2); + + + p.X() = p.Y() = p.Z() = 0; + for (i = 1; i <= points.Size(); i++) + { + p.X() += hm1.Get(1, 3*i-2) * points.Get(i).X(); + p.Y() += hm1.Get(1, 3*i-2) * points.Get(i).Y(); + p.Z() += hm1.Get(1, 3*i-2) * points.Get(i).Z(); + } + freezone.Append (p); + freezonelimit.Append (p); + + hm2 = 0; + for (i = 1; i <= 3 * noldp; i++) + hm2.Elem(i, i) = 1; + for (i = 1; i <= 3 * noldp; i++) + for (j = 1; j <= 3 * (points.Size() - noldp); j++) + hm2.Elem(j + 3 * noldp, i) = tempoldutonewu.Get(j, i); + + for (i = 1; i <= 3; i++) + for (j = 1; j <= 3 * noldp; j++) + { + double sum = 0; + for (k = 1; k <= 3 * points.Size(); k++) + sum += hm1.Get(i, k) * hm2.Get(k, j); + + hm3.Elem(i + 3 * (nfp-1), j) = sum; + } + + // (*testout) << "freepoint: " << p << endl; + + while (ch != ';') + ist >> ch; + + ist >> ch; + } + + tfzl = tfz; + + tempoldutofreezone = hm3; + tempoldutofreezonelimit = hm3; + ist.putback(ch); + } + + else if (strcmp (buf, "freezonelimit") == 0) + { + int k, nfp; + nfp = 0; + ist >> ch; + + DenseMatrix hm1(3, 50), hm2(50, 50), hm3(50, 50); + hm3 = 0; + + while (ch == '{') + { + hm1 = 0; + nfp++; + LoadVMatrixLine (ist, hm1, 1); + + for (i = 1; i <= points.Size(); i++) + tfzl.Elem(nfp, i) = hm1.Get(1, 3*i-2); + + + p.X() = p.Y() = p.Z() = 0; + for (i = 1; i <= points.Size(); i++) + { + p.X() += hm1.Get(1, 3*i-2) * points.Get(i).X(); + p.Y() += hm1.Get(1, 3*i-2) * points.Get(i).Y(); + p.Z() += hm1.Get(1, 3*i-2) * points.Get(i).Z(); + } + freezonelimit.Elem(nfp) = p; + + hm2 = 0; + for (i = 1; i <= 3 * noldp; i++) + hm2.Elem(i, i) = 1; + for (i = 1; i <= 3 * noldp; i++) + for (j = 1; j <= 3 * (points.Size() - noldp); j++) + hm2.Elem(j + 3 * noldp, i) = tempoldutonewu.Get(j, i); + + for (i = 1; i <= 3; i++) + for (j = 1; j <= 3 * noldp; j++) + { + double sum = 0; + for (k = 1; k <= 3 * points.Size(); k++) + sum += hm1.Get(i, k) * hm2.Get(k, j); + + hm3.Elem(i + 3 * (nfp-1), j) = sum; + } + + // (*testout) << "freepoint: " << p << endl; + + while (ch != ';') + ist >> ch; + + ist >> ch; + } + + tempoldutofreezonelimit = hm3; + ist.putback(ch); + } + + else if (strcmp (buf, "freeset") == 0) + { + freesets.Append (new Array); + + ist >> ch; + + while (ch != ';') + { + ist.putback (ch); + ist >> i; + freesets.Last()->Append(i); + ist >> ch; + } + } + + else if (strcmp (buf, "elements") == 0) + { + ist >> ch; + + while (ch == '(') + { + elements.Append (Element(TET)); + + // elements.Last().SetNP(1); + ist >> elements.Last().PNum(1); + ist >> ch; // ',' + + if (ch == COMMASIGN) + { + // elements.Last().SetNP(2); + ist >> elements.Last().PNum(2); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // elements.Last().SetNP(3); + ist >> elements.Last().PNum(3); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // elements.Last().SetNP(4); + elements.Last().SetType(TET); + ist >> elements.Last().PNum(4); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // elements.Last().SetNP(5); + elements.Last().SetType(PYRAMID); + ist >> elements.Last().PNum(5); + ist >> ch; // ',' + } + if (ch == COMMASIGN) + { + // elements.Last().SetNP(6); + elements.Last().SetType(PRISM); + ist >> elements.Last().PNum(6); + ist >> ch; // ',' + } + + /* + orientations.Append (fourint()); + orientations.Last().i1 = elements.Last().PNum(1); + orientations.Last().i2 = elements.Last().PNum(2); + orientations.Last().i3 = elements.Last().PNum(3); + orientations.Last().i4 = elements.Last().PNum(4); + */ + + ist >> ch; + while (ch != ';') + { + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + else if (strcmp (buf, "orientations") == 0) + + { + ist >> ch; + + while (ch == '(') + { + // fourint a = fourint(); + orientations.Append (fourint()); + + ist >> orientations.Last().i1; + ist >> ch; // ',' + ist >> orientations.Last().i2; + ist >> ch; // ',' + ist >> orientations.Last().i3; + ist >> ch; // ',' + ist >> orientations.Last().i4; + ist >> ch; // ',' + + + ist >> ch; + while (ch != ';') + { + ist >> ch; + } + + ist >> ch; + } + + ist.putback (ch); + } + + + else if (strcmp (buf, "endrule") != 0) + { + PrintSysError ("Parser3d, unknown token " , buf); + } + } + while (!ist.eof() && strcmp (buf, "endrule") != 0); + + + // (*testout) << endl; + // (*testout) << Name() << endl; + // (*testout) << "no1 = " << GetNO() << endl; + + oldutonewu.SetSize (3 * (points.Size() - noldp), 3 * noldp); + oldutonewu = 0; + + for (i = 1; i <= oldutonewu.Height(); i++) + for (j = 1; j <= oldutonewu.Width(); j++) + oldutonewu.Elem(i, j) = tempoldutonewu.Elem(i, j); + + + /* + oldutofreezone = new SparseMatrixFlex (3 * freezone.Size(), 3 * noldp); + oldutofreezonelimit = new SparseMatrixFlex (3 * freezone.Size(), 3 * noldp); + + oldutofreezone -> SetSymmetric(0); + oldutofreezonelimit -> SetSymmetric(0); + */ + + /* + oldutofreezone = new DenseMatrix (3 * freezone.Size(), 3 * noldp); + oldutofreezonelimit = new DenseMatrix (3 * freezone.Size(), 3 * noldp); + + for (i = 1; i <= oldutofreezone->Height(); i++) + for (j = 1; j <= oldutofreezone->Width(); j++) + // if (j == 4 || j >= 7) + { + if (tempoldutofreezone.Elem(i, j)) + (*oldutofreezone)(i, j) = tempoldutofreezone(i, j); + if (tempoldutofreezonelimit.Elem(i, j)) + (*oldutofreezonelimit)(i, j) = tempoldutofreezonelimit(i, j); + } + */ + + + + + oldutofreezone = new DenseMatrix (freezone.Size(), points.Size()); + oldutofreezonelimit = new DenseMatrix (freezone.Size(), points.Size()); + // oldutofreezone = new SparseMatrixFlex (freezone.Size(), points.Size()); + // oldutofreezonelimit = new SparseMatrixFlex (freezone.Size(), points.Size()); + + for (i = 1; i <= freezone.Size(); i++) + for (j = 1; j <= points.Size(); j++) + { + if (tfz.Elem(i, j)) + (*oldutofreezone).Elem(i, j) = tfz.Elem(i, j); + if (tfzl.Elem(i, j)) + (*oldutofreezonelimit).Elem(i, j) = tfzl.Elem(i, j); + } + + /* + (*testout) << "Rule " << Name() << endl; + (*testout) << "oldutofreezone = " << (*oldutofreezone) << endl; + (*testout) << "oldutofreezonelimit = " << (*oldutofreezonelimit) << endl; + */ + + freezonepi.SetSize (freezone.Size()); + for (i = 1; i <= freezonepi.Size(); i++) + freezonepi.Elem(i) = 0; + for (i = 1; i <= freezone.Size(); i++) + for (j = 1; j <= noldp; j++) + if (Dist (freezone.Get(i), points.Get(j)) < 1e-8) + freezonepi.Elem(i) = j; + + + + + for (i = 1; i <= elements.Size(); i++) + { + if (elements.Elem(i).GetNP() == 4) + { + orientations.Append (fourint()); + orientations.Last().i1 = elements.Get(i).PNum(1); + orientations.Last().i2 = elements.Get(i).PNum(2); + orientations.Last().i3 = elements.Get(i).PNum(3); + orientations.Last().i4 = elements.Get(i).PNum(4); + } + if (elements.Elem(i).GetNP() == 5) + { + orientations.Append (fourint()); + orientations.Last().i1 = elements.Get(i).PNum(1); + orientations.Last().i2 = elements.Get(i).PNum(2); + orientations.Last().i3 = elements.Get(i).PNum(3); + orientations.Last().i4 = elements.Get(i).PNum(5); + + orientations.Append (fourint()); + orientations.Last().i1 = elements.Get(i).PNum(1); + orientations.Last().i2 = elements.Get(i).PNum(3); + orientations.Last().i3 = elements.Get(i).PNum(4); + orientations.Last().i4 = elements.Get(i).PNum(5); + } + } + + + + if (freesets.Size() == 0) + { + freesets.Append (new Array); + for (i = 1; i <= freezone.Size(); i++) + freesets.Elem(1)->Append(i); + } + + + // testout << "Freezone: " << endl; + + // for (i = 1; i <= freezone.Size(); i++) + // (*testout) << "freepoint: " << freezone.Get(i) << endl; + Vector vp(points.Size()), vfp(freezone.Size()); + + + if (quality < 100) + { + for (int i = 1; i <= 3; i++) + { + for (int j = 1; j <= points.Size(); j++) + vp(j-1) = points.Get(j).X(i); + oldutofreezone->Mult(vp, vfp); + for (int j = 1; j <= freezone.Size(); j++) + freezone.Elem(j).X(i) = vfp(j-1); + } + // for (i = 1; i <= freezone.Size(); i++) + // (*testout) << "freepoint: " << freezone.Get(i) << endl; + } + + + for (fs = 1; fs <= freesets.Size(); fs++) + { + freefaces.Append (new Array); + + Array & freeset = *freesets.Elem(fs); + Array & freesetfaces = *freefaces.Last(); + + for (ii1 = 1; ii1 <= freeset.Size(); ii1++) + for (ii2 = 1; ii2 <= freeset.Size(); ii2++) + for (ii3 = 1; ii3 <= freeset.Size(); ii3++) + if (ii1 < ii2 && ii1 < ii3 && ii2 != ii3) + { + i1 = freeset.Get(ii1); + i2 = freeset.Get(ii2); + i3 = freeset.Get(ii3); + + Vec3d v1, v2, n; + + v1 = freezone.Get(i3) - freezone.Get(i1); + v2 = freezone.Get(i2) - freezone.Get(i1); + n = Cross (v1, v2); + n /= n.Length(); + // (*testout) << "i1,2,3 = " << i1 << ", " << i2 << ", " << i3 << endl; + // (*testout) << "v1 = " << v1 << " v2 = " << v2 << " n = " << n << endl; + ok = 1; + for (ii = 1; ii <= freeset.Size(); ii++) + { + i = freeset.Get(ii); + // (*testout) << "i = " << i << endl; + if (i != i1 && i != i2 && i != i3) + if ( (freezone.Get(i) - freezone.Get(i1)) * n < 0 ) ok = 0; + } + + if (ok) + { + freesetfaces.Append (threeint()); + freesetfaces.Last().i1 = i1; + freesetfaces.Last().i2 = i2; + freesetfaces.Last().i3 = i3; + } + } + } + + for (fs = 1; fs <= freesets.Size(); fs++) + { + freefaceinequ.Append (new DenseMatrix (freefaces.Get(fs)->Size(), 4)); + } + + + { + int minn; + // Array pnearness (noldp); + pnearness.SetSize (noldp); + + for (i = 1; i <= pnearness.Size(); i++) + pnearness.Elem(i) = INT_MAX/10; + + for (j = 1; j <= GetNP(1); j++) + pnearness.Elem(GetPointNr (1, j)) = 0; + + do + { + ok = 1; + + for (i = 1; i <= noldf; i++) + { + minn = INT_MAX/10; + for (j = 1; j <= GetNP(i); j++) + minn = min2 (minn, pnearness.Get(GetPointNr (i, j))); + + for (j = 1; j <= GetNP(i); j++) + if (pnearness.Get(GetPointNr (i, j)) > minn+1) + { + ok = 0; + pnearness.Elem(GetPointNr (i, j)) = minn+1; + } + } + + for (i = 1; i <= edges.Size(); i++) + { + int pi1 = edges.Get(i).i1; + int pi2 = edges.Get(i).i2; + + if (pnearness.Get(pi1) > pnearness.Get(pi2)+1) + { + ok = 0; + pnearness.Elem(pi1) = pnearness.Get(pi2)+1; + } + if (pnearness.Get(pi2) > pnearness.Get(pi1)+1) + { + ok = 0; + pnearness.Elem(pi2) = pnearness.Get(pi1)+1; + } + } + + + for (i = 1; i <= elements.Size(); i++) + if (elements.Get(i).GetNP() == 6) // prism rule + { + for (j = 1; j <= 3; j++) + { + int pi1 = elements.Get(i).PNum(j); + int pi2 = elements.Get(i).PNum(j+3); + + if (pnearness.Get(pi1) > pnearness.Get(pi2)+1) + { + ok = 0; + pnearness.Elem(pi1) = pnearness.Get(pi2)+1; + } + if (pnearness.Get(pi2) > pnearness.Get(pi1)+1) + { + ok = 0; + pnearness.Elem(pi2) = pnearness.Get(pi1)+1; + } + } + } + } + while (!ok); + + maxpnearness = 0; + for (i = 1; i <= pnearness.Size(); i++) + maxpnearness = max2 (maxpnearness, pnearness.Get(i)); + + + fnearness.SetSize (noldf); + + for (i = 1; i <= noldf; i++) + { + fnearness.Elem(i) = 0; + for (j = 1; j <= GetNP(i); j++) + fnearness.Elem(i) += pnearness.Get(GetPointNr (i, j)); + } + + // (*testout) << "rule " << name << ", pnear = " << pnearness << endl; + } + + + //Table of edges: + for (fs = 1; fs <= freesets.Size(); fs++) + { + freeedges.Append (new Array); + + // Array & freeset = *freesets.Get(fs); + Array & freesetedges = *freeedges.Last(); + Array & freesetfaces = *freefaces.Get(fs); + int k,l; + INDEX ind; + + for (k = 1; k <= freesetfaces.Size(); k++) + { + threeint tr = freesetfaces.Get(k); + + for (l = k+1; l <= freesetfaces.Size(); l++) + { + ind = NeighbourTrianglePoint(freesetfaces.Get(k), freesetfaces.Get(l)); + if (!ind) continue; + + INDEX_3 f1(freesetfaces.Get(k).i1, + freesetfaces.Get(k).i2, + freesetfaces.Get(k).i3); + INDEX_3 f2(freesetfaces.Get(l).i1, + freesetfaces.Get(l).i2, + freesetfaces.Get(l).i3); + INDEX_2 ed(0, 0); + for (int f11 = 1; f11 <= 3; f11++) + for (int f12 = 1; f12 <= 3; f12++) + if (f11 != f12) + for (int f21 = 1; f21 <= 3; f21++) + for (int f22 = 1; f22 <= 3; f22++) + if (f1.I(f11) == f2.I(f21) && f1.I(f12) == f2.I(f22)) + { + ed.I(1) = f1.I(f11); + ed.I(2) = f1.I(f12); + } + // (*testout) << "ed = " << ed.I(1) << "-" << ed.I(2) << endl; + // (*testout) << "ind = " << ind << " ed = " << ed << endl; + for (int eli = 1; eli <= GetNOldF(); eli++) + { + if (GetNP(eli) == 4) + { + for (int elr = 1; elr <= 4; elr++) + { + if (GetPointNrMod (eli, elr) == ed.I(1) && + GetPointNrMod (eli, elr+2) == ed.I(2)) + { + /* + (*testout) << "ed is diagonal of rectangle" << endl; + (*testout) << "ed = " << ed.I(1) << "-" << ed.I(2) << endl; + (*testout) << "ind = " << ind << endl; + */ + ind = 0; + } + + } + } + } + + if (ind) + { + /* + (*testout) << "new edge from face " << k + << " = (" << freesetfaces.Get(k).i1 + << ", " << freesetfaces.Get(k).i2 + << ", " << freesetfaces.Get(k).i3 + << "), point " << ind << endl; + */ + freesetedges.Append(twoint(k,ind)); + } + } + } + } + +} + + + + + +void Meshing3 :: LoadRules (const char * filename, const char ** prules) +{ + char buf[256]; + istream * ist; + char *tr1 = NULL; + + if (filename) + { + PrintMessage (3, "rule-filename = ", filename); + ist = new ifstream (filename); + } + else + { + /* connect tetrules to one string */ + PrintMessage (3, "Use internal rules"); + if (!prules) prules = tetrules; + + const char ** hcp = prules; + size_t len = 0; + while (*hcp) + { + len += strlen (*hcp); + hcp++; + } + tr1 = new char[len+1]; + tr1[0] = 0; + hcp = prules; // tetrules; + + + char * tt1 = tr1; + while (*hcp) + { + strcat (tt1, *hcp); + tt1 += strlen (*hcp); + hcp++; + } + + +#ifdef WIN32 + // VC++ 2005 workaround + for(size_t i=0; igood()) + { + cerr << "Rule description file " << filename << " not found" << endl; + delete ist; + exit (1); + } + + while (!ist->eof()) + { + buf[0] = 0; + (*ist) >> buf; + + if (strcmp (buf, "rule") == 0) + { + vnetrule * rule = new vnetrule; + rule -> LoadRule(*ist); + rules.Append (rule); + if (!rule->TestOk()) + { + PrintSysError ("Parser3d: Rule ", rules.Size(), " not ok"); + exit (1); + } + } + else if (strcmp (buf, "tolfak") == 0) + { + (*ist) >> tolfak; + } + } + delete ist; + delete [] tr1; +} +} diff --git a/libsrc/meshing/prism2rls.cpp b/libsrc/meshing/prism2rls.cpp new file mode 100644 index 00000000..7e696554 --- /dev/null +++ b/libsrc/meshing/prism2rls.cpp @@ -0,0 +1,457 @@ +namespace netgen +{ +const char * prismrules2[] = { +"tolfak 0.5\n",\ +"\n",\ +"rule \"prism on quad\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0, -0.86);\n",\ +"(0.5, 1, -0.86);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(1, 5, 2) del;\n",\ +"(4, 3, 6) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(5, 2, 3, 6);\n",\ +"(1, 5, 6, 4);\n",\ +"\n",\ +"elements\n",\ +"(1, 5, 2, 4, 6, 3);\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3, 5);\n",\ +"(1, 3, 4, 6);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ +"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ +"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 4 5 6 7;\n",\ +"\n",\ +"freeset\n",\ +"2 3 4 5 6 8;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"prism on quad, one trig\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0, -0.86);\n",\ +"(0.5, 1, -0.86);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(1, 5, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(5, 2, 3, 6);\n",\ +"(1, 5, 6, 4);\n",\ +"(4, 6, 3);\n",\ +"\n",\ +"elements\n",\ +"(1, 5, 2, 4, 6, 3);\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3, 5);\n",\ +"(1, 3, 4, 6);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ +"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ +"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 4 5 6 7;\n",\ +"\n",\ +"freeset\n",\ +"2 3 4 5 6 8;\n",\ +"\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"prism on 2 quad\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0, -0.86);\n",\ +"(0.5, 1, -0.86);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 5, 6, 3) del;\n",\ +"(1, 5, 2) del;\n",\ +"(4, 3, 6) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 5, 6, 4);\n",\ +"\n",\ +"elements\n",\ +"(1, 5, 2, 4, 6, 3);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 4 5 6 7;\n",\ +"\n",\ +"freeset\n",\ +"2 3 4 6;\n",\ +"\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"prism on 2 quad, one trig\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0, -0.86);\n",\ +"(0.5, 1, -0.86);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 5, 6, 3) del;\n",\ +"(1, 5, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 5, 6, 4);\n",\ +"(4, 6, 3);\n",\ +"\n",\ +"elements\n",\ +"(1, 5, 2, 4, 6, 3);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.3 P1, -0.1 P2, -0.1 P3, 0.3 P4, 0.3 P5, 0.3 P6 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0.25 P1, 0 P2, 0 P3, 0.25 P4, 0.25 P5, 0.25 P6 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 4 5 6 7;\n",\ +"\n",\ +"freeset\n",\ +"2 3 4 6;\n",\ +"\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"prism on 2 quada\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0, -0.86);\n",\ +"(0.5, 1, -0.86);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(5, 1, 4, 6) del;\n",\ +"(1, 5, 2) del;\n",\ +"(4, 3, 6) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(5, 2, 3, 6);\n",\ +"\n",\ +"elements\n",\ +"(1, 5, 2, 4, 6, 3);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ -0.1 P1, 0.3 P2, 0.3 P3, -0.1 P4, 0.3 P5, 0.3 P6 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 0 P1, 0.25 P2, 0.25 P3, 0 P4, 0.25 P5, 0.25 P6 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5 6 7;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 6;\n",\ +"\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"fill prism\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0, -0.86);\n",\ +"(0.5, 1, -0.86);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 5, 6, 3) del;\n",\ +"(5, 1, 4, 6) del;\n",\ +"(1, 5, 2) del;\n",\ +"(4, 3, 6) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 5, 2, 4, 6, 3);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 4 5;\n",\ +"\n",\ +"freeset\n",\ +"2 3 4 6;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"prism on 3 quad, one trig\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0, -0.86);\n",\ +"(0.5, 1, -0.86);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 5, 6, 3) del;\n",\ +"(5, 1, 4, 6) del;\n",\ +"(1, 5, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(4, 6, 3);\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 5, 2, 4, 6, 3);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 4 5;\n",\ +"\n",\ +"freeset\n",\ +"2 3 4 6;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"flat prism\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(0.5, 0.866, 0);\n",\ +"(0, 0, -1);\n",\ +"(1, 0, -1);\n",\ +"(0.5, 0.866, -1);\n",\ +"\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(5, 4, 6) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 4);\n",\ +"(4, 2, 5);\n",\ +"(2, 3, 5);\n",\ +"(5, 3, 6);\n",\ +"(3, 1, 6);\n",\ +"(6, 1, 4);\n",\ +"\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 5, 4, 6);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"endrule\n",\ +"\n",\ +0}; +} diff --git a/libsrc/meshing/pyramid2rls.cpp b/libsrc/meshing/pyramid2rls.cpp new file mode 100644 index 00000000..a97e7f13 --- /dev/null +++ b/libsrc/meshing/pyramid2rls.cpp @@ -0,0 +1,309 @@ +namespace netgen +{ +const char * pyramidrules2[] = { +"tolfak 0.5\n",\ +"\n",\ +"rule \"Pyramid on quad\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.5, -0.5) \n",\ +" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ +" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 5);\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"rule \"small Pyramid on quad\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.5, -0.1 )\n",\ +" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ +" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 5);\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"connect pyramid\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0.5, -0.5);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 5);\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"pyramid with one trig\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0.5, -0.5);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 1, 5) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 };\n",\ +"{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 };\n",\ +"{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P2 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 };\n",\ +"{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 };\n",\ +"{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P2 };\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3, 5);\n",\ +"(1, 3, 4, 5);\n",\ +"\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"freeset\n",\ +"2 3 5 6;\n",\ +"freeset\n",\ +"3 4 5 7;\n",\ +"freeset \n",\ +"1 4 5 8;\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"pyramid with two trig\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0.5, -0.5);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 1, 5) del;\n",\ +"(3, 2, 5) del;\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"pyramid with two trig, left\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0.5, -0.5);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 1, 5) del;\n",\ +"(1, 4, 5) del;\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(3, 4, 5);\n",\ +"(2, 3, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +0}; +} diff --git a/libsrc/meshing/pyramidrls.cpp b/libsrc/meshing/pyramidrls.cpp new file mode 100644 index 00000000..d4e997c1 --- /dev/null +++ b/libsrc/meshing/pyramidrls.cpp @@ -0,0 +1,263 @@ +namespace netgen +{ +const char * pyramidrules[] = { +"tolfak 0.5\n",\ +"\n",\ +"rule \"Pyramid on quad\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.5, -0.5) \n",\ +" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ +" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 5);\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"rule \"small Pyramid on quad\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.5, -0.1 )\n",\ +" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 } \n",\ +" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 } { };\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 5);\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.4 P5, -0.1 P1, -0.1 P2, -0.1 P3, -0.1 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"connect pyramid\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0.5, -0.5);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 5);\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"pyramid with one trig\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0.5, -0.5);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 1, 5) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(2, 3, 5);\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 0.34 P2, 0.34 P3, 0.34 P5, -0.02 P1 };\n",\ +"{ 0.34 P3, 0.34 P4, 0.34 P5, -0.02 P1 };\n",\ +"{ 0.34 P1, 0.34 P4, 0.34 P5, -0.02 P3 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 0.333 P2, 0.333 P3, 0.334 P5, 0 P1 };\n",\ +"{ 0.333 P3, 0.333 P4, 0.334 P5, 0 P1 };\n",\ +"{ 0.333 P1, 0.333 P4, 0.334 P5, 0 P3 };\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3, 5);\n",\ +"(1, 3, 4, 5);\n",\ +"\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"freeset\n",\ +"2 3 5 6;\n",\ +"freeset\n",\ +"3 4 5 7;\n",\ +"freeset \n",\ +"1 4 5 8;\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"pyramid with two trig\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(1, 1, 0);\n",\ +"(0, 1, 0);\n",\ +"(0.5, 0.5, -0.5);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3, 4) del;\n",\ +"(2, 1, 5) del;\n",\ +"(3, 2, 5) del;\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(3, 4, 5);\n",\ +"(4, 1, 5);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +0}; +} diff --git a/libsrc/meshing/quadrls.cpp b/libsrc/meshing/quadrls.cpp new file mode 100644 index 00000000..1c2cd23b --- /dev/null +++ b/libsrc/meshing/quadrls.cpp @@ -0,0 +1,887 @@ +namespace netgen +{ +const char * quadrules[] = { +"rule \"Free Quad (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(1, 1) { 1 X2 } { };\n",\ +"(0, 1) { } { };\n",\ +"\n",\ +"newlines\n",\ +"(3, 2);\n",\ +"(4, 3);\n",\ +"(1, 4);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 1.5) { 1.5 X2 } { };\n",\ +"(-0.5, 1.5) { -0.5 X2 } { };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Free Quad (5)\"\n",\ +"\n",\ +"quality 5\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(1, 1) { 1 X2 } { };\n",\ +"(0, 1) { } { };\n",\ +"\n",\ +"newlines\n",\ +"(3, 2);\n",\ +"(4, 3);\n",\ +"(1, 4);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 1.5) { 1.5 X2 } { };\n",\ +"(-0.5, 1.5) { -0.5 X2 } { };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X2 } { };\n",\ +"(0, 1) { } { };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Quad Right (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0, 1) { } { 1 y3 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 4);\n",\ +"(4, 3);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(-0.5, 1.5) { } { 1.5 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Quad P Right (2)\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0, 1) { -1 X2, 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 4);\n",\ +"(4, 3);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { -1 X2, 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"rule \"Quad P Right (150)\"\n",\ +"\n",\ +"quality 150\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 4)\n;",\ +"(4, 3)\n;",\ +"(3, 2)\n;",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.2, 0.5) { 0.7 X2, 0.5 X3 } { 0.5 Y3 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(-0.5, 1.5) { -2 X2, 1.5 X3 } { 1.5 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"rule \"Quad Right PL (2)\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(1, 4);\n",\ +"(4, 3);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"(-0.2, 0.5) { -0.1 X2, -0.1 X3, 0.6 X4 } { -0.1 Y2, -0.1 Y3, 0.6 Y4 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3);\n",\ +"(1, 3, 4);\n",\ +"(1, 2, 4);\n",\ +"(4, 2, 3);\n",\ +"\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left Quad (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(3, 4);\n",\ +"(4, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left P Quad (2)\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 4);\n",\ +"(4, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X2, 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 0.5) { 0.5 X3 } { 0.5 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left P Quad (150)\"\n",\ +"\n",\ +"quality 150\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(1, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 4);\n",\ +"(4, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 1.5) { 1.5 X2, 1.5 X3 } { 1.5 Y3 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"(-0.2, 0.6) { -0.2 X2, 0.6 X3 } { 0.6 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X2, -1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 0.5) { 0.5 X3 } { 0.5 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left Quad RP (2)\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0, 1);\n",\ +"(1, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(3, 4);\n",\ +"(4, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.2, 0.5) { 0.6 X2, 0.6 X4, -0.1 X3 } { 0.6 Y2, 0.6 Y4, -0.1 Y3 };\n",\ +"(1, 1) { 1 X4 } { 1 Y4 };\n",\ +"(0.5, 1.2) { -0.1 X2, 0.6 X3, 0.6 X4 } { -0.1 Y2, 0.6 Y3, 0.6 Y4 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.5) { 0.5 X2, 0.5 X4 } { 0.5 Y2, 0.5 Y4 };\n",\ +"(1, 1) { 1 X4 } { 1 Y4 };\n",\ +"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ +"(0, 1) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4, 3);\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 4);\n",\ +"(1, 4, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Two left (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 4) del;\n",\ +"(4, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Two Right (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"(3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(1, 4);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Right 120 (1)\"\n",\ +"\n",\ +"quality 1000\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 4);\n",\ +"(4, 3);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 };\n",\ +"(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 };\n",\ +"(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4);\n",\ +"(2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left 120 (1)\"\n",\ +"\n",\ +"quality 1000\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(-0.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(3, 4);\n",\ +"(4, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 };\n",\ +"(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 };\n",\ +"(0, 1.732) { -1 X2, 2 X3 } { 2 Y3 };\n",\ +"(-0.5, 0.866) { 1 X3 } {1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4);\n",\ +"(2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left Right (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"(4, 1) del;\n",\ +"\n",\ +"\n",\ +"newlines\n",\ +"(4, 3);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0.5, 1.5) { -0.25 X2, 0.75 X3, 0.75 X4 } { 0.75 Y3, 0.75 Y4 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0.5, 1) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Fill Quad\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"(3, 4) del;\n",\ +"(4, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { 1 Y2 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Fill Triangle\"\n",\ +"\n",\ +"quality 10\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0.5, 0.86);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"(3, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { 1 Y2 };\n",\ +"(0.5, 0.86) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Right 60 (1)\"\n",\ +"\n",\ +"quality 10\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0) { 0.5, 0, 1.0 };\n",\ +"(0.5, 0.866) { 0.6, 0, 0.8 };\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Vis A Vis (2)\"\n",\ +"\n",\ +"quality 2\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1);\n",\ +"(0, 1);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(1, 4);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.5) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y3, -0.25 Y4 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"(-0.5, 0.5) { -0.25 X2, -0.25 X3, 0.75 X4 } { -0.25 Y3, 0.75 Y4 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.5) { 0.5 X2, 0.5 X3 } { 0.5 Y3 };\n",\ +"(1, 1) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1) { 1 X4 } { 1 Y4 };\n",\ +"(0, 0.5) { 0.5 X4 } { 0.5 Y4 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"orientations\n",\ +"(1, 3, 4);\n",\ +"(2, 3, 4);\n",\ +"(1, 2, 3);\n",\ +"(1, 2, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Triangle Vis A Vis (200)\"\n",\ +"\n",\ +"quality 200\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"2 h Vis A Vis (1)\"\n",\ +"\n",\ +"quality 3000\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1.732);\n",\ +"(0, 1.732);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 5);\n",\ +"(5, 4);\n",\ +"(3, 5);\n",\ +"(5, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { 1 Y2 };\n",\ +"(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 };\n",\ +"(1, 1.732) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1.732) { 1 X4 } { 1 Y4 };\n",\ +"(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 5);\n",\ +"(3, 4, 5);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +0}; +} diff --git a/libsrc/meshing/refine.cpp b/libsrc/meshing/refine.cpp new file mode 100644 index 00000000..aeae9e41 --- /dev/null +++ b/libsrc/meshing/refine.cpp @@ -0,0 +1,757 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + + void Refinement :: Refine (Mesh & mesh) const + { + const_cast (*this).Refine(mesh); + } + + + void Refinement :: Refine (Mesh & mesh) + { + // reduce 2nd order + mesh.ComputeNVertices(); + mesh.SetNP(mesh.GetNV()); + + + INDEX_2_HASHTABLE between(mesh.GetNP() + 5); + + int oldne, oldns, oldnf; + + // refine edges + + Array epgi; + + oldns = mesh.GetNSeg(); + for (SegmentIndex si = 0; si < oldns; si++) + { + const Segment & el = mesh.LineSegment(si); + + INDEX_2 i2 = INDEX_2::Sort(el[0], el[1]); + PointIndex pinew; + EdgePointGeomInfo ngi; + + if (between.Used(i2)) + { + pinew = between.Get(i2); + ngi = epgi[pinew]; + } + else + { + Point<3> pnew; + PointBetween (mesh.Point (el[0]), + mesh.Point (el[1]), 0.5, + el.surfnr1, el.surfnr2, + el.epgeominfo[0], el.epgeominfo[1], + pnew, ngi); + + pinew = mesh.AddPoint (pnew); + between.Set (i2, pinew); + + + if (pinew >= epgi.Size()+PointIndex::BASE) + epgi.SetSize (pinew+1-PointIndex::BASE); + epgi[pinew] = ngi; + } + + Segment ns1 = el; + Segment ns2 = el; + ns1[1] = pinew; + ns1.epgeominfo[1] = ngi; + ns2[0] = pinew; + ns2.epgeominfo[0] = ngi; + + mesh.LineSegment(si) = ns1; + mesh.AddSegment (ns2); + } + + // refine surface elements + Array surfgi (8*mesh.GetNP()); + for (int i = PointIndex::BASE; + i < surfgi.Size()+PointIndex::BASE; i++) + surfgi[i].trignum = -1; + + + oldnf = mesh.GetNSE(); + for (SurfaceElementIndex sei = 0; sei < oldnf; sei++) + { + int j, k; + const Element2d & el = mesh.SurfaceElement(sei); + + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + ArrayMem pnums(6); + ArrayMem pgis(6); + + static int betw[3][3] = + { { 2, 3, 4 }, + { 1, 3, 5 }, + { 1, 2, 6 } }; + + for (j = 1; j <= 3; j++) + { + pnums.Elem(j) = el.PNum(j); + pgis.Elem(j) = el.GeomInfoPi(j); + } + + for (j = 0; j < 3; j++) + { + PointIndex pi1 = pnums.Elem(betw[j][0]); + PointIndex pi2 = pnums.Elem(betw[j][1]); + + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + + Point<3> pb; + PointGeomInfo pgi; + PointBetween (mesh.Point (pi1), + mesh.Point (pi2), 0.5, + mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), + el.GeomInfoPi (betw[j][0]), + el.GeomInfoPi (betw[j][1]), + pb, pgi); + + + pgis.Elem(4+j) = pgi; + if (between.Used(i2)) + pnums.Elem(4+j) = between.Get(i2); + else + { + pnums.Elem(4+j) = mesh.AddPoint (pb); + between.Set (i2, pnums.Get(4+j)); + } + + if (surfgi.Size() < pnums.Elem(4+j)) + surfgi.SetSize (pnums.Elem(4+j)); + surfgi.Elem(pnums.Elem(4+j)) = pgis.Elem(4+j); + } + + + static int reftab[4][3] = + { { 1, 6, 5 }, + { 2, 4, 6 }, + { 3, 5, 4 }, + { 6, 4, 5 } }; + + int ind = el.GetIndex(); + for (j = 0; j < 4; j++) + { + Element2d nel(TRIG); + for (k = 1; k <= 3; k++) + { + nel.PNum(k) = pnums.Get(reftab[j][k-1]); + nel.GeomInfoPi(k) = pgis.Get(reftab[j][k-1]); + } + nel.SetIndex(ind); + + if (j == 0) + mesh.SurfaceElement(sei) = nel; + else + mesh.AddSurfaceElement(nel); + } + break; + } + case QUAD: + case QUAD6: + case QUAD8: + { + ArrayMem pnums(9); + ArrayMem pgis(9); + + static int betw[5][3] = + { { 1, 2, 5 }, + { 2, 3, 6 }, + { 3, 4, 7 }, + { 1, 4, 8 }, + { 5, 7, 9 } }; + + for (j = 1; j <= 4; j++) + { + pnums.Elem(j) = el.PNum(j); + pgis.Elem(j) = el.GeomInfoPi(j); + } + + for (j = 0; j < 5; j++) + { + int pi1 = pnums.Elem(betw[j][0]); + int pi2 = pnums.Elem(betw[j][1]); + + INDEX_2 i2 (pi1, pi2); + i2.Sort(); + + if (between.Used(i2)) + { + pnums.Elem(5+j) = between.Get(i2); + pgis.Elem(5+j) = surfgi.Get(pnums.Elem(4+j)); + } + else + { + Point<3> pb; + PointBetween (mesh.Point (pi1), + mesh.Point (pi2), 0.5, + mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), + el.GeomInfoPi (betw[j][0]), + el.GeomInfoPi (betw[j][1]), + pb, pgis.Elem(5+j)); + + pnums.Elem(5+j) = mesh.AddPoint (pb); + + between.Set (i2, pnums.Get(5+j)); + + if (surfgi.Size() < pnums.Elem(5+j)) + surfgi.SetSize (pnums.Elem(5+j)); + surfgi.Elem(pnums.Elem(5+j)) = pgis.Elem(5+j); + } + } + + static int reftab[4][4] = + { + { 1, 5, 9, 8 }, + { 5, 2, 6, 9 }, + { 8, 9, 7, 4 }, + { 9, 6, 3, 7 } }; + + int ind = el.GetIndex(); + for (j = 0; j < 4; j++) + { + Element2d nel(QUAD); + for (k = 1; k <= 4; k++) + { + nel.PNum(k) = pnums.Get(reftab[j][k-1]); + nel.GeomInfoPi(k) = pgis.Get(reftab[j][k-1]); + } + nel.SetIndex(ind); + + if (j == 0) + mesh.SurfaceElement(sei) = nel; + else + mesh.AddSurfaceElement(nel); + } + break; + } + default: + PrintSysError ("Refine: undefined surface element type ", int(el.GetType())); + } + } + + // refine volume elements + oldne = mesh.GetNE(); + for (ElementIndex ei = 0; ei < oldne; ei++) + { + int j, k; + + const Element & el = mesh.VolumeElement(ei); + switch (el.GetType()) + { + case TET: + case TET10: + { + ArrayMem pnums(10); + static int betw[6][3] = + { { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 4, 10 } }; + + int elrev = el.flags.reverse; + + for (j = 1; j <= 4; j++) + pnums.Elem(j) = el.PNum(j); + if (elrev) + swap (pnums.Elem(3), pnums.Elem(4)); + + for (j = 0; j < 6; j++) + { + INDEX_2 i2; + i2.I1() = pnums.Get(betw[j][0]); + i2.I2() = pnums.Get(betw[j][1]); + i2.Sort(); + + if (between.Used(i2)) + pnums.Elem(5+j) = between.Get(i2); + else + { + pnums.Elem(5+j) = mesh.AddPoint + (Center (mesh.Point(i2.I1()), + mesh.Point(i2.I2()))); + between.Set (i2, pnums.Elem(5+j)); + } + } + + static int reftab[8][4] = + { { 1, 5, 6, 7 }, + { 5, 2, 8, 9 }, + { 6, 8, 3, 10 }, + { 7, 9, 10, 4 }, + { 5, 6, 7, 9 }, + { 5, 6, 9, 8 }, + { 6, 7, 9, 10 }, + { 6, 8, 10, 9 } }; + /* + { { 1, 5, 6, 7 }, + { 5, 2, 8, 9 }, + { 6, 8, 3, 10 }, + { 7, 9, 10, 4 }, + { 5, 6, 7, 9 }, + { 5, 6, 8, 9 }, + { 6, 7, 9, 10 }, + { 6, 8, 9, 10 } }; + */ + static bool reverse[8] = + { + false, false, false, false, false, true, false, true + }; + + int ind = el.GetIndex(); + for (j = 0; j < 8; j++) + { + Element nel; + for (k = 1; k <= 4; k++) + nel.PNum(k) = pnums.Get(reftab[j][k-1]); + nel.SetIndex(ind); + nel.flags.reverse = reverse[j]; + if (elrev) + { + nel.flags.reverse = !nel.flags.reverse; + swap (nel.PNum(3), nel.PNum(4)); + } + + if (j == 0) + mesh.VolumeElement(ei) = nel; + else + mesh.AddVolumeElement (nel); + } + break; + } + case HEX: + { + ArrayMem pnums(27); + static int betw[13][3] = + { { 1, 2, 9 }, + { 3, 4, 10 }, + { 4, 1, 11 }, + { 2, 3, 12 }, + { 5, 6, 13 }, + { 7, 8, 14 }, + { 8, 5, 15 }, + { 6, 7, 16 }, + { 1, 5, 17 }, + { 2, 6, 18 }, + { 3, 7, 19 }, + { 4, 8, 20 }, + { 2, 8, 21 }, + }; + + /* + static int fbetw[12][3] = + { { 1, 3, 22 }, + { 2, 4, 22 }, + { 5, 7, 23 }, + { 6, 8, 23 }, + { 1, 6, 24 }, + { 2, 5, 24 }, + { 2, 7, 25 }, + { 3, 6, 25 }, + { 3, 8, 26 }, + { 4, 7, 26 }, + { 1, 8, 27 }, + { 4, 5, 27 }, + }; + */ + + // udpated by anonymous supporter, donations please to Karo W. + static int fbetw[12][3] = + { { 11, 12, 22 }, + { 9, 10, 22 }, + { 13, 14, 23 }, + { 15, 16, 23 }, + { 9, 13, 24 }, + { 17, 18, 24 }, + { 12, 16, 25 }, + { 18, 19, 25 }, + { 19, 20, 26 }, + { 10, 14, 26 }, + { 11, 15, 27 }, + { 17, 20, 27 }, + }; + + pnums = PointIndex(-1); + + for (j = 1; j <= 8; j++) + pnums.Elem(j) = el.PNum(j); + + + for (j = 0; j < 13; j++) + { + INDEX_2 i2; + i2.I1() = pnums.Get(betw[j][0]); + i2.I2() = pnums.Get(betw[j][1]); + i2.Sort(); + + if (between.Used(i2)) + pnums.Elem(9+j) = between.Get(i2); + else + { + pnums.Elem(9+j) = mesh.AddPoint + (Center (mesh.Point(i2.I1()), + mesh.Point(i2.I2()))); + between.Set (i2, pnums.Elem(9+j)); + } + } + + for (j = 0; j < 6; j++) + { + INDEX_2 i2a, i2b; + i2a.I1() = pnums.Get(fbetw[2*j][0]); + i2a.I2() = pnums.Get(fbetw[2*j][1]); + i2a.Sort(); + i2b.I1() = pnums.Get(fbetw[2*j+1][0]); + i2b.I2() = pnums.Get(fbetw[2*j+1][1]); + i2b.Sort(); + + if (between.Used(i2a)) + pnums.Elem(22+j) = between.Get(i2a); + else if (between.Used(i2b)) + pnums.Elem(22+j) = between.Get(i2b); + else + { + pnums.Elem(22+j) = mesh.AddPoint + (Center (mesh.Point(i2a.I1()), + mesh.Point(i2a.I2()))); + + between.Set (i2a, pnums.Elem(22+j)); + } + } + + static int reftab[8][8] = + { { 1, 9, 22, 11, 17, 24, 21, 27 }, + { 9, 2, 12, 22, 24, 18, 25, 21 }, + { 11, 22, 10, 4, 27, 21, 26, 20}, + { 22, 12, 3, 10, 21, 25, 19, 26}, + { 17, 24, 21, 27, 5, 13, 23, 15}, + { 24, 18, 25, 21, 13, 6, 16, 23}, + { 27, 21, 26, 20, 15, 23, 14, 8}, + { 21, 25, 19, 26, 23, 16, 7, 14} }; + + + int ind = el.GetIndex(); + for (j = 0; j < 8; j++) + { + Element nel(HEX); + for (k = 1; k <= 8; k++) + nel.PNum(k) = pnums.Get(reftab[j][k-1]); + nel.SetIndex(ind); + + if (j == 0) + mesh.VolumeElement(ei) = nel; + else + mesh.AddVolumeElement (nel); + } + break; + } + case PRISM: + { + ArrayMem pnums(18); + static int betw[9][3] = + { { 3, 1, 7 }, + { 1, 2, 8 }, + { 3, 2, 9 }, + { 6, 4, 10 }, + { 4, 5, 11 }, + { 6, 5, 12 }, + { 1, 4, 13 }, + { 3, 6, 14 }, + { 2, 5, 15 }, + }; + +// he: 15.jul 08, old version is wrong +// produces double points ad quad faces and inconsistent mesh +// static int fbetw[6][3] = +// { { 1, 6, 16 }, +// { 3, 4, 16 }, +// { 1, 5, 17 }, +// { 2, 4, 17 }, +// { 2, 6, 18 }, +// { 3, 5, 18 }, +// }; + + static int fbetw[6][3] = + { { 7, 10, 16 }, + { 14, 13, 16 }, + { 11, 8, 17 }, + { 13, 15, 17 }, + { 12, 9, 18 }, + { 14, 15, 18 }, + }; + + //int elrev = el.flags.reverse; + pnums = PointIndex(-1); + + for (j = 1; j <= 6; j++) + pnums.Elem(j) = el.PNum(j); + // if (elrev) + // swap (pnums.Elem(3), pnums.Elem(4)); + + for (j = 0; j < 9; j++) + { + INDEX_2 i2; + i2.I1() = pnums.Get(betw[j][0]); + i2.I2() = pnums.Get(betw[j][1]); + i2.Sort(); + + if (between.Used(i2)) + pnums.Elem(7+j) = between.Get(i2); + else + { + pnums.Elem(7+j) = mesh.AddPoint + (Center (mesh.Point(i2.I1()), + mesh.Point(i2.I2()))); + between.Set (i2, pnums.Elem(7+j)); + } + } + + for (j = 0; j < 3; j++) + { + INDEX_2 i2a, i2b; + i2a.I1() = pnums.Get(fbetw[2*j][0]); + i2a.I2() = pnums.Get(fbetw[2*j][1]); + i2a.Sort(); + i2b.I1() = pnums.Get(fbetw[2*j+1][0]); + i2b.I2() = pnums.Get(fbetw[2*j+1][1]); + i2b.Sort(); + + if (between.Used(i2a)) + pnums.Elem(16+j) = between.Get(i2a); + else if (between.Used(i2b)) + pnums.Elem(16+j) = between.Get(i2b); + else + { + pnums.Elem(16+j) = mesh.AddPoint + (Center (mesh.Point(i2a.I1()), + mesh.Point(i2a.I2()))); + + between.Set (i2a, pnums.Elem(16+j)); + } + } + + + static int reftab[8][6] = + { { 1, 8, 7, 13, 17, 16 }, + { 7, 8, 9, 16, 17, 18 }, + { 7, 9, 3, 16, 18, 14 }, + { 8, 2, 9, 17, 15, 18 }, + { 13, 17, 16, 4, 11, 10 }, + { 16, 17, 18, 10, 11, 12 }, + { 16, 18, 14, 10, 12, 6 }, + { 17, 15, 18, 11, 5, 12 } }; + + + int ind = el.GetIndex(); + for (j = 0; j < 8; j++) + { + Element nel(PRISM); + for (k = 1; k <= 6; k++) + nel.PNum(k) = pnums.Get(reftab[j][k-1]); + nel.SetIndex(ind); + + + //nel.flags.reverse = reverse[j]; + //if (elrev) + // { + //nel.flags.reverse = 1 - nel.flags.reverse; + //swap (nel.PNum(3), nel.PNum(4)); + + + if (j == 0) + mesh.VolumeElement(ei) = nel; + else + mesh.AddVolumeElement (nel); + } + break; + } + default: + PrintSysError ("Refine: undefined volume element type ", int(el.GetType())); + } + } + + + // update identification tables + for (int i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) + { + Array identmap; + mesh.GetIdentifications().GetMap (i, identmap); + + for (int j = 1; j <= between.GetNBags(); j++) + for (int k = 1; k <= between.GetBagSize(j); k++) + { + INDEX_2 i2; + PointIndex newpi; + between.GetData (j, k, i2, newpi); + INDEX_2 oi2(identmap.Get(i2.I1()), + identmap.Get(i2.I2())); + oi2.Sort(); + if (between.Used (oi2)) + { + PointIndex onewpi = between.Get(oi2); + mesh.GetIdentifications().Add (newpi, onewpi, i); + } + } + + } + + mesh.ComputeNVertices(); + mesh.RebuildSurfaceElementLists(); + return; + + int cnttrials = 10; + int wrongels = 0; + for (int i = 1; i <= mesh.GetNE(); i++) + if (mesh.VolumeElement(i).Volume(mesh.Points()) < 0) + { + wrongels++; + mesh.VolumeElement(i).flags.badel = 1; + } + else + mesh.VolumeElement(i).flags.badel = 0; + + if (wrongels) + { + cout << "WARNING: " << wrongels << " with wrong orientation found" << endl; + + int np = mesh.GetNP(); + Array > should(np); + Array > can(np); + for (int i = 1; i <= np; i++) + { + should.Elem(i) = can.Elem(i) = mesh.Point(i); + } + for (int i = 1; i <= between.GetNBags(); i++) + for (int j = 1; j <= between.GetBagSize(i); j++) + { + INDEX_2 parent; + PointIndex child; + between.GetData (i, j, parent, child); + can.Elem(child) = Center (can.Elem(parent.I1()), + can.Elem(parent.I2())); + } + + BitArray boundp(np); + boundp.Clear(); + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + for (int j = 1; j <= sel.GetNP(); j++) + boundp.Set(sel.PNum(j)); + } + + + double lam = 0.5; + + while (lam < 0.9 && cnttrials > 0) + { + lam = 2; + do + { + lam *= 0.5; + cnttrials--; + + cout << "lam = " << lam << endl; + + for (int i = 1; i <= np; i++) + if (boundp.Test(i)) + { + for (int j = 0; j < 3; j++) + mesh.Point(i)(j) = + lam * should.Get(i)(j) + + (1-lam) * can.Get(i)(j); + } + else + mesh.Point(i) = can.Get(i); + + + BitArray free (mesh.GetNP()), fhelp(mesh.GetNP()); + free.Clear(); + for (int i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement(i); + if (el.Volume(mesh.Points()) < 0) + for (int j = 1; j <= el.GetNP(); j++) + free.Set (el.PNum(j)); + } + for (int k = 1; k <= 3; k++) + { + fhelp.Clear(); + for (int i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement(i); + int freeel = 0; + for (int j = 1; j <= el.GetNP(); j++) + if (free.Test(el.PNum(j))) + freeel = 1; + if (freeel) + for (int j = 1; j <= el.GetNP(); j++) + fhelp.Set (el.PNum(j)); + } + free.Or (fhelp); + } + + (*testout) << "smooth points: " << endl; + for (int i = 1; i <= free.Size(); i++) + if (free.Test(i)) + (*testout) << "p " << i << endl; + + (*testout) << "surf points: " << endl; + for (int i = 1; i <= mesh.GetNSE(); i++) + for (int j = 1; j <= 3; j++) + (*testout) << mesh.SurfaceElement(i).PNum(j) << endl; + + + + mesh.CalcSurfacesOfNode(); + free.Invert(); + mesh.FixPoints (free); + MeshingParameters dummymp; + mesh.ImproveMesh (dummymp, OPT_REST); + + + wrongels = 0; + for (int i = 1; i <= mesh.GetNE(); i++) + { + if (mesh.VolumeElement(i).Volume(mesh.Points()) < 0) + { + wrongels++; + mesh.VolumeElement(i).flags.badel = 1; + (*testout) << "wrong el: "; + for (int j = 1; j <= 4; j++) + (*testout) << mesh.VolumeElement(i).PNum(j) << " "; + (*testout) << endl; + } + else + mesh.VolumeElement(i).flags.badel = 0; + } + cout << "wrongels = " << wrongels << endl; + } + while (wrongels && cnttrials > 0); + + for (int i = 1; i <= np; i++) + can.Elem(i) = mesh.Point(i); + } + } + + if (cnttrials <= 0) + { + cerr << "ERROR: Sorry, reverted elements" << endl; + } + + mesh.ComputeNVertices(); + } +} diff --git a/libsrc/meshing/ruler2.cpp b/libsrc/meshing/ruler2.cpp new file mode 100644 index 00000000..e705dde7 --- /dev/null +++ b/libsrc/meshing/ruler2.cpp @@ -0,0 +1,719 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + + + static double CalcElementBadness (const Array & points, + const Element2d & elem) + { + // badness = sqrt(3) /36 * circumference^2 / area - 1 + + // h / li + li / h - 2 + + Vec2d v12, v13, v23; + double l12, l13, l23, cir, area; + static const double c = sqrt(3.0) / 36; + + v12 = points.Get(elem.PNum(2)) - points.Get(elem.PNum(1)); + v13 = points.Get(elem.PNum(3)) - points.Get(elem.PNum(1)); + v23 = points.Get(elem.PNum(3)) - points.Get(elem.PNum(2)); + + l12 = v12.Length(); + l13 = v13.Length(); + l23 = v23.Length(); + + cir = l12 + l13 + l23; + area = 0.5 * (v12.X() * v13.Y() - v12.Y() * v13.X()); + if (area < 1e-6) + { + return 1e8; + } + + if (testmode) + { + (*testout) << "l = " << l12 << " + " << l13 << " + " << l23 << " = " + << cir << ", area = " << area << endl; + (*testout) << "shapeerr = " << 10 * (c * cir * cir / area - 1) << endl + << "sizeerr = " << 1/l12 + l12 + 1/l13 + l13 + 1/l23 + l23 - 6 + << endl; + } + + return 10 * (c * cir * cir / area - 1) + + 1/l12 + l12 + 1/l13 + l13 + 1/l23 + l23 - 6; + } + + + + int Meshing2 ::ApplyRules (Array & lpoints, + Array & legalpoints, + int maxlegalpoint, + Array & llines1, + int maxlegalline, + Array & elements, + Array & dellines, int tolerance, + const MeshingParameters & mp) + { + static int timer = NgProfiler::CreateTimer ("meshing2::ApplyRules"); + NgProfiler::RegionTimer reg (timer); + + + + double maxerr = 0.5 + 0.3 * tolerance; + double minelerr = 2 + 0.5 * tolerance * tolerance; + + int noldlp = lpoints.Size(); + int noldll = llines1.Size(); + + + ArrayMem pused(maxlegalpoint), lused(maxlegalline); + ArrayMem pnearness(noldlp), lnearness(llines1.Size()); + + ArrayMem pmap, pfixed, lmap; + + ArrayMem tempnewpoints; + ArrayMem tempnewlines; + ArrayMem tempdellines; + ArrayMem tempelements; + + + elements.SetSize (0); + dellines.SetSize (0); + + testmode = debugparam.debugoutput; + +#ifdef LOCDEBUG + int loctestmode = testmode; + + if (loctestmode) + { + (*testout) << endl << endl << "Check new environment" << endl; + (*testout) << "tolerance = " << tolerance << endl; + for (int i = 1; i <= lpoints.Size(); i++) + (*testout) << "P" << i << " = " << lpoints.Get(i) << endl; + (*testout) << endl; + for (int i = 1; i <= llines1.Size(); i++) + (*testout) << "(" << llines1.Get(i).I1() << "-" << llines1.Get(i).I2() << ")" << endl; + } +#endif + + // check every rule + + int found = 0; // rule number + + pnearness = 1000; + + for (int j = 0; j < 2; j++) + pnearness.Set(llines1[0][j], 0); + + + + enum { MAX_NEARNESS = 3 }; + + for (int cnt = 0; cnt < MAX_NEARNESS; cnt++) + { + bool ok = true; + for (int i = 0; i < maxlegalline; i++) + { + const INDEX_2 & hline = llines1[i]; + + int minn = min2 (pnearness.Get(hline[0]), pnearness.Get(hline[1])); + + for (int j = 0; j < 2; j++) + if (pnearness.Get(hline[j]) > minn+1) + { + ok = false; + pnearness.Set(hline[j], minn+1); + } + } + if (!ok) break; + } + + + for (int i = 0; i < maxlegalline; i++) + lnearness[i] = pnearness.Get(llines1[i][0]) + pnearness.Get(llines1[i][1]); + + + // resort lines after lnearness + Array llines(llines1.Size()); + Array sortlines(llines1.Size()); + int lnearness_class[MAX_NEARNESS]; + + for (int j = 0; j < MAX_NEARNESS; j++) + lnearness_class[j] = 0; + for (int i = 0; i < maxlegalline; i++) + if (lnearness[i] < MAX_NEARNESS) + lnearness_class[lnearness[i]]++; + + int cumm = 0; + for (int j = 0; j < MAX_NEARNESS; j++) + { + int hcnt = lnearness_class[j]; + lnearness_class[j] = cumm; + cumm += hcnt; + } + + for (int i = 0; i < maxlegalline; i++) + if (lnearness[i] < MAX_NEARNESS) + { + llines[lnearness_class[lnearness[i]]] = llines1[i]; + sortlines[lnearness_class[lnearness[i]]] = i+1; + lnearness_class[lnearness[i]]++; + } + else + { + llines[cumm] = llines1[i]; + sortlines[cumm] = i+1; + cumm++; + } + + for (int i = maxlegalline; i < llines1.Size(); i++) + { + llines[cumm] = llines1[i]; + sortlines[cumm] = i+1; + cumm++; + } + + for (int i = 0; i < maxlegalline; i++) + lnearness[i] = pnearness.Get(llines[i][0]) + pnearness.Get(llines[i][1]); + + + + + static bool firsttime = true; + static int timers[100]; + static int timers2[100]; + static int timers3[100]; + if (firsttime) + { + for (int ri = 0; ri < rules.Size(); ri++) + timers[ri] = NgProfiler::CreateTimer (string("netrule ")+rules[ri]->Name()); + for (int ri = 0; ri < rules.Size(); ri++) + timers2[ri] = NgProfiler::CreateTimer (string("netrule,mapped ")+rules[ri]->Name()); + for (int ri = 0; ri < rules.Size(); ri++) + timers3[ri] = NgProfiler::CreateTimer (string("netrule,lines mapped ")+rules[ri]->Name()); + firsttime = false; + } + + lused = 0; + pused = 0; + + + static int timer1 = NgProfiler::CreateTimer ("meshing2::ApplyRules 1"); + NgProfiler::RegionTimer reg1 (timer1); + + + for (int ri = 1; ri <= rules.Size(); ri++) + { + // NgProfiler::RegionTimer reg(timers[ri-1]); + netrule * rule = rules.Get(ri); + +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "Rule " << rule->Name() << endl; +#endif + + if (rule->GetQuality() > tolerance) continue; + + pmap.SetSize (rule->GetNP()); + lmap.SetSize (rule->GetNL()); + + pmap = 0; + lmap = 0; + + lused[0] = 1; + lmap[0] = 1; + + for (int j = 0; j < 2; j++) + { + pmap.Elem(rule->GetLine(1)[j]) = llines[0][j]; + pused.Elem(llines[0][j])++; + } + + + + int nlok = 2; + + + bool ok = false; + + while (nlok >= 2) + { + + if (nlok <= rule->GetNOldL()) + + { + ok = 0; + + int maxline = (rule->GetLNearness(nlok) < MAX_NEARNESS) ? lnearness_class[rule->GetLNearness(nlok)] : maxlegalline; + // int maxline = maxlegalline; + + while (!ok && lmap.Get(nlok) < maxline) + { + lmap.Elem(nlok)++; + int locli = lmap.Get(nlok); + + if (lnearness.Get(locli) > rule->GetLNearness (nlok) ) continue; + if (lused.Get(locli)) continue; + + + ok = 1; + + INDEX_2 loclin = llines.Get(locli); + Vec2d linevec = lpoints.Get(loclin.I2()) - lpoints.Get(loclin.I1()); + + if (rule->CalcLineError (nlok, linevec) > maxerr) + { + ok = 0; +#ifdef LOCDEBUG + if(loctestmode) + (*testout) << "not ok pos1" << endl; +#endif + continue; + } + + for (int j = 0; j < 2; j++) + { + int refpi = rule->GetLine(nlok)[j]; + + if (pmap.Get(refpi) != 0) + { + if (pmap.Get(refpi) != loclin[j]) + { + ok = 0; +#ifdef LOCDEBUG + if(loctestmode) + (*testout) << "not ok pos2" << endl; +#endif + break; + } + } + else + { + if (rule->CalcPointDist (refpi, lpoints.Get(loclin[j])) > maxerr + || !legalpoints.Get(loclin[j]) + || pused.Get(loclin[j])) + { + ok = 0; +#ifdef LOCDEBUG + if(loctestmode) + { + (*testout) << "nok pos3" << endl; + //if(rule->CalcPointDist (refpi, lpoints.Get(loclin[j])) > maxerr) + //(*testout) << "r1" << endl; + //if(!legalpoints.Get(loclin[j])) + //(*testout) << "r2 legalpoints " << legalpoints << " loclin " << loclin << " j " << j << endl; + //if(pused.Get(loclin[j])) + //(*testout) << "r3" << endl; + } +#endif + break; + } + } + } + } + + if (ok) + { + int locli = lmap.Get(nlok); + INDEX_2 loclin = llines.Get(locli); + + lused.Elem (locli) = 1; + for (int j = 0; j < 2; j++) + { + pmap.Set(rule->GetLine (nlok)[j], loclin[j]); + pused.Elem(loclin[j])++; + } + + nlok++; + } + else + { + lmap.Elem(nlok) = 0; + nlok--; + + lused.Elem (lmap.Get(nlok)) = 0; + for (int j = 0; j < 2; j++) + { + pused.Elem(llines.Get(lmap.Get(nlok))[j]) --; + if (! pused.Get (llines.Get (lmap.Get (nlok))[j])) + pmap.Set (rule->GetLine (nlok)[j], 0); + } + } + } + + else + + { + // NgProfiler::RegionTimer reg(timers3[ri-1]); + + // all lines are mapped !! + + // map also all points: + + int npok = 1; + int incnpok = 1; + + pfixed.SetSize (pmap.Size()); + for (int i = 0; i < pmap.Size(); i++) + pfixed[i] = (pmap[i] >= 1); + + while (npok >= 1) + { + + if (npok <= rule->GetNOldP()) + + { + if (pfixed.Get(npok)) + + { + if (incnpok) + npok++; + else + npok--; + } + + else + + { + ok = 0; + + if (pmap.Get(npok)) + pused.Elem(pmap.Get(npok))--; + + while (!ok && pmap.Get(npok) < maxlegalpoint) + { + ok = 1; + + pmap.Elem(npok)++; + + if (pused.Get(pmap.Get(npok))) + { + ok = 0; + } + else + { + if (rule->CalcPointDist (npok, lpoints.Get(pmap.Get(npok))) > maxerr + || !legalpoints.Get(pmap.Get(npok))) + + ok = 0; + } + } + + if (ok) + { + pused.Elem(pmap.Get(npok))++; + npok++; + incnpok = 1; + } + + else + + { + pmap.Elem(npok) = 0; + npok--; + incnpok = 0; + } + } + } + + else + + { + // NgProfiler::RegionTimer reg(timers2[ri-1]); + + npok = rule->GetNOldP(); + incnpok = 0; + + if (ok) + foundmap.Elem(ri)++; + +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "lines and points mapped" << endl; +#endif + + ok = 1; + + // check orientations + + for (int i = 1; i <= rule->GetNOrientations(); i++) + { + if (CW (lpoints.Get(pmap.Get(rule->GetOrientation(i).i1)), + lpoints.Get(pmap.Get(rule->GetOrientation(i).i2)), + lpoints.Get(pmap.Get(rule->GetOrientation(i).i3))) ) + { + ok = 0; +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "Orientation " << i << " not ok" << endl; +#endif + break; + } + } + + + if (!ok) continue; + + Vector oldu (2 * rule->GetNOldP()); + + for (int i = 1; i <= rule->GetNOldP(); i++) + { + Vec2d ui(rule->GetPoint(i), lpoints.Get(pmap.Get(i))); + oldu (2*i-2) = ui.X(); + oldu (2*i-1) = ui.Y(); + } + + rule -> SetFreeZoneTransformation (oldu, tolerance); + + + if (!ok) continue; + if (!rule->ConvexFreeZone()) + { + ok = 0; +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "freezone not convex" << endl; +#endif + /* + static int cnt = 0; + cnt++; + if (cnt % 100 == 0) + { + cout << "freezone not convex, cnt = " << cnt << "; rule = " << rule->Name() << endl; + (*testout) << "freezone not convex, cnt = " << cnt << "; rule = " << rule->Name() << endl; + (*testout) << "tol = " << tolerance << endl; + (*testout) << "maxerr = " << maxerr << "; minerr = " << minelerr << endl; + (*testout) << "freezone = " << rule->GetTransFreeZone() << endl; + } + */ + } + + // check freezone: + if (!ok) continue; + for (int i = 1; i <= maxlegalpoint && ok; i++) + { + if ( !pused.Get(i) && + rule->IsInFreeZone (lpoints.Get(i)) ) + { + ok = 0; +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "Point " << i << " in freezone" << endl; +#endif + break; + } + } + + if (!ok) continue; + for (int i = maxlegalpoint+1; i <= lpoints.Size(); i++) + { + if ( rule->IsInFreeZone (lpoints.Get(i)) ) + { + ok = 0; +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "Point " << i << " in freezone" << endl; +#endif + break; + } + } + + + if (!ok) continue; + for (int i = 1; i <= maxlegalline; i++) + { + if (!lused.Get(i) && + rule->IsLineInFreeZone (lpoints.Get(llines.Get(i).I1()), + lpoints.Get(llines.Get(i).I2()))) + { + ok = 0; +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "line " << llines.Get(i).I1() << "-" + << llines.Get(i).I2() << " in freezone" << endl; +#endif + break; + } + } + + if (!ok) continue; + + for (int i = maxlegalline+1; i <= llines.Size(); i++) + { + if (rule->IsLineInFreeZone (lpoints.Get(llines.Get(i).I1()), + lpoints.Get(llines.Get(i).I2()))) + { + ok = 0; +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "line " << llines.Get(i).I1() << "-" + << llines.Get(i).I2() << " in freezone" << endl; +#endif + break; + } + } + + + /* + // check orientations + + for (i = 1; i <= rule->GetNOrientations() && ok; i++) + { + if (CW (lpoints.Get(pmap.Get(rule->GetOrientation(i).i1)), + lpoints.Get(pmap.Get(rule->GetOrientation(i).i2)), + lpoints.Get(pmap.Get(rule->GetOrientation(i).i3))) ) + { + ok = 0; + if (loctestmode) + (*testout) << "Orientation " << i << " not ok" << endl; + } + } + */ + + + if (!ok) continue; + +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "rule ok" << endl; +#endif + + // Setze neue Punkte: + if (rule->GetNOldP() < rule->GetNP()) + { + Vector newu(rule->GetOldUToNewU().Height()); + rule->GetOldUToNewU().Mult (oldu, newu); + + int oldnp = rule->GetNOldP(); + for (int i = oldnp + 1; i <= rule->GetNP(); i++) + { + Point2d np = rule->GetPoint(i); + np.X() += newu (2 * (i-oldnp) - 2); + np.Y() += newu (2 * (i-oldnp) - 1); + + pmap.Elem(i) = lpoints.Append (np); + } + } + + // Setze neue Linien: + + for (int i = rule->GetNOldL() + 1; i <= rule->GetNL(); i++) + { + llines.Append (INDEX_2 (pmap.Get(rule->GetLine (i)[0]), + pmap.Get(rule->GetLine (i)[1]))); + } + + + // delete old lines: + for (int i = 1; i <= rule->GetNDelL(); i++) + dellines.Append (sortlines.Elem (lmap.Get(rule->GetDelLine(i)))); + // dellines.Append (lmap.Get(rule->GetDelLine(i)))); + + // dellines.Append (lmap.Elem(rule->GetDelLines())); + // lmap[rule->GetDelLines()]; + + + // insert new elements: + + for (int i = 1; i <= rule->GetNE(); i++) + { + elements.Append (rule->GetElement(i)); + for (int j = 1; j <= elements.Get(i).GetNP(); j++) + elements.Elem(i).PNum(j) = pmap.Get(elements.Get(i).PNum(j)); + } + + + double elerr = 0; + for (int i = 1; i <= elements.Size(); i++) + { + double hf; + if (!mp.quad) + hf = CalcElementBadness (lpoints, elements.Get(i)); + else + hf = elements.Get(i).CalcJacobianBadness (lpoints) * 5; +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "r " << rule->Name() << "bad = " << hf << endl; +#endif + if (hf > elerr) elerr = hf; + } + +#ifdef LOCDEBUG + if (loctestmode) + (*testout) << "error = " << elerr; +#endif + + canuse.Elem(ri) ++; + + if (elerr < 0.99*minelerr) + { +#ifdef LOCDEBUG + if (loctestmode) + { + (*testout) << "rule = " << rule->Name() << endl; + (*testout) << "class = " << tolerance << endl; + (*testout) << "lpoints: " << endl; + for (int i = 1; i <= lpoints.Size(); i++) + (*testout) << lpoints.Get(i) << endl; + (*testout) << "llines: " << endl; + for (int i = 1; i <= llines.Size(); i++) + (*testout) << llines.Get(i).I1() << " " << llines.Get(i).I2() << endl; + + (*testout) << "Freezone: "; + for (int i = 1; i <= rule -> GetTransFreeZone().Size(); i++) + (*testout) << rule->GetTransFreeZone().Get(i) << endl; + } +#endif + + minelerr = elerr; + found = ri; + + tempnewpoints = lpoints.Range (noldlp, lpoints.Size()); + tempnewlines = llines.Range (noldll, llines.Size()); + tempdellines = dellines; + tempelements = elements; + } + + lpoints.SetSize (noldlp); + llines.SetSize (noldll); + dellines.SetSize (0); + elements.SetSize (0); + ok = 0; + } + } + + nlok = rule->GetNOldL(); + + lused.Set (lmap.Get(nlok), 0); + + for (int j = 1; j <= 2; j++) + { + int refpi = rule->GetPointNr (nlok, j); + pused.Elem(pmap.Get(refpi))--; + + if (pused.Get(pmap.Get(refpi)) == 0) + pmap.Set(refpi, 0); + } + } + } + } + + + if (found) + { + lpoints.Append (tempnewpoints); + llines1.Append (tempnewlines); + dellines.Append (tempdellines); + elements.Append (tempelements); + } + + + return found; + } + + + + + +} diff --git a/libsrc/meshing/ruler2.hpp b/libsrc/meshing/ruler2.hpp new file mode 100644 index 00000000..afbe6b98 --- /dev/null +++ b/libsrc/meshing/ruler2.hpp @@ -0,0 +1,169 @@ +#ifndef FILE_NETRULE +#define FILE_NETRULE + +/// +class netrule +{ +private: + /// + typedef struct tf + { float f1, f2, f3; } threefloat; + + class threeint + { + public: int i1, i2, i3; + threeint() { } + threeint(int ai1, int ai2, int ai3) + { i1 = ai1; i2 = ai2; i3 = ai3; } + }; + + + /// + int quality; + /// + char * name; + /// + Array points; + /// + Array lines; + /// + Array freezone, freezonelimit; + /// + Array*> freezone_i; + /// + Array transfreezone; + + /// + Array dellines; + /// + Array elements; + /// + Array tolerances, linetolerances; + /// + Array orientations; + /// + DenseMatrix oldutonewu, oldutofreearea, oldutofreearealimit; + /// + Array oldutofreearea_i; + /// + MatrixFixWidth<3> freesetinequ; + + /// + Array linevecs; + + /// + int noldp, noldl; + /// + float fzminx, fzmaxx, fzminy, fzmaxy; + + /// topological distance of line to base element + Array lnearness; + +public: + + /// + netrule (); + /// + ~netrule(); + + /// + int GetNP () const { return points.Size(); } + /// + int GetNL () const { return lines.Size(); } + /// + int GetNE () const { return elements.Size(); } + /// + int GetNOldP () const { return noldp; } + /// + int GetNOldL () const { return noldl; } + /// + int GetNDelL () const { return dellines.Size(); } + /// + int GetNOrientations () const { return orientations.Size(); } + /// + int GetQuality () const { return quality; } + /// + int GetLNearness (int li) const { return lnearness.Get(li); } + + /// + const Point2d & GetPoint (int i) const { return points.Get(i); } + /// + const INDEX_2 & GetLine (int i) const { return lines.Get(i); } + /// + const Element2d & GetElement (int i) const { return elements.Get(i); } + /// + const threeint & GetOrientation (int i) const { return orientations.Get(i); } + /// + int GetDelLine (int i) const { return dellines.Get(i); } + /// + const Array & GetDelLines() const { return dellines; } + /// + void GetFreeZone (Array & afreearea); + /// + + double CalcPointDist (int pi, const Point2d & p) const + { + double dx = p.X() - points.Get(pi).X(); + double dy = p.Y() - points.Get(pi).Y(); + const threefloat * tfp = &tolerances.Get(pi); + return tfp->f1 * dx * dx + tfp->f2 * dx * dy + tfp->f3 * dy * dy; + } + + /// + float CalcLineError (int li, const Vec2d & v) const; + + /// + void SetFreeZoneTransformation (const Vector & u, int tolclass); + + /// + bool IsInFreeZone (const Point2d & p) const + { + if (p.X() < fzminx || p.X() > fzmaxx || + p.Y() < fzminy || p.Y() > fzmaxy) return 0; + + for (int i = 0; i < transfreezone.Size(); i++) + { + if (freesetinequ(i, 0) * p.X() + + freesetinequ(i, 1) * p.Y() + + freesetinequ(i, 2) > 0) return 0; + } + return 1; + } + + /// + int IsLineInFreeZone (const Point2d & p1, const Point2d & p2) const + { + if ( (p1.X() > fzmaxx && p2.X() > fzmaxx) || + (p1.X() < fzminx && p2.X() < fzminx) || + (p1.Y() > fzmaxy && p2.Y() > fzmaxy) || + (p1.Y() < fzminy && p2.Y() < fzminy) ) return 0; + return IsLineInFreeZone2 (p1, p2); + } + /// + int IsLineInFreeZone2 (const Point2d & p1, const Point2d & p2) const; + /// + int ConvexFreeZone () const; + /// + const Array & GetTransFreeZone () { return transfreezone; } + + /// + int GetPointNr (int ln, int endp) const { return lines.Get(ln).I(endp); } + + /// + const DenseMatrix & GetOldUToNewU () const { return oldutonewu; } + /// + const DenseMatrix & GetOldUToFreeArea () const { return oldutofreearea; } + /// + const char * Name () const { return name; } + + /// + void LoadRule (istream & ist); +}; + + + +/** Draws 2D rules. + Visual testing of 2D meshing rules */ +extern void DrawRules (); +#endif + diff --git a/libsrc/meshing/ruler3.cpp b/libsrc/meshing/ruler3.cpp new file mode 100644 index 00000000..3b6f7a91 --- /dev/null +++ b/libsrc/meshing/ruler3.cpp @@ -0,0 +1,1136 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ +extern double minother; +extern double minwithoutother; + + +static double CalcElementBadness (const Array & points, + const Element & elem) +{ + double vol, l, l4, l5, l6; + if (elem.GetNP() != 4) + { + if (elem.GetNP() == 5) + { + double z = points.Get(elem.PNum(5)).Z(); + if (z > -1e-8) return 1e8; + return (-1 / z) - z; // - 2; + } + return 0; + } + + Vec3d v1 = points.Get(elem.PNum(2)) - points.Get(elem.PNum(1)); + Vec3d v2 = points.Get(elem.PNum(3)) - points.Get(elem.PNum(1)); + Vec3d v3 = points.Get(elem.PNum(4)) - points.Get(elem.PNum(1)); + + vol = - (Cross (v1, v2) * v3); + l4 = Dist (points.Get(elem.PNum(2)), points.Get(elem.PNum(3))); + l5 = Dist (points.Get(elem.PNum(2)), points.Get(elem.PNum(4))); + l6 = Dist (points.Get(elem.PNum(3)), points.Get(elem.PNum(4))); + + l = v1.Length() + v2.Length() + v3.Length() + l4 + l5 + l6; + + // testout << "vol = " << vol << " l = " << l << endl; + if (vol < 1e-8) return 1e10; + // (*testout) << "l^3/vol = " << (l*l*l / vol) << endl; + + double err = pow (l*l*l/vol, 1.0/3.0) / 12; + return err; +} + + + + + + +int Meshing3 :: ApplyRules +( + Array & lpoints, // in: local points, out: old+new local points + Array & allowpoint, // in: 2 .. it is allowed to use pointi, 1..will be allowed later, 0..no means + Array & lfaces, // in: local faces, out: old+new local faces + INDEX lfacesplit, // for local faces in outer radius + INDEX_2_HASHTABLE & connectedpairs, // connected pairs for prism-meshing + Array & elements, // out: new elements + Array & delfaces, // out: face indices of faces to delete + int tolerance, // quality class: 1 best + double sloppy, // quality strength + int rotind1, // how to rotate base element + float & retminerr // element error + ) + +{ + NgProfiler::RegionTimer regtot(97); + + int i, j, k, ri, nfok, npok, incnpok, refpi, locpi, locfi, locfr; + float hf, err, minerr, teterr, minteterr; + char ok, found, hc; + vnetrule * rule; + Vector oldu, newu, newu1, newu2, allp; + Vec3d ui; + Point3d np; + int oldnp, noldlp, noldlf; + const MiniElement2d * locface = NULL; + int loktestmode; + + + Array pused; // point is already mapped + Array fused; // face is already mapped + Array pmap; // map of reference point to local point + Array pfixed; // point mapped by face-map + Array fmapi; // face in reference is mapped to face nr ... + Array fmapr; // face in reference is rotated to map + Array transfreezone; // transformed free-zone + INDEX_2_CLOSED_HASHTABLE ledges(100); // edges in local environment + + Array tempnewpoints; + Array tempnewfaces; + Array tempdelfaces; + Array tempelements; + Array triboxes; // bounding boxes of local faces + + Array pnearness; + Array fnearness; + + static int cnt = 0; + cnt++; + + delfaces.SetSize (0); + elements.SetSize (0); + + // determine topological distance of faces and points to + // base element + + pnearness.SetSize (lpoints.Size()); + fnearness.SetSize (lfacesplit); + + pnearness = INT_MAX/10; + for (j = 0; j < lfaces[0].GetNP(); j++) + pnearness[lfaces[0][j]] = 0; + + NgProfiler::RegionTimer reg2(98); + + NgProfiler::StartTimer (90); + + for (int loop = 0; loop < 2; loop++) + { + + for (i = 0; i < lfacesplit; i++) + { + const MiniElement2d & hface = lfaces[i]; + + int minn = INT_MAX-1; + for (j = 0; j < hface.GetNP(); j++) + { + int hi = pnearness[hface[j]]; + if (hi < minn) minn = hi; + } + if (minn < INT_MAX/10) + for (j = 0; j < hface.GetNP(); j++) + if (pnearness[hface[j]] > minn+1) + pnearness[hface[j]] = minn+1; + } + + for (i = 1; i <= connectedpairs.GetNBags(); i++) + for (j = 1; j <= connectedpairs.GetBagSize(i); j++) + { + INDEX_2 edge; + int val; + connectedpairs.GetData (i, j, edge, val); + + if (pnearness[edge.I1()] > pnearness[edge.I2()] + 1) + pnearness[edge.I1()] = pnearness[edge.I2()] + 1; + + if (pnearness[edge.I2()] > pnearness[edge.I1()] + 1) + pnearness[edge.I2()] = pnearness[edge.I1()] + 1; + } + + } + + for (i = 0; i < fnearness.Size(); i++) + { + int sum = 0; + for (j = 0; j < lfaces[i].GetNP(); j++) + sum += pnearness[lfaces[i][j]]; + fnearness[i] = sum; + } + + + NgProfiler::StopTimer (90); + NgProfiler::StartTimer (91); + + // find bounding boxes of faces + + triboxes.SetSize (lfaces.Size()); + for (i = 0; i < lfaces.Size(); i++) + { + const MiniElement2d & face = lfaces[i]; + triboxes[i].SetPoint (lpoints.Get(face[0])); + for (j = 1; j < face.GetNP(); j++) + triboxes[i].AddPoint (lpoints.Get(face[j])); + } + + NgProfiler::StopTimer (91); + NgProfiler::StartTimer (92); + + + bool useedges = 0; + for (ri = 0; ri < rules.Size(); ri++) + if (rules[ri]->GetNEd()) useedges = 1; + + if (useedges) + { + ledges.SetSize (5 * lfacesplit); + + for (j = 0; j < lfacesplit; j++) + // if (fnearness[j] <= 5) + { + const MiniElement2d & face = lfaces[j]; + int newp, oldp; + + newp = face[face.GetNP()-1]; + for (k = 0; k < face.GetNP(); k++) + { + oldp = newp; + newp = face[k]; + ledges.Set (INDEX_2::Sort(oldp, newp), 1); + } + } + } + + NgProfiler::StopTimer (92); + + NgProfiler::RegionTimer reg3(99); + + pused.SetSize (lpoints.Size()); + fused.SetSize (lfaces.Size()); + + found = 0; + minerr = tolfak * tolerance * tolerance; + minteterr = sloppy * tolerance; + + if (testmode) + (*testout) << "cnt = " << cnt << " class = " << tolerance << endl; + + + + // impossible, if no rule can be applied at any tolerance class + bool impossible = 1; + + + // check each rule: + + for (ri = 1; ri <= rules.Size(); ri++) + { + int base = (lfaces[0].GetNP() == 3) ? 100 : 200; + NgProfiler::RegionTimer regx1(base); + NgProfiler::RegionTimer regx(base+ri); + + sprintf (problems.Elem(ri), ""); + + rule = rules.Get(ri); + + if (rule->GetNP(1) != lfaces[0].GetNP()) + continue; + + if (rule->GetQuality() > tolerance) + { + if (rule->GetQuality() < 100) impossible = 0; + + if (testmode) + sprintf (problems.Elem(ri), "Quality not ok"); + continue; + } + + if (testmode) + sprintf (problems.Elem(ri), "no mapping found"); + + loktestmode = testmode || rule->TestFlag ('t') || tolerance > 5; + + if (loktestmode) + (*testout) << "Rule " << ri << " = " << rule->Name() << endl; + + pmap.SetSize (rule->GetNP()); + fmapi.SetSize (rule->GetNF()); + fmapr.SetSize (rule->GetNF()); + + fused = 0; + pused = 0; + pmap = 0; + fmapi = 0; + for (i = 1; i <= fmapr.Size(); i++) + fmapr.Set(i, rule->GetNP(i)); + + fused[0] = 1; + fmapi[0] = 1; + fmapr[0] = rotind1; + + + for (j = 1; j <= lfaces.Get(1).GetNP(); j++) + { + locpi = lfaces[0].PNumMod (j+rotind1); + pmap.Set (rule->GetPointNr (1, j), locpi); + pused.Elem(locpi)++; + } + + /* + map all faces + nfok .. first nfok-1 faces are mapped properly + */ + + nfok = 2; + NgProfiler::RegionTimer regfa(300); + NgProfiler::RegionTimer regx2(base+50+ri); + while (nfok >= 2) + { + + if (nfok <= rule->GetNOldF()) + { + // not all faces mapped + + ok = 0; + locfi = fmapi.Get(nfok); + locfr = fmapr.Get(nfok); + + int actfnp = rule->GetNP(nfok); + + while (!ok) + { + locfr++; + if (locfr == actfnp + 1) + { + locfr = 1; + locfi++; + if (locfi > lfacesplit) break; + } + + + if (fnearness.Get(locfi) > rule->GetFNearness (nfok) || + fused.Get(locfi) || + actfnp != lfaces.Get(locfi).GetNP() ) + { + // face not feasible in any rotation + + locfr = actfnp; + } + else + { + + ok = 1; + + locface = &lfaces.Get(locfi); + + + // reference point already mapped differently ? + for (j = 1; j <= actfnp && ok; j++) + { + locpi = pmap.Get(rule->GetPointNr (nfok, j)); + + if (locpi && locpi != locface->PNumMod(j+locfr)) + ok = 0; + } + + // local point already used or point outside tolerance ? + for (j = 1; j <= actfnp && ok; j++) + { + refpi = rule->GetPointNr (nfok, j); + + if (pmap.Get(refpi) == 0) + { + locpi = locface->PNumMod (j + locfr); + + if (pused.Get(locpi)) + ok = 0; + else + { + const Point3d & lp = lpoints.Get(locpi); + const Point3d & rp = rule->GetPoint(refpi); + + if ( Dist2 (lp, rp) * rule->PointDistFactor(refpi) > minerr) + { + impossible = 0; + ok = 0; + } + } + } + } + } + } + + + if (ok) + { + // map face nfok + + fmapi.Set (nfok, locfi); + fmapr.Set (nfok, locfr); + fused.Set (locfi, 1); + + for (j = 1; j <= rule->GetNP (nfok); j++) + { + locpi = locface->PNumMod(j+locfr); + + if (rule->GetPointNr (nfok, j) <= 3 && + pmap.Get(rule->GetPointNr(nfok, j)) != locpi) + (*testout) << "change face1 point, mark1" << endl; + + pmap.Set(rule->GetPointNr (nfok, j), locpi); + pused.Elem(locpi)++; + } + + nfok++; + } + else + { + // backtrack one face + fmapi.Set (nfok, 0); + fmapr.Set (nfok, rule->GetNP(nfok)); + nfok--; + + fused.Set (fmapi.Get(nfok), 0); + for (j = 1; j <= rule->GetNP (nfok); j++) + { + refpi = rule->GetPointNr (nfok, j); + pused.Elem(pmap.Get(refpi))--; + + if (pused.Get(pmap.Get(refpi)) == 0) + { + pmap.Set(refpi, 0); + } + } + } + } + + else + + { + NgProfiler::RegionTimer regfb(301); + + // all faces are mapped + // now map all isolated points: + + if (loktestmode) + { + (*testout) << "Faces Ok" << endl; + sprintf (problems.Elem(ri), "Faces Ok"); + } + + npok = 1; + incnpok = 1; + + pfixed.SetSize (pmap.Size()); + for (i = 1; i <= pmap.Size(); i++) + pfixed.Set(i, (pmap.Get(i) != 0) ); + + while (npok >= 1) + { + + if (npok <= rule->GetNOldP()) + { + + if (pfixed.Get(npok)) + + { + if (incnpok) + npok++; + else + npok--; + } + + else + + { + locpi = pmap.Elem(npok); + ok = 0; + + if (locpi) + pused.Elem(locpi)--; + + while (!ok && locpi < lpoints.Size()) + { + ok = 1; + locpi++; + + if (pused.Get(locpi) || + pnearness.Get(locpi) > rule->GetPNearness(npok)) + { + ok = 0; + } + else if (allowpoint.Get(locpi) != 2) + { + ok = 0; + if (allowpoint.Get(locpi) == 1) + impossible = 0; + } + else + { + const Point3d & lp = lpoints.Get(locpi); + const Point3d & rp = rule->GetPoint(npok); + + if ( Dist2 (lp, rp) * rule->PointDistFactor(npok) > minerr) + { + ok = 0; + impossible = 0; + } + } + } + + + if (ok) + { + pmap.Set (npok, locpi); + + if (npok <= 3) + (*testout) << "set face1 point, mark3" << endl; + + pused.Elem(locpi)++; + npok++; + incnpok = 1; + } + + else + + { + pmap.Set (npok, 0); + + if (npok <= 3) + (*testout) << "set face1 point, mark4" << endl; + + npok--; + incnpok = 0; + } + } + } + + else + + { + NgProfiler::RegionTimer regfa2(302); + + // all points are mapped + + if (loktestmode) + { + (*testout) << "Mapping found!!: Rule " << rule->Name() << endl; + for (i = 1; i <= pmap.Size(); i++) + (*testout) << pmap.Get(i) << " "; + (*testout) << endl; + sprintf (problems.Elem(ri), "mapping found"); + (*testout) << rule->GetNP(1) << " = " << lfaces.Get(1).GetNP() << endl; + } + + ok = 1; + + + // check mapedges: + for (i = 1; i <= rule->GetNEd(); i++) + { + INDEX_2 in2(pmap.Get(rule->GetEdge(i).i1), + pmap.Get(rule->GetEdge(i).i2)); + in2.Sort(); + if (!ledges.Used (in2)) ok = 0; + } + + + // check prism edges: + for (i = 1; i <= rule->GetNE(); i++) + { + const Element & el = rule->GetElement (i); + if (el.GetType() == PRISM) + { + for (j = 1; j <= 3; j++) + { + INDEX_2 in2(pmap.Get(el.PNum(j)), + pmap.Get(el.PNum(j+3))); + in2.Sort(); + if (!connectedpairs.Used (in2)) ok = 0; + } + } + if (el.GetType() == PYRAMID) + { + if (loktestmode) + (*testout) << "map pyramid, rule = " << rule->Name() << endl; + for (j = 1; j <= 2; j++) + { + INDEX_2 in2; + if (j == 1) + { + in2.I1() = pmap.Get(el.PNum(2)); + in2.I2() = pmap.Get(el.PNum(3)); + } + else + { + in2.I1() = pmap.Get(el.PNum(1)); + in2.I2() = pmap.Get(el.PNum(4)); + } + in2.Sort(); + if (!connectedpairs.Used (in2)) + { + ok = 0; + if (loktestmode) + (*testout) << "no pair" << endl; + } + } + } + + } + + + + for (i = rule->GetNOldF() + 1; i <= rule->GetNF(); i++) + fmapi.Set(i, 0); + + + if (ok) + { + foundmap.Elem(ri)++; + } + + + + + // deviation of existing points + + oldu.SetSize (3 * rule->GetNOldP()); + newu.SetSize (3 * (rule->GetNP() - rule->GetNOldP())); + allp.SetSize (3 * rule->GetNP()); + + for (i = 1; i <= rule->GetNOldP(); i++) + { + const Point3d & lp = lpoints.Get(pmap.Get(i)); + const Point3d & rp = rule->GetPoint(i); + oldu (3*i-3) = lp.X()-rp.X(); + oldu (3*i-2) = lp.Y()-rp.Y(); + oldu (3*i-1) = lp.Z()-rp.Z(); + + allp (3*i-3) = lp.X(); + allp (3*i-2) = lp.Y(); + allp (3*i-1) = lp.Z(); + } + + if (rule->GetNP() > rule->GetNOldP()) + { + newu.SetSize (rule->GetOldUToNewU().Height()); + rule->GetOldUToNewU().Mult (oldu, newu); + } + + // int idiff = 3 * (rule->GetNP()-rule->GetNOldP()); + int idiff = 3 * rule->GetNOldP(); + for (i = rule->GetNOldP()+1; i <= rule->GetNP(); i++) + { + const Point3d & rp = rule->GetPoint(i); + allp (3*i-3) = rp.X() + newu(3*i-3 - idiff); + allp (3*i-2) = rp.Y() + newu(3*i-2 - idiff); + allp (3*i-1) = rp.Z() + newu(3*i-1 - idiff); + } + + rule->SetFreeZoneTransformation (allp, + tolerance + int(sloppy)); + + if (!rule->ConvexFreeZone()) + { + ok = 0; + sprintf (problems.Elem(ri), "Freezone not convex"); + + if (loktestmode) + (*testout) << "Freezone not convex" << endl; + } + + if (loktestmode) + { + const Array & fz = rule->GetTransFreeZone(); + (*testout) << "Freezone: " << endl; + for (i = 1; i <= fz.Size(); i++) + (*testout) << fz.Get(i) << endl; + } + + + // check freezone: + + for (i = 1; i <= lpoints.Size(); i++) + { + if ( !pused.Get(i) ) + { + const Point3d & lp = lpoints.Get(i); + + if (rule->fzbox.IsIn (lp)) + { + if (rule->IsInFreeZone(lp)) + { + if (loktestmode) + { + (*testout) << "Point " << i + << " in Freezone" << endl; + sprintf (problems.Elem(ri), + "locpoint %d in Freezone", i); + } + ok = 0; + break; + } + } + } + } + + for (i = 1; i <= lfaces.Size() && ok; i++) + { + static Array lpi(4); + + if (!fused.Get(i)) + { + int triin; + const MiniElement2d & lfacei = lfaces.Get(i); + + if (!triboxes.Elem(i).Intersect (rule->fzbox)) + triin = 0; + else + { + int li, lj; + for (li = 1; li <= lfacei.GetNP(); li++) + { + int lpii = 0; + int pi = lfacei.PNum(li); + for (lj = 1; lj <= rule->GetNOldP(); lj++) + if (pmap.Get(lj) == pi) + lpii = lj; + lpi.Elem(li) = lpii; + } + + + if (lfacei.GetNP() == 3) + { + triin = rule->IsTriangleInFreeZone + ( + lpoints.Get(lfacei.PNum(1)), + lpoints.Get(lfacei.PNum(2)), + lpoints.Get(lfacei.PNum(3)), lpi, 1 + ); + } + else + { + triin = rule->IsQuadInFreeZone + ( + lpoints.Get(lfacei.PNum(1)), + lpoints.Get(lfacei.PNum(2)), + lpoints.Get(lfacei.PNum(3)), + lpoints.Get(lfacei.PNum(4)), + lpi, 1 + ); + } + } + + + if (triin == -1) + { + ok = 0; + } + + if (triin == 1) + { +#ifdef TEST_JS + ok = 0; + + if (loktestmode) + { + (*testout) << "El with " << lfaces.Get(i).GetNP() << " points in freezone: " + << lfaces.Get(i).PNum(1) << " - " + << lfaces.Get(i).PNum(2) << " - " + << lfaces.Get(i).PNum(3) << " - " + << lfaces.Get(i).PNum(4) << endl; + for (int lj = 1; lj <= lfaces.Get(i).GetNP(); lj++) + (*testout) << lpoints.Get(lfaces.Get(i).PNum(lj)) << " "; + + (*testout) << endl; + + sprintf (problems.Elem(ri), "triangle (%d, %d, %d) in Freezone", + lfaces.Get(i).PNum(1), lfaces.Get(i).PNum(2), + lfaces.Get(i).PNum(3)); + } +#else + if (loktestmode) + { + if (lfacei.GetNP() == 3) + { + (*testout) << "Triangle in freezone: " + << lfacei.PNum(1) << " - " + << lfacei.PNum(2) << " - " + << lfacei.PNum(3) + << ", or " + << lpoints.Get(lfacei.PNum(1)) << " - " + << lpoints.Get(lfacei.PNum(2)) << " - " + << lpoints.Get(lfacei.PNum(3)) + << endl; + (*testout) << "lpi = " << lpi.Get(1) << ", " + << lpi.Get(2) << ", " << lpi.Get(3) << endl; + } + else + (*testout) << "Quad in freezone: " + << lfacei.PNum(1) << " - " + << lfacei.PNum(2) << " - " + << lfacei.PNum(3) << " - " + << lfacei.PNum(4) + << ", or " + << lpoints.Get(lfacei.PNum(1)) << " - " + << lpoints.Get(lfacei.PNum(2)) << " - " + << lpoints.Get(lfacei.PNum(3)) << " - " + << lpoints.Get(lfacei.PNum(4)) + << endl; + + sprintf (problems.Elem(ri), "triangle (%d, %d, %d) in Freezone", + int(lfaces.Get(i).PNum(1)), + int(lfaces.Get(i).PNum(2)), + int(lfaces.Get(i).PNum(3))); + } + + hc = 0; + for (k = rule->GetNOldF() + 1; k <= rule->GetNF(); k++) + { + if (rule->GetPointNr(k, 1) <= rule->GetNOldP() && + rule->GetPointNr(k, 2) <= rule->GetNOldP() && + rule->GetPointNr(k, 3) <= rule->GetNOldP()) + { + for (j = 1; j <= 3; j++) + if (lfaces.Get(i).PNumMod(j ) == pmap.Get(rule->GetPointNr(k, 1)) && + lfaces.Get(i).PNumMod(j+1) == pmap.Get(rule->GetPointNr(k, 3)) && + lfaces.Get(i).PNumMod(j+2) == pmap.Get(rule->GetPointNr(k, 2))) + { + fmapi.Elem(k) = i; + hc = 1; + + + // (*testout) << "found from other side: " +// << rule->Name() +// << " ( " << pmap.Get (rule->GetPointNr(k, 1)) +// << " - " << pmap.Get (rule->GetPointNr(k, 2)) +// << " - " << pmap.Get (rule->GetPointNr(k, 3)) << " ) " +// << endl; + + strcpy (problems.Elem(ri), "other"); + } + } + } + + if (!hc) + { + if (loktestmode) + { + (*testout) << "Triangle in freezone: " + << lfaces.Get(i).PNum(1) << " - " + << lfaces.Get(i).PNum(2) << " - " + << lfaces.Get(i).PNum(3) << endl; + + sprintf (problems.Elem(ri), "triangle (%d, %d, %d) in Freezone", + int (lfaces.Get(i).PNum(1)), + int (lfaces.Get(i).PNum(2)), + int (lfaces.Get(i).PNum(3))); + } + ok = 0; + } +#endif + } + } + + } + + + if (ok) + { + err = 0; + for (i = 1; i <= rule->GetNOldP(); i++) + { + hf = rule->CalcPointDist (i, lpoints.Get(pmap.Get(i))); + if (hf > err) err = hf; + } + + + if (loktestmode) + { + (*testout) << "Rule ok" << endl; + sprintf (problems.Elem(ri), "Rule ok, err = %f", err); + } + + + // newu = rule->GetOldUToNewU() * oldu; + + // set new points: + + oldnp = rule->GetNOldP(); + noldlp = lpoints.Size(); + noldlf = lfaces.Size(); + + + for (i = oldnp + 1; i <= rule->GetNP(); i++) + { + np = rule->GetPoint(i); + np.X() += newu (3 * (i-oldnp) - 3); + np.Y() += newu (3 * (i-oldnp) - 2); + np.Z() += newu (3 * (i-oldnp) - 1); + + pmap.Elem(i) = lpoints.Append (np); + } + + // Set new Faces: + + for (i = rule->GetNOldF() + 1; i <= rule->GetNF(); i++) + if (!fmapi.Get(i)) + { + MiniElement2d nface(rule->GetNP(i)); + for (j = 1; j <= nface.GetNP(); j++) + nface.PNum(j) = pmap.Get(rule->GetPointNr (i, j)); + + lfaces.Append (nface); + } + + + // Delete old Faces: + + for (i = 1; i <= rule->GetNDelF(); i++) + delfaces.Append (fmapi.Get(rule->GetDelFace(i))); + for (i = rule->GetNOldF()+1; i <= rule->GetNF(); i++) + if (fmapi.Get(i)) + { + delfaces.Append (fmapi.Get(i)); + fmapi.Elem(i) = 0; + } + + + // check orientation + for (i = 1; i <= rule->GetNO() && ok; i++) + { + const fourint * fouri; + + fouri = &rule->GetOrientation(i); + Vec3d v1 (lpoints.Get(pmap.Get(fouri->i1)), + lpoints.Get(pmap.Get(fouri->i2))); + Vec3d v2 (lpoints.Get(pmap.Get(fouri->i1)), + lpoints.Get(pmap.Get(fouri->i3))); + Vec3d v3 (lpoints.Get(pmap.Get(fouri->i1)), + lpoints.Get(pmap.Get(fouri->i4))); + + Vec3d n; + Cross (v1, v2, n); + //if (n * v3 >= -1e-7*n.Length()*v3.Length()) // OR -1e-7??? + if (n * v3 >= -1e-9) + { + if (loktestmode) + { + sprintf (problems.Elem(ri), "Orientation wrong"); + (*testout) << "Orientation wrong ("<< n*v3 << ")" << endl; + } + ok = 0; + } + } + + + + // new points in free-zone ? + for (i = rule->GetNOldP() + 1; i <= rule->GetNP() && ok; i++) + if (!rule->IsInFreeZone (lpoints.Get(pmap.Get(i)))) + { + if (loktestmode) + { + (*testout) << "Newpoint " << lpoints.Get(pmap.Get(i)) + << " outside convex hull" << endl; + sprintf (problems.Elem(ri), "newpoint outside convex hull"); + } + ok = 0; + + } + + // insert new elements + + for (i = 1; i <= rule->GetNE(); i++) + { + elements.Append (rule->GetElement(i)); + for (j = 1; j <= elements.Get(i).NP(); j++) + elements.Elem(i).PNum(j) = pmap.Get(elements.Get(i).PNum(j)); + } + + + // Calculate Element badness + + teterr = 0; + for (i = 1; i <= elements.Size(); i++) + { + hf = CalcElementBadness (lpoints, elements.Get(i)); + if (hf > teterr) teterr = hf; + } + + /* + // keine gute Erfahrung am 25.1.2000, js + if (ok && teterr < 100 && + (rule->TestFlag('b') || tolerance > 10) ) + { + (*mycout) << "Reset teterr " + << rule->Name() + << " err = " << teterr + << endl; + teterr = 1; + } + */ + + // compare edgelength + if (rule->TestFlag('l')) + { + double oldlen = 0; + double newlen = 0; + + for (i = 1; i <= rule->GetNDelF(); i++) + { + const Element2d & face = + rule->GetFace (rule->GetDelFace(i)); + for (j = 1; j <= 3; j++) + { + const Point3d & p1 = + lpoints.Get(pmap.Get(face.PNumMod(j))); + const Point3d & p2 = + lpoints.Get(pmap.Get(face.PNumMod(j+1))); + oldlen += Dist(p1, p2); + } + } + + for (i = rule->GetNOldF()+1; i <= rule->GetNF(); i++) + { + const Element2d & face = rule->GetFace (i); + for (j = 1; j <= 3; j++) + { + const Point3d & p1 = + lpoints.Get(pmap.Get(face.PNumMod(j))); + const Point3d & p2 = + lpoints.Get(pmap.Get(face.PNumMod(j+1))); + newlen += Dist(p1, p2); + } + } + + if (oldlen < newlen) + { + ok = 0; + if (loktestmode) + sprintf (problems.Elem(ri), "oldlen < newlen"); + } + } + + + if (loktestmode) + (*testout) << "ok = " << int(ok) + << "teterr = " << teterr + << "minteterr = " << minteterr << endl; + + + if (ok && teterr < tolerance) + { + canuse.Elem(ri) ++; + /* + (*testout) << "can use rule " << rule->Name() + << ", err = " << teterr << endl; + for (i = 1; i <= pmap.Size(); i++) + (*testout) << pmap.Get(i) << " "; + (*testout) << endl; + */ + + if (strcmp (problems.Elem(ri), "other") == 0) + { + if (teterr < minother) + minother = teterr; + } + else + { + if (teterr < minwithoutother) + minwithoutother = teterr; + } + } + + + if (teterr > minteterr) impossible = 0; + + if (ok && teterr < minteterr) + { + + if (loktestmode) + (*testout) << "use rule" << endl; + + found = ri; + minteterr = teterr; + + if (testmode) + { + for (i = 1; i <= rule->GetNOldP(); i++) + { + (*testout) << "P" << i << ": Ref: " + << rule->GetPoint (i) << " is: " + << lpoints.Get(pmap.Get(i)) << endl; + } + } + + tempnewpoints.SetSize (0); + for (i = noldlp+1; i <= lpoints.Size(); i++) + tempnewpoints.Append (lpoints.Get(i)); + + tempnewfaces.SetSize (0); + for (i = noldlf+1; i <= lfaces.Size(); i++) + tempnewfaces.Append (lfaces.Get(i)); + + tempdelfaces.SetSize (0); + for (i = 1; i <= delfaces.Size(); i++) + tempdelfaces.Append (delfaces.Get(i)); + + tempelements.SetSize (0); + for (i = 1; i <= elements.Size(); i++) + tempelements.Append (elements.Get(i)); + } + + + lpoints.SetSize (noldlp); + lfaces.SetSize (noldlf); + delfaces.SetSize (0); + elements.SetSize (0); + } + + npok = rule->GetNOldP(); + incnpok = 0; + } + } + + nfok = rule->GetNOldF(); + + for (j = 1; j <= rule->GetNP (nfok); j++) + { + refpi = rule->GetPointNr (nfok, j); + pused.Elem(pmap.Get(refpi))--; + + if (pused.Get(pmap.Get(refpi)) == 0) + { + pmap.Set(refpi, 0); + } + } + + } + } + if (loktestmode) + (*testout) << "end rule" << endl; + } + + if (found) + { + for (i = 1; i <= tempnewpoints.Size(); i++) + lpoints.Append (tempnewpoints.Get(i)); + for (i = 1; i <= tempnewfaces.Size(); i++) + if (tempnewfaces.Get(i).PNum(1)) + lfaces.Append (tempnewfaces.Get(i)); + for (i = 1; i <= tempdelfaces.Size(); i++) + delfaces.Append (tempdelfaces.Get(i)); + for (i = 1; i <= tempelements.Size(); i++) + elements.Append (tempelements.Get(i)); + } + + retminerr = minerr; + + + if (impossible && found == 0) + return -1; + + return found; +} +} diff --git a/libsrc/meshing/ruler3.hpp b/libsrc/meshing/ruler3.hpp new file mode 100644 index 00000000..fcbf8f59 --- /dev/null +++ b/libsrc/meshing/ruler3.hpp @@ -0,0 +1,210 @@ +#ifndef FILE_RULER3 +#define FILE_RULER3 + + +/** + 3D element generation rule. + */ +class vnetrule +{ +private: + /// rule is applicable for quality classes above this value + int quality; + /// name of rule + char * name; + /// point coordinates in reference position + Array points; + /// old and new faces in reference numbering + Array faces; + /// additional edges of rule + Array edges; + + /// points of freezone in reference coordinates + Array freezone; + /// points of freezone in reference coordinates if tolcalss to infty + Array freezonelimit; + /// point index, if point equal to mappoint, otherwise 0 + Array freezonepi; + /// faces of each convex part of freezone + Array*> freefaces; + /// set of points of each convex part of freezone + Array*> freesets; + /// points of transformed freezone + Array transfreezone; + /// edges of each convex part of freezone + Array*> freeedges; + + /// face numbers to be deleted + Array delfaces; + /// elements to be generated + Array elements; + /// tolerances for points and faces (used ??) + Array tolerances, linetolerances; + /// transformation matrix + DenseMatrix oldutonewu; + /// transformation matrix: deviation old point to dev. freezone + DenseMatrix * oldutofreezone; + /** transformation matrix: deviation old point to dev. freezone, + quality class to infinity */ + DenseMatrix * oldutofreezonelimit; + + // can be deleted: + // BaseMatrix *outf, *outfl; + + /** + a point is outside of convex part of freezone, + iff mat * (point, 1) >= 0 for each component (correct ?) + */ + Array freefaceinequ; + /// + Array orientations; + /** + flags specified in rule-description file: + t .. test rule + */ + Array flags; + + /** + topological distance of face to base element + non-connected: > 100 (??) + */ + Array fnearness; + Array pnearness; + int maxpnearness; + + /// number of old points in rule + int noldp; + /// number of new poitns in rule + int noldf; + /// box containing free-zone +public: + // double fzminx, fzmaxx, fzminy, fzmaxy, fzminz, fzmaxz; + Box3d fzbox; + +public: + + /// + vnetrule (); + /// + ~vnetrule (); + /// + int GetNP () const { return points.Size(); } + /// + int GetNF () const { return faces.Size(); } + /// + int GetNE () const { return elements.Size(); } + /// + int GetNO () const { return orientations.Size(); } + /// + int GetNEd () const { return edges.Size(); } + /// + int GetNOldP () const { return noldp; } + /// + int GetNOldF () const { return noldf; } + /// + int GetNDelF () const { return delfaces.Size(); } + /// + int GetQuality () const { return quality; } + /// + int GetFNearness (int fi) const { return fnearness.Get(fi); } + /// + int GetPNearness (int pi) const { return pnearness.Get(pi); } + /// + int GetMaxPNearness () const { return maxpnearness; } + + + /// + const Point3d & GetPoint (int i) const { return points.Get(i); } + /// + const Element2d & GetFace (int i) const { return faces.Get(i); } + /// + const Element & GetElement (int i) const { return elements.Get(i); } + /// + const twoint & GetEdge (int i) const { return edges.Get(i); } + /// + int GetDelFace (int i) const { return delfaces.Get(i); } + /// + int IsDelFace (int fn) const; + + /// + float CalcPointDist (int pi, const Point3d & p) const; + /// + double PointDistFactor (int pi) const + { + return tolerances.Get(pi); + } + /// + void SetFreeZoneTransformation (const Vector & allp, + int tolclass); + /// + int IsInFreeZone (const Point3d & p) const; + /** + 0 not in free-zone + 1 in free-zone + -1 maybe + */ + int IsTriangleInFreeZone (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Array & pi, int newone); + /// + int IsQuadInFreeZone (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, + const Array & pi, int newone); + /// + int IsTriangleInFreeSet (const Point3d & p1, const Point3d & p2, + const Point3d & p3, int fs, const Array & pi, int newone); + + /// + int IsQuadInFreeSet (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4, + int fs, const Array & pi, int newone); + + /// + int ConvexFreeZone () const; + + /// if t1 and t2 are neighbourtriangles, NTP returns the opposite Point of t1 in t2 + int NeighbourTrianglePoint (const threeint & t1, const threeint & t2) const; + /// + const Point3d & GetTransFreeZone (int i) { return transfreezone.Get(i); } + + /// + int GetNP (int fn) const + { return faces.Get(fn).GetNP(); } + /// + int GetPointNr (int fn, int endp) const + { return faces.Get(fn).PNum(endp); } + /// + int GetPointNrMod (int fn, int endp) const + { return faces.Get(fn).PNumMod(endp); } + /// + const fourint & GetOrientation (int i) { return orientations.Get(i); } + + /// + int TestFlag (char flag) const; + + /// + const DenseMatrix & GetOldUToNewU () const { return oldutonewu; } + // + // const DenseMatrix & GetOldUToFreeZone () const { return oldutofreezone; } + // + // const DenseMatrix & GetOldUToFreeZoneLimit () const + // { return oldutofreezonelimit; } + /// + const char * Name () const { return name; } + /// + void LoadRule (istream & ist); + + /// + const Array & GetTransFreeZone () { return transfreezone; } + /// + int TestOk () const; + + /// + friend void TestRules (); + /// + // friend void Plot3DRule (const ROT3D & r, char key); +}; + + + +#endif + diff --git a/libsrc/meshing/secondorder.cpp b/libsrc/meshing/secondorder.cpp new file mode 100644 index 00000000..7cd2205a --- /dev/null +++ b/libsrc/meshing/secondorder.cpp @@ -0,0 +1,495 @@ +#include +#include "meshing.hpp" + + +namespace netgen +{ + + void Refinement :: MakeSecondOrder (Mesh & mesh) const + { + const_cast (*this).MakeSecondOrder(mesh); + } + + + void Refinement :: MakeSecondOrder (Mesh & mesh) + { + int nseg, nse, ne; + + mesh.ComputeNVertices(); + mesh.SetNP(mesh.GetNV()); + + INDEX_2_HASHTABLE between(mesh.GetNP() + 5); + + + bool thinlayers = 0; + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + if (mesh[ei].GetType() == PRISM || + mesh[ei].GetType() == PRISM12) + thinlayers = 1; + + + nseg = mesh.GetNSeg(); + for (SegmentIndex si = 0; si < nseg; si++) + { + Segment & el = mesh.LineSegment(si); + + INDEX_2 i2 = INDEX_2::Sort (el[0], el[1]); + + if (between.Used(i2)) + el[2] = between.Get(i2); + else + { + Point<3> pb; + EdgePointGeomInfo ngi; + PointBetween (mesh.Point (el[0]), + mesh.Point (el[1]), 0.5, + el.surfnr1, el.surfnr2, + el.epgeominfo[0], el.epgeominfo[1], + pb, ngi); + + el[2] = mesh.AddPoint (pb, mesh.Point(el[0]).GetLayer(), + EDGEPOINT); + between.Set (i2, el[2]); + } + } + + // refine surface elements + nse = mesh.GetNSE(); + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + int j; + const Element2d & el = mesh.SurfaceElement(sei); + + int onp(0); + + Element2d newel; + newel.SetIndex (el.GetIndex()); + + static int betw_trig[3][3] = + { { 1, 2, 3 }, + { 0, 2, 4 }, + { 0, 1, 5 } }; + static int betw_quad6[2][3] = + { { 0, 1, 4 }, + { 3, 2, 5 } }; + static int betw_quad8[4][3] = + { { 0, 1, 4 }, + { 3, 2, 5 }, + { 0, 3, 6 }, + { 1, 2, 7 } }; + int (*betw)[3] = NULL; + + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + betw = betw_trig; + newel.SetType (TRIG6); + onp = 3; + break; + } + case QUAD: + case QUAD6: + case QUAD8: + { + if (thinlayers) + { + betw = betw_quad6; + newel.SetType (QUAD6); + } + else + { + betw = betw_quad8; + newel.SetType (QUAD8); + } + onp = 4; + break; + } + default: + PrintSysError ("Unhandled element in secondorder:", int(el.GetType())); + } + + for (j = 0; j < onp; j++) + newel[j] = el[j]; + + int nnp = newel.GetNP(); + for (j = 0; j < nnp-onp; j++) + { + int pi1 = newel[betw[j][0]]; + int pi2 = newel[betw[j][1]]; + + INDEX_2 i2 = INDEX_2::Sort (pi1, pi2); + + if (between.Used(i2)) + newel[onp+j] = between.Get(i2); + else + { + Point<3> pb; + PointGeomInfo newgi; + PointBetween (mesh.Point (pi1), + mesh.Point (pi2), 0.5, + mesh.GetFaceDescriptor(el.GetIndex ()).SurfNr(), + el.GeomInfoPi (betw[j][0]+1), + el.GeomInfoPi (betw[j][1]+1), + pb, newgi); + + newel[onp+j] = mesh.AddPoint (pb, mesh.Point(pi1).GetLayer(), + SURFACEPOINT); + between.Set (i2, newel[onp+j]); + } + } + + mesh.SurfaceElement(sei) = newel; + } + + + // int i, j; + + + + // refine volume elements + ne = mesh.GetNE(); + for (int i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + int onp = 0; + + Element newel; + newel.SetIndex (el.GetIndex()); + + static int betw_tet[6][3] = + { { 0, 1, 4 }, + { 0, 2, 5 }, + { 0, 3, 6 }, + { 1, 2, 7 }, + { 1, 3, 8 }, + { 2, 3, 9 } }; + static int betw_prism[6][3] = + { + { 0, 2, 6 }, + { 0, 1, 7 }, + { 1, 2, 8 }, + { 3, 5, 9 }, + { 3, 4, 10 }, + { 4, 5, 11 }, + }; + int (*betw)[3] = NULL; + + switch (el.GetType()) + { + case TET: + case TET10: + { + betw = betw_tet; + newel.SetType (TET10); + onp = 4; + break; + } + case PRISM: + case PRISM12: + { + betw = betw_prism; + newel.SetType (PRISM12); + onp = 6; + break; + } + default: + PrintSysError ("MakeSecondOrder, illegal vol type ", el.GetType()); + } + + + for (int j = 1; j <= onp; j++) + newel.PNum(j) = el.PNum(j); + int nnp = newel.GetNP(); + + for (int j = 0; j < nnp-onp; j++) + { + INDEX_2 i2(newel[betw[j][0]], + newel[betw[j][1]]); + i2.Sort(); + + if (between.Used(i2)) + newel.PNum(onp+1+j) = between.Get(i2); + else + { + newel.PNum(onp+1+j) = mesh.AddPoint + (Center (mesh.Point(i2.I1()), + mesh.Point(i2.I2())), + mesh.Point(i2.I1()).GetLayer(), + INNERPOINT); + + between.Set (i2, newel.PNum(onp+1+j)); + } + } + + mesh.VolumeElement (i) = newel; + } + + + // makes problems after linear mesh refinement, since + // 2nd order identifications are not removed + // update identification tables + for (int i = 1; i <= mesh.GetIdentifications().GetMaxNr(); i++) + { + Array identmap; + mesh.GetIdentifications().GetMap (i, identmap); + + for (INDEX_2_HASHTABLE::Iterator it = between.Begin(); + it != between.End(); it++) + { + INDEX_2 i2; + PointIndex newpi; + between.GetData (it, i2, newpi); + INDEX_2 oi2(identmap.Get(i2.I1()), + identmap.Get(i2.I2())); + oi2.Sort(); + if (between.Used (oi2)) + { + PointIndex onewpi = between.Get(oi2); + mesh.GetIdentifications().Add (newpi, onewpi, i); + } + } + + /* + for (int j = 1; j <= between.GetNBags(); j++) + for (int k = 1; k <= between.GetBagSize(j); k++) + { + INDEX_2 i2; + int newpi; + between.GetData (j, k, i2, newpi); + INDEX_2 oi2(identmap.Get(i2.I1()), + identmap.Get(i2.I2())); + oi2.Sort(); + if (between.Used (oi2)) + { + int onewpi = between.Get(oi2); + mesh.GetIdentifications().Add (newpi, onewpi, i); + } + } + */ + } + + + // mesh.mglevels++; + int oldsize = mesh.mlbetweennodes.Size(); + mesh.mlbetweennodes.SetSize(mesh.GetNP()); + for (int i = oldsize; i < mesh.GetNP(); i++) + mesh.mlbetweennodes[i] = INDEX_2(0,0); + + /* + for (i = 1; i <= between.GetNBags(); i++) + for (j = 1; j <= between.GetBagSize(i); j++) + { + INDEX_2 oldp; + int newp; + between.GetData (i, j, oldp, newp); + mesh.mlbetweennodes.Elem(newp) = oldp; + } + */ + + for (INDEX_2_HASHTABLE::Iterator it = between.Begin(); + it != between.End(); it++) + { + mesh.mlbetweennodes[between.GetData (it)] = between.GetHash(it); + } + + mesh.ComputeNVertices(); + mesh.RebuildSurfaceElementLists(); + // ValidateSecondOrder (mesh); + } + + + void Refinement :: ValidateSecondOrder (Mesh & mesh) + { + PrintMessage (3, "Validate mesh"); + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + // int i, j; + Array parents(np); + + for (int i = 1; i <= np; i++) + parents.Elem(i) = INDEX_2(0,0); + + for (int i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + if (el.GetType() == TET10) + { + static int betweentab[6][3] = + { { 1, 2, 5 }, + { 1, 3, 6 }, + { 1, 4, 7 }, + { 2, 3, 8 }, + { 2, 4, 9 }, + { 3, 4, 10 } }; + for (int j = 0; j < 6; j++) + { + int f1 = el.PNum (betweentab[j][0]); + int f2 = el.PNum (betweentab[j][1]); + int son = el.PNum (betweentab[j][2]); + parents.Elem(son).I1() = f1; + parents.Elem(son).I2() = f2; + } + } + } + + ValidateRefinedMesh (mesh, parents); + } + + + void Refinement :: + ValidateRefinedMesh (Mesh & mesh, + Array & parents) + { + // int i, j, k; + + // homotopy method + + int ne = mesh.GetNE(); + + int cnttrials = 100; + int wrongels = 0; + for (int i = 1; i <= ne; i++) + if (mesh.VolumeElement(i).CalcJacobianBadness (mesh.Points()) > 1e10) + { + wrongels++; + mesh.VolumeElement(i).flags.badel = 1; + } + else + mesh.VolumeElement(i).flags.badel = 0; + + double facok = 0; + double factry; + + BitArray illegalels(ne); + illegalels.Clear(); + + + if (wrongels) + { + cout << "WARNING: " << wrongels << " illegal element(s) found" << endl; + + int np = mesh.GetNP(); + Array > should(np); + Array > can(np); + + for (int i = 1; i <= np; i++) + { + should.Elem(i) = can.Elem(i) = mesh.Point(i); + } + + for (int i = 1; i <= parents.Size(); i++) + { + if (parents.Get(i).I1()) + can.Elem(i) = Center (can.Elem(parents.Get(i).I1()), + can.Elem(parents.Get(i).I2())); + } + + BitArray boundp(np); + boundp.Clear(); + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + for (int j = 1; j <= sel.GetNP(); j++) + boundp.Set(sel.PNum(j)); + } + + + (*testout) << "bpoints:" << endl; + for (int i = 1; i <= np; i++) + if (boundp.Test(i)) + (*testout) << i << endl; + + double lam = 0.5; + + while (facok < 1-1e-8 && cnttrials > 0) + { + lam *= 4; + if (lam > 2) lam = 2; + + do + { + // cout << "trials: " << cnttrials << endl; + lam *= 0.5; + cnttrials--; + + cout << "lam = " << lam << endl; + + factry = lam + (1-lam) * facok; + cout << "trying: " << factry << endl; + + for (int i = 1; i <= np; i++) + if (boundp.Test(i)) + { + for (int j = 0; j < 3; j++) + mesh.Point(i)(j) = + lam * should.Get(i)(j) + + (1-lam) * can.Get(i)(j); + } + else + mesh.Point(i) = Point<3> (can.Get(i)); + + // (*testout) << "bad els: " << endl; + wrongels = 0; + for (int i = 1; i <= ne; i++) + { + if (!illegalels.Test(i) && + mesh.VolumeElement(i). + CalcJacobianBadness(mesh.Points()) > 1e10) + { + wrongels++; + Element & el = mesh.VolumeElement(i); + el.flags.badel = 1; + + + if (lam < 1e-4) + illegalels.Set(i); + + + /* + (*testout) << i << ": "; + for (j = 1; j <= el.GetNP(); j++) + (*testout) << el.PNum(j) << " "; + (*testout) << endl; + */ + } + else + mesh.VolumeElement(i).flags.badel = 0; + } + cout << "wrongels = " << wrongels << endl; + } + while (wrongels && cnttrials > 0); + + mesh.CalcSurfacesOfNode(); + MeshingParameters dummymp; + mesh.ImproveMeshJacobian (dummymp, OPT_WORSTCASE); + + facok = factry; + for (int i = 1; i <= np; i++) + can.Elem(i) = mesh.Point(i); + } + } + + + + for (int i = 1; i <= ne; i++) + { + if (illegalels.Test(i)) + { + cout << "illegal element: " << i << endl; + mesh.VolumeElement(i).flags.badel = 1; + } + else + mesh.VolumeElement(i).flags.badel = 0; + } + + /* + if (cnttrials <= 0) + { + cerr << "ERROR: Sorry, illegal elements:" << endl; + } + */ + } + +} diff --git a/libsrc/meshing/smoothing2.5.cpp b/libsrc/meshing/smoothing2.5.cpp new file mode 100644 index 00000000..2ab5c24c --- /dev/null +++ b/libsrc/meshing/smoothing2.5.cpp @@ -0,0 +1,264 @@ +#include + +#include "meshing.hpp" +#include + +namespace netgen +{ + + + void MeshOptimize2d :: ProjectBoundaryPoints(Array & surfaceindex, + const Array* > & from, Array* > & dest) + { + for(int i=0; i= 0) + { + *dest[i] = *from[i]; + ProjectPoint(surfaceindex[i],*dest[i]); + } + } + + + } + + void MeshOptimize2d :: ImproveVolumeMesh (Mesh & mesh) + { + + if (!faceindex) + { + PrintMessage (3, "Smoothing"); + + for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) + { + ImproveVolumeMesh (mesh); + if (multithread.terminate) + throw NgException ("Meshing stopped"); + } + faceindex = 0; + return; + } + + + + static int timer = NgProfiler::CreateTimer ("MeshSmoothing 2D"); + NgProfiler::RegionTimer reg (timer); + + + + CheckMeshApproximation (mesh); + + int i, j, k; + SurfaceElementIndex sei; + + Array seia; + mesh.GetSurfaceElementsOfFace (faceindex, seia); + + bool mixed = 0; + for (i = 0; i < seia.Size(); i++) + if (mesh[seia[i]].GetNP() != 3) + { + mixed = 1; + break; + } + + + int loci; + double fact; + bool moveisok; + + PointGeomInfo ngi; + Point<3> origp; + + Vector x(3); + + Array savepoints(mesh.GetNP()); + + Array nelementsonpoint(mesh.GetNP()); + nelementsonpoint = 0; + + for (i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (j = 0; j < el.GetNP(); j++) + nelementsonpoint[el[j]]++; + } + + + TABLE elementsonpoint(nelementsonpoint); + for (i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (j = 0; j < el.GetNP(); j++) + elementsonpoint.Add (el[j], seia[i]); + } + + + JacobianPointFunction pf(mesh.Points(),mesh.VolumeElements()); + + + +// Opti2SurfaceMinFunction surfminf(mesh); +// Opti2EdgeMinFunction edgeminf(mesh); +// Opti2SurfaceMinFunctionJacobian surfminfj(mesh); + + OptiParameters par; + par.maxit_linsearch = 8; + par.maxit_bfgs = 5; + + int np = mesh.GetNP(); + int ne = mesh.GetNE(); + + BitArray badnodes(np); + badnodes.Clear(); + + for (i = 1; i <= ne; i++) + { + const Element & el = mesh.VolumeElement(i); + double bad = el.CalcJacobianBadness (mesh.Points()); + if (bad > 1) + for (j = 1; j <= el.GetNP(); j++) + badnodes.Set (el.PNum(j)); + } + + + bool printeddot = 0; + char plotchar = '.'; + int modplot = 1; + if (mesh.GetNP() > 1000) + { + plotchar = '+'; + modplot = 10; + } + if (mesh.GetNP() > 10000) + { + plotchar = 'o'; + modplot = 100; + } + int cnt = 0; + + + Array locelements(0); + Array locrots(0); + + for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++) + { + if (mesh[pi].Type() != SURFACEPOINT) + continue; + + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + int surfi(-1); + + if(elementsonpoint[pi].Size() == 0) + continue; + + Element2d & hel = mesh[elementsonpoint[pi][0]]; + + if(hel.GetIndex() != faceindex) + continue; + + cnt++; + if (cnt % modplot == 0 && writestatus) + { + printeddot = 1; + PrintDot (plotchar); + } + + + int hpi = 0; + for (j = 1; j <= hel.GetNP(); j++) + if (hel.PNum(j) == pi) + { + hpi = j; + break; + } + PointGeomInfo gi1 = hel.GeomInfoPi(hpi); + + locelements.SetSize(0); + locrots.SetSize (0); + + for (j = 0; j < elementsonpoint[pi].Size(); j++) + { + sei = elementsonpoint[pi][j]; + const Element2d & bel = mesh[sei]; + surfi = mesh.GetFaceDescriptor(bel.GetIndex()).SurfNr(); + + locelements.Append (sei); + + for (k = 1; k <= bel.GetNP(); k++) + if (bel.PNum(k) == pi) + { + locrots.Append (k); + break; + } + } + + + double lh = mesh.GetH(mesh.Point(pi)); + par.typx = lh; + + pf.SetPointIndex(pi); + + x = 0; + bool pok = (pf.Func (x) < 1e10); + + if (pok) + { + BFGS (x, pf, par); + + origp = mesh[pi]; + loci = 1; + fact = 1; + moveisok = false; + + + //optimizer loop (if whole distance is not possible, move only a bit!!!!) + while (loci <= 5 && !moveisok) + { + loci ++; + mesh[pi](0) = origp(0) + x(0)*fact; + mesh[pi](1) = origp(1) + x(1)*fact; + mesh[pi](2) = origp(2) + x(2)*fact; + fact = fact/2.; + + + //cout << "origp " << origp << " newp " << mesh[pi]; + + ngi = gi1; + moveisok = (ProjectPointGI (surfi, mesh[pi], ngi) != 0); + + //cout << " projected " << mesh[pi] << endl; + + // point lies on same chart in stlsurface + + if (moveisok) + { + for (j = 0; j < locelements.Size(); j++) + mesh[locelements[j]].GeomInfoPi(locrots[j]) = ngi; + + //cout << "moved " << origp << " to " << mesh[pi] << endl; + } + else + { + mesh[pi] = origp; + } + + } + } + else + { + cout << "el not ok (point " << pi << ": " << mesh[pi] << ")" << endl; + } + } + + if (printeddot) + PrintDot ('\n'); + + CheckMeshApproximation (mesh); + mesh.SetNextTimeStamp(); + } + + +} diff --git a/libsrc/meshing/smoothing2.cpp b/libsrc/meshing/smoothing2.cpp new file mode 100644 index 00000000..61a964e0 --- /dev/null +++ b/libsrc/meshing/smoothing2.cpp @@ -0,0 +1,1102 @@ +#include + +#include "meshing.hpp" +#include + +namespace netgen +{ + + static const double c_trig = 0.14433756; // sqrt(3.0) / 12 + static const double c_trig4 = 0.57735026; // sqrt(3.0) / 3 + + + inline double CalcTriangleBadness (double x2, double x3, double y3, + double metricweight, double h) + { + // badness = sqrt(3.0) / 12 * (\sum l_i^2) / area - 1 + // p1 = (0, 0), p2 = (x2, 0), p3 = (x3, y3); + + double cir_2 = (x2*x2 + x3*x3 + y3*y3 - x2*x3); + double area = x2 * y3; + + if (area <= 1e-24 * cir_2) + return 1e10; + + double badness = c_trig4 * cir_2 / area - 1; + + if (metricweight > 0) + { + // add: metricweight * (area / h^2 + h^2 / area - 2) + + double areahh = area / (h * h); + badness += metricweight * (areahh + 1 / areahh - 2); + } + return badness; + } + + inline void CalcTriangleBadness (double x2, double x3, double y3, double metricweight, + double h, double & badness, double & g1x, double & g1y) + { + // old: badness = sqrt(3.0) /36 * circumference^2 / area - 1 + // badness = sqrt(3.0) / 12 * (\sum l_i^2) / area - 1 + // p1 = (0, 0), p2 = (x2, 0), p3 = (x3, y3); + + + double cir_2 = 2* (x2*x2 + x3*x3 + y3*y3 - x2*x3); + double area = 0.5 * x2 * y3; + + if (area <= 1e-24 * cir_2) + { + g1x = 0; + g1y = 0; + badness = 1e10; + return; + } + + badness = c_trig * cir_2 / area - 1; + + double c1 = -2 * c_trig / area; + double c2 = 0.5 * c_trig * cir_2 / (area * area); + g1x = c1 * (x2 + x3) + c2 * y3; + g1y = c1 * (y3) + c2 * (x2-x3); + + if (metricweight > 0) + { + // area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1); + // add: metricweight * (area / h^2 + h^2 / area - 2) + + area = x2 * y3; + double dareax1 = -y3; + double dareay1 = x3 - x2; + + double areahh = area / (h * h); + double fac = metricweight * (areahh - 1 / areahh) / area; + + badness += metricweight * (areahh + 1 / areahh - 2); + g1x += fac * dareax1; + g1y += fac * dareay1; + } + } + + + + double CalcTriangleBadness (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + double metricweight, + double h) + { + // badness = sqrt(3.0) / 12 * (\sum l_i^2) / area - 1 + + Vec<3> e12 = p2-p1; + Vec<3> e13 = p3-p1; + Vec<3> e23 = p3-p2; + + double cir_2 = e12.Length2() + e13.Length2() + e23.Length2(); + double area = 0.5 * Cross (e12, e13).Length(); + + if (area <= 1e-24 * cir_2) + return 1e10; + + double badness = c_trig * cir_2 / area - 1; + + if (metricweight > 0) + { + // add: metricweight * (area / h^2 + h^2 / area - 2) + area *= 2; // optimum for (2 area) is h^2 + double areahh = area / (h * h); + badness += metricweight * (areahh + 1 / areahh - 2); + } + + return badness; + } + + double CalcTriangleBadnessGrad (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + Vec<3> & gradp1, + double metricweight, + double h) + { + // badness = sqrt(3.0) / 12 * (\sum l_i^2) / area - 1 + + Vec<3> e12 = p2-p1; + Vec<3> e13 = p3-p1; + Vec<3> e23 = p3-p2; + + double cir_2 = e12.Length2() + e13.Length2() + e23.Length2(); + Vec<3> varea = Cross(e12, e13); + double area = 0.5 * varea.Length(); + + Vec<3> dcir_2 = (-2) * (e12+e13); + Vec<3> darea = (0.25/area) * Cross (p2-p3, varea); + + if (area <= 1e-24 * cir_2) + { + gradp1 = 0; + return 1e10; + } + + double badness = c_trig * cir_2 / area - 1; + gradp1 = c_trig * (1.0/area * dcir_2 - cir_2 / (area*area) * darea); + + if (metricweight > 0) + { + // add: metricweight * (area / h^2 + h^2 / area - 2) + area *= 2; // optimum for (2 area) is h^2 + + double areahh = area / (h * h); + badness += metricweight * (areahh + 1 / areahh - 2); + + gradp1 += (2*metricweight * (1/(h*h) - (h*h)/(area*area))) * darea; + } + + return badness; + } + + + + + double CalcTriangleBadness (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + const Vec<3> & n, + double metricweight, + double h) + { + Vec<3> v1 = p2-p1; + Vec<3> v2 = p3-p1; + + Vec<3> e1 = v1; + Vec<3> e2 = v2; + + e1 -= (e1 * n) * n; + e1 /= (e1.Length() + 1e-24); + e2 = Cross (n, e1); + + return CalcTriangleBadness ( (e1 * v1), (e1 * v2), (e2 * v2), + metricweight, h); + } + + + class Opti2dLocalData + { + public: + const MeshOptimize2d * meshthis; + MeshPoint sp1; + PointGeomInfo gi1; + Vec<3> normal, t1, t2; + Array locelements; + Array locrots; + Array lochs; + Array > loc_pnts2, loc_pnts3; + // static int locerr2; + double locmetricweight; + double loch; + int surfi, surfi2; + int uselocalh; + public: + Opti2dLocalData () + { + locmetricweight = 0; + } + }; + + + class Opti2SurfaceMinFunction : public MinFunction + { + const Mesh & mesh; + Opti2dLocalData & ld; + public: + Opti2SurfaceMinFunction (const Mesh & amesh, + Opti2dLocalData & ald) + : mesh(amesh), ld(ald) + { } ; + + + virtual double Func (const Vector & x) const + { + Vec<3> n; + + double badness = 0; + + ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n); + Point<3> pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2; + + for (int j = 0; j < ld.locelements.Size(); j++) + { + Vec<3> e1 = ld.loc_pnts2[j] - pp1; + Vec<3> e2 = ld.loc_pnts3[j] - pp1; + + if (ld.uselocalh) ld.loch = ld.lochs[j]; + + if (Determinant(e1, e2, n) > 1e-8 * ld.loch * ld.loch) + { + badness += CalcTriangleBadness (pp1, ld.loc_pnts2[j], ld.loc_pnts3[j], + ld.locmetricweight, ld.loch); + } + else + { + badness += 1e8; + } + } + + return badness; + } + + + virtual double FuncGrad (const Vector & x, Vector & g) const + { + Vec<3> vgrad; + Point<3> pp1; + + vgrad = 0; + double badness = 0; + + pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2; + + for (int j = 0; j < ld.locelements.Size(); j++) + { + Vec<3> e1 = ld.loc_pnts2[j] - pp1; + Vec<3> e2 = ld.loc_pnts3[j] - pp1; + + if (ld.uselocalh) ld.loch = ld.lochs[j]; + + if (Determinant(e1, e2, ld.normal) > 1e-8 * ld.loch * ld.loch) + { + Vec<3> hgrad; + badness += + CalcTriangleBadnessGrad (pp1, ld.loc_pnts2[j], ld.loc_pnts3[j], hgrad, + ld.locmetricweight, ld.loch); + vgrad += hgrad; + } + else + { + badness += 1e8; + } + } + g(0) = ld.t1 * vgrad; + g(1) = ld.t2 * vgrad; + return badness; + } + + virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const + { + deriv = 0; + double badness = 0; + + Point<3> pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2; + Vec<3> dir3d = dir(0) * ld.t1 + dir(1) * ld.t2; + + for (int j = 0; j < ld.locelements.Size(); j++) + { + Vec<3> e1 = ld.loc_pnts2[j] - pp1; + Vec<3> e2 = ld.loc_pnts3[j] - pp1; + + if (ld.uselocalh) ld.loch = ld.lochs[j]; + + if (Determinant(e1, e2, ld.normal) > 1e-8 * ld.loch * ld.loch) + { + Vec<3> hgrad; + badness += + CalcTriangleBadnessGrad (pp1, ld.loc_pnts2[j], ld.loc_pnts3[j], hgrad, + ld.locmetricweight, ld.loch); + deriv += dir3d * hgrad; + } + else + { + badness += 1e8; + } + } + + // cout << "deriv = " << deriv << " =?= "; + return badness; + /* + static int timer = NgProfiler::CreateTimer ("opti2surface - deriv"); + NgProfiler::RegionTimer reg (timer); + + double eps = 1e-6; + Vector xr(2), xl(2); + xr = x; xl = x; + for (int i = 0; i < 2; i++) + { + xr(i) = x(i) + eps * dir(i); + xl(i) = x(i) - eps * dir(i); + } + deriv = (Func (xr) - Func(xl) ) / (2*eps); + cout << deriv << endl; + return Func(x); + */ + } + + + + virtual double XXFuncGrad (const Vector & x, Vector & g) const; + virtual double XXFuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; + + }; + + + /* + double Opti2SurfaceMinFunction :: + Func (const Vector & x) const + { + static int timer = NgProfiler::CreateTimer ("opti2surface - func"); + NgProfiler::RegionTimer reg (timer); + + Vector g(x.Size()); + return FuncGrad (x, g); + } + */ + + double Opti2SurfaceMinFunction :: + XXFuncGrad (const Vector & x, Vector & grad) const + { + // static int timer = NgProfiler::CreateTimer ("opti2surface - funcgrad"); + // NgProfiler::RegionTimer reg (timer); + + Vec<3> n, vgrad; + Point<3> pp1; + + vgrad = 0; + double badness = 0; + + ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n); + pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2; + + // meshthis -> ProjectPoint (surfi, pp1); + // meshthis -> GetNormalVector (surfi, pp1, n); + + for (int j = 0; j < ld.locelements.Size(); j++) + { + double g1x, g1y, hbadness; + + Vec<3> e1 = ld.loc_pnts2[j] - pp1; + Vec<3> e2 = ld.loc_pnts3[j] - pp1; + + if (ld.uselocalh) ld.loch = ld.lochs[j]; + + double e1l = e1.Length(); + if (Determinant(e1, e2, n) > 1e-8 * e1l * e2.Length()) + { + e1 /= e1l; + double e1e2 = e1 * e2; + e2 -= e1e2 * e1; + double e2l = e2.Length(); + + CalcTriangleBadness ( e1l, e1e2, e2l, ld.locmetricweight, ld.loch, + hbadness, g1x, g1y); + + badness += hbadness; + vgrad += g1x * e1 + (g1y/e2l) * e2; + } + else + { + // (*testout) << "very very bad badness" << endl; + badness += 1e8; + } + } + + // vgrad -= (vgrad * n) * n; + grad(0) = vgrad * ld.t1; + grad(1) = vgrad * ld.t2; + return badness; + } + + + double Opti2SurfaceMinFunction :: + XXFuncDeriv (const Vector & x, const Vector & dir, double & deriv) const + { + // static int timer = NgProfiler::CreateTimer ("opti2surface - funcderiv"); + // NgProfiler::RegionTimer reg (timer); + + Vec<3> n, vgrad; + Point<3> pp1; + + vgrad = 0; + double badness = 0; + + ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n); + pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2; + + for (int j = 0; j < ld.locelements.Size(); j++) + { + double g1x, g1y, hbadness; + + /* + int roti = ld.locrots[j]; + const Element2d & bel = mesh[ld.locelements[j]]; + Vec<3> e1 = mesh[bel.PNumMod(roti + 1)] - pp1; + Vec<3> e2 = mesh[bel.PNumMod(roti + 2)] - pp1; + */ + Vec<3> e1 = ld.loc_pnts2[j] - pp1; + Vec<3> e2 = ld.loc_pnts3[j] - pp1; + if (ld.uselocalh) ld.loch = ld.lochs[j]; + + double e1l = e1.Length(); + if (Determinant(e1, e2, n) > 1e-8 * e1l * e2.Length()) + { + e1 /= e1l; + double e1e2 = e1 * e2; + e2 -= e1e2 * e1; + double e2l = e2.Length(); + CalcTriangleBadness ( e1l, e1e2, e2l, ld.locmetricweight, ld.loch, + hbadness, g1x, g1y); + + badness += hbadness; + vgrad += g1x * e1 + (g1y / e2l) * e2; + } + else + { + // (*testout) << "very very bad badness" << endl; + badness += 1e8; + } + } + + // vgrad -= (vgrad * n) * n; + deriv = dir(0) * (vgrad*ld.t1) + dir(1) * (vgrad*ld.t2); + + return badness; + } + + + + + + + + + + + + + class Opti2EdgeMinFunction : public MinFunction + { + const Mesh & mesh; + Opti2dLocalData & ld; + + public: + Opti2EdgeMinFunction (const Mesh & amesh, + Opti2dLocalData & ald) + : mesh(amesh), ld(ald) { } ; + + virtual double FuncGrad (const Vector & x, Vector & g) const; + virtual double Func (const Vector & x) const; + }; + + double Opti2EdgeMinFunction :: Func (const Vector & x) const + { + Vector g(x.Size()); + return FuncGrad (x, g); + } + + double Opti2EdgeMinFunction :: FuncGrad (const Vector & x, Vector & grad) const + { + int j, rot; + Vec<3> n1, n2, v1, v2, e1, e2, vgrad; + Point<3> pp1; + Vec<2> g1; + double badness, hbadness; + + vgrad = 0.0; + badness = 0; + + pp1 = ld.sp1 + x(0) * ld.t1; + ld.meshthis -> ProjectPoint2 (ld.surfi, ld.surfi2, pp1); + + for (j = 0; j < ld.locelements.Size(); j++) + { + rot = ld.locrots[j]; + const Element2d & bel = mesh[ld.locelements[j]]; + + v1 = mesh[bel.PNumMod(rot + 1)] - pp1; + v2 = mesh[bel.PNumMod(rot + 2)] - pp1; + + e1 = v1; + e2 = v2; + e1 /= e1.Length(); + e2 -= (e1 * e2) * e1; + e2 /= e2.Length(); + + if (ld.uselocalh) ld.loch = ld.lochs[j]; + CalcTriangleBadness ( (e1 * v1), (e1 * v2), (e2 * v2), ld.locmetricweight, ld.loch, + hbadness, g1(0), g1(1)); + + badness += hbadness; + vgrad += g1(0) * e1 + g1(1) * e2; + } + + ld.meshthis -> GetNormalVector (ld.surfi, pp1, n1); + ld.meshthis -> GetNormalVector (ld.surfi2, pp1, n2); + + v1 = Cross (n1, n2); + v1.Normalize(); + + grad(0) = (vgrad * v1) * (ld.t1 * v1); + + return badness; + } + + + + + class Opti2SurfaceMinFunctionJacobian : public MinFunction + { + const Mesh & mesh; + Opti2dLocalData & ld; + + public: + Opti2SurfaceMinFunctionJacobian (const Mesh & amesh, + Opti2dLocalData & ald) + : mesh(amesh), ld(ald) + { } ; + virtual double FuncGrad (const Vector & x, Vector & g) const; + virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; + virtual double Func (const Vector & x) const; + }; + + double Opti2SurfaceMinFunctionJacobian :: + Func (const Vector & x) const + { + Vector g(x.Size()); + return FuncGrad (x, g); + } + + + double Opti2SurfaceMinFunctionJacobian :: + FuncGrad (const Vector & x, Vector & grad) const + { + // from 2d: + + int lpi, gpi; + Vec<3> n, vgrad; + Point<3> pp1; + Vec2d g1, vdir; + double badness, hbad, hderiv; + + vgrad = 0; + badness = 0; + + ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n); + + pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2; + + // meshthis -> ProjectPoint (surfi, pp1); + // meshthis -> GetNormalVector (surfi, pp1, n); + + static Array pts2d; + pts2d.SetSize(mesh.GetNP()); + + grad = 0; + + for (int j = 1; j <= ld.locelements.Size(); j++) + { + lpi = ld.locrots.Get(j); + const Element2d & bel = + mesh[ld.locelements.Get(j)]; + + gpi = bel.PNum(lpi); + + for (int k = 1; k <= bel.GetNP(); k++) + { + PointIndex pi = bel.PNum(k); + pts2d.Elem(pi) = Point2d (ld.t1 * (mesh.Point(pi) - ld.sp1), + ld.t2 * (mesh.Point(pi) - ld.sp1)); + } + pts2d.Elem(gpi) = Point2d (x(0), x(1)); + + + for (int k = 1; k <= 2; k++) + { + if (k == 1) + vdir = Vec2d (1, 0); + else + vdir = Vec2d (0, 1); + + hbad = bel. + CalcJacobianBadnessDirDeriv (pts2d, lpi, vdir, hderiv); + + grad(k-1) += hderiv; + if (k == 1) + badness += hbad; + } + } + + + /* + vgrad.Add (-(vgrad * n), n); + + grad.Elem(1) = vgrad * t1; + grad.Elem(2) = vgrad * t2; + */ + return badness; + } + + + + + double Opti2SurfaceMinFunctionJacobian :: + FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const + { + // from 2d: + + int j, k, lpi, gpi; + Vec<3> n, vgrad; + Point<3> pp1; + Vec2d g1, vdir; + double badness, hbad, hderiv; + + vgrad = 0; + badness = 0; + + ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n); + + // pp1 = sp1; + // pp1.Add2 (x.Get(1), t1, x.Get(2), t2); + pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2; + + static Array pts2d; + pts2d.SetSize(mesh.GetNP()); + + deriv = 0; + + for (j = 1; j <= ld.locelements.Size(); j++) + { + lpi = ld.locrots.Get(j); + const Element2d & bel = + mesh[ld.locelements.Get(j)]; + + gpi = bel.PNum(lpi); + + for (k = 1; k <= bel.GetNP(); k++) + { + PointIndex pi = bel.PNum(k); + pts2d.Elem(pi) = Point2d (ld.t1 * (mesh.Point(pi) - ld.sp1), + ld.t2 * (mesh.Point(pi) - ld.sp1)); + } + pts2d.Elem(gpi) = Point2d (x(0), x(1)); + + + vdir = Vec2d (dir(0), dir(1)); + + hbad = bel. + CalcJacobianBadnessDirDeriv (pts2d, lpi, vdir, hderiv); + + deriv += hderiv; + badness += hbad; + } + + + return badness; + } + + + + + + + + MeshOptimize2d dummy; + + MeshOptimize2d :: MeshOptimize2d () + { + SetFaceIndex (0); + SetImproveEdges (0); + SetMetricWeight (0); + SetWriteStatus (1); + } + + + void MeshOptimize2d :: SelectSurfaceOfPoint (const Point<3> & p, + const PointGeomInfo & gi) + { + ; + } + + void MeshOptimize2d :: ImproveMesh (Mesh & mesh, const MeshingParameters & mp) + { + if (!faceindex) + { + PrintMessage (3, "Smoothing"); + + for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) + { + ImproveMesh (mesh, mp); + if (multithread.terminate) + throw NgException ("Meshing stopped"); + } + faceindex = 0; + return; + } + + static int timer = NgProfiler::CreateTimer ("MeshSmoothing 2D"); + static int timer1 = NgProfiler::CreateTimer ("MeshSmoothing 2D start"); + static int timer2 = NgProfiler::CreateTimer ("MeshSmoothing 2D - BFGS"); + + NgProfiler::RegionTimer reg (timer); + NgProfiler::StartTimer (timer1); + + CheckMeshApproximation (mesh); + + Opti2dLocalData ld; + + + Array seia; + mesh.GetSurfaceElementsOfFace (faceindex, seia); + + bool mixed = 0; + for (int i = 0; i < seia.Size(); i++) + if (mesh[seia[i]].GetNP() != 3) + { + mixed = 1; + break; + } + + Vector x(2); + + Array savepoints(mesh.GetNP()); + + ld.uselocalh = mp.uselocalh; + + Array compress(mesh.GetNP()); + Array icompress; + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + compress[el[j]] = -1; + } + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + if (compress[el[j]] == -1) + { + compress[el[j]] = icompress.Size(); + icompress.Append(el[j]); + } + } + Array cnta(icompress.Size()); + cnta = 0; + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + cnta[compress[el[j]]]++; + } + TABLE elementsonpoint(cnta); + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + elementsonpoint.Add (compress[el[j]], seia[i]); + } + + + /* + Array nelementsonpoint(mesh.GetNP()); + nelementsonpoint = 0; + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + nelementsonpoint[el[j]]++; + } + + TABLE elementsonpoint(nelementsonpoint); + + for (int i = 0; i < seia.Size(); i++) + { + const Element2d & el = mesh[seia[i]]; + for (int j = 0; j < el.GetNP(); j++) + elementsonpoint.Add (el[j], seia[i]); + } + */ + + + + ld.loch = mp.maxh; + ld.locmetricweight = metricweight; + ld.meshthis = this; + + + + Opti2SurfaceMinFunction surfminf(mesh, ld); + Opti2EdgeMinFunction edgeminf(mesh, ld); + Opti2SurfaceMinFunctionJacobian surfminfj(mesh, ld); + + OptiParameters par; + par.maxit_linsearch = 8; + par.maxit_bfgs = 5; + + /* + int i, j, k; + Vector xedge(1); + if (improveedges) + for (i = 1; i <= mesh.GetNP(); i++) + if (mesh.PointType(i) == EDGEPOINT) + { + continue; + PrintDot (); + sp1 = mesh.Point(i); + + locelements.SetSize(0); + locrots.SetSize (0); + lochs.SetSize (0); + surfi = surfi2 = surfi3 = 0; + + for (j = 0; j < elementsonpoint[i].Size(); j++) + { + sei = elementsonpoint[i][j]; + const Element2d * bel = &mesh[sei]; + + if (!surfi) + surfi = mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr(); + else if (surfi != mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr()) + { + if (surfi2 != 0 && surfi2 != + mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr()) + surfi3 = mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr(); + else + surfi2 = mesh.GetFaceDescriptor(bel->GetIndex()).SurfNr(); + } + + locelements.Append (sei); + + if (bel->PNum(1) == i) + locrots.Append (1); + else if (bel->PNum(2) == i) + locrots.Append (2); + else + locrots.Append (3); + + if (uselocalh) + { + Point3d pmid = Center (mesh.Point(bel->PNum(1)), + mesh.Point(bel->PNum(2)), + mesh.Point(bel->PNum(3))); + lochs.Append (mesh.GetH(pmid)); + } + } + + if (surfi2 && !surfi3) + { + Vec3d n1, n2; + GetNormalVector (surfi, sp1, n1); + GetNormalVector (surfi2, sp1, n2); + t1 = Cross (n1, n2); + + xedge = 0; + BFGS (xedge, edgeminf, par, 1e-6); + + mesh.Point(i).X() += xedge.Get(1) * t1.X(); + mesh.Point(i).Y() += xedge.Get(1) * t1.Y(); + mesh.Point(i).Z() += xedge.Get(1) * t1.Z(); + ProjectPoint2 (surfi, surfi2, mesh.Point(i)); + } + } + */ + + + bool printeddot = 0; + char plotchar = '.'; + int modplot = 1; + if (mesh.GetNP() > 1000) + { + plotchar = '+'; + modplot = 100; + } + if (mesh.GetNP() > 10000) + { + plotchar = 'o'; + modplot = 1000; + } + if (mesh.GetNP() > 100000) + { + plotchar = 'O'; + modplot = 10000; + } + int cnt = 0; + + + NgProfiler::StopTimer (timer1); + + /* + for (PointIndex pi = PointIndex::BASE; pi < mesh.GetNP()+PointIndex::BASE; pi++) + if (mesh[pi].Type() == SURFACEPOINT) + */ + for (int hi = 0; hi < icompress.Size(); hi++) + { + PointIndex pi = icompress[hi]; + if (mesh[pi].Type() == SURFACEPOINT) + { + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + cnt++; + if (cnt % modplot == 0 && writestatus) + { + printeddot = 1; + PrintDot (plotchar); + } + + // if (elementsonpoint[pi].Size() == 0) continue; + if (elementsonpoint[hi].Size() == 0) continue; + + ld.sp1 = mesh[pi]; + + // Element2d & hel = mesh[elementsonpoint[pi][0]]; + Element2d & hel = mesh[elementsonpoint[hi][0]]; + + int hpi = 0; + for (int j = 1; j <= hel.GetNP(); j++) + if (hel.PNum(j) == pi) + { + hpi = j; + break; + } + + ld.gi1 = hel.GeomInfoPi(hpi); + SelectSurfaceOfPoint (ld.sp1, ld.gi1); + + ld.locelements.SetSize(0); + ld.locrots.SetSize (0); + ld.lochs.SetSize (0); + ld.loc_pnts2.SetSize (0); + ld.loc_pnts3.SetSize (0); + + for (int j = 0; j < elementsonpoint[hi].Size(); j++) + { + SurfaceElementIndex sei = elementsonpoint[hi][j]; + const Element2d & bel = mesh[sei]; + ld.surfi = mesh.GetFaceDescriptor(bel.GetIndex()).SurfNr(); + + ld.locelements.Append (sei); + + for (int k = 1; k <= bel.GetNP(); k++) + if (bel.PNum(k) == pi) + { + ld.locrots.Append (k); + ld.loc_pnts2.Append (mesh[bel.PNumMod(k + 1)]); + ld.loc_pnts3.Append (mesh[bel.PNumMod(k + 2)]); + break; + } + + if (ld.uselocalh) + { + Point3d pmid = Center (mesh[bel[0]], mesh[bel[1]], mesh[bel[2]]); + ld.lochs.Append (mesh.GetH(pmid)); + } + } + + GetNormalVector (ld.surfi, ld.sp1, ld.gi1, ld.normal); + ld.t1 = ld.normal.GetNormal (); + ld.t2 = Cross (ld.normal, ld.t1); + + // save points, and project to tangential plane + for (int j = 0; j < ld.locelements.Size(); j++) + { + const Element2d & el = mesh[ld.locelements[j]]; + for (int k = 0; k < el.GetNP(); k++) + savepoints[el[k]] = mesh[el[k]]; + } + + for (int j = 0; j < ld.locelements.Size(); j++) + { + const Element2d & el = mesh[ld.locelements[j]]; + for (int k = 0; k < el.GetNP(); k++) + { + PointIndex hhpi = el[k]; + double lam = ld.normal * (mesh[hhpi] - ld.sp1); + mesh[hhpi] -= lam * ld.normal; + } + } + + x = 0; + par.typx = 0.3*ld.lochs[0]; + + NgProfiler::StartTimer (timer2); + + if (mixed) + { + BFGS (x, surfminfj, par, 1e-6); + } + else + { + BFGS (x, surfminf, par, 1e-6); + } + + NgProfiler::StopTimer (timer2); + + Point3d origp = mesh[pi]; + int loci = 1; + double fact = 1; + int moveisok = 0; + + // restore other points + for (int j = 0; j < ld.locelements.Size(); j++) + { + const Element2d & el = mesh[ld.locelements[j]]; + for (int k = 0; k < el.GetNP(); k++) + { + PointIndex hhpi = el[k]; + if (hhpi != pi) mesh[hhpi] = savepoints[hhpi]; + } + } + + + //optimizer loop (if whole distance is not possible, move only a bit!!!!) + while (loci <= 5 && !moveisok) + { + loci ++; + /* + mesh[pi].X() = origp.X() + (x.Get(1) * t1.X() + x.Get(2) * t2.X())*fact; + mesh[pi].Y() = origp.Y() + (x.Get(1) * t1.Y() + x.Get(2) * t2.Y())*fact; + mesh[pi].Z() = origp.Z() + (x.Get(1) * t1.Z() + x.Get(2) * t2.Z())*fact; + */ + Vec<3> hv = x(0) * ld.t1 + x(1) * ld.t2; + Point3d hnp = origp + Vec3d (hv); + mesh[pi](0) = hnp.X(); + mesh[pi](1) = hnp.Y(); + mesh[pi](2) = hnp.Z(); + + fact = fact/2.; + + // ProjectPoint (surfi, mesh[pi]); + // moveisok = CalcPointGeomInfo(surfi, ngi, mesh[pi]); + + PointGeomInfo ngi; + ngi = ld.gi1; + moveisok = ProjectPointGI (ld.surfi, mesh[pi], ngi); + // point lies on same chart in stlsurface + + if (moveisok) + { + for (int j = 0; j < ld.locelements.Size(); j++) + mesh[ld.locelements[j]].GeomInfoPi(ld.locrots[j]) = ngi; + } + else + { + mesh[pi] = Point<3> (origp); + } + + } + } + } + if (printeddot) + PrintDot ('\n'); + + CheckMeshApproximation (mesh); + mesh.SetNextTimeStamp(); + } + + void MeshOptimize2d :: GetNormalVector(INDEX /* surfind */, const Point<3> & p, Vec<3> & nv) const + { + nv = Vec<3> (0, 0, 1); + } + + void MeshOptimize2d :: GetNormalVector(INDEX surfind, const Point<3> & p, PointGeomInfo & gi, Vec<3> & n) const + { + GetNormalVector (surfind, p, n); + } +} diff --git a/libsrc/meshing/smoothing3.cpp b/libsrc/meshing/smoothing3.cpp new file mode 100644 index 00000000..24f1ef71 --- /dev/null +++ b/libsrc/meshing/smoothing3.cpp @@ -0,0 +1,1837 @@ +#include + +#include "meshing.hpp" +#ifdef SOLIDGEOM +#include +#endif +#include + + +namespace netgen +{ + + + double MinFunctionSum :: Func (const Vector & x) const + { + double retval = 0; + for(int i=0; iFunc(x); + + return retval; + } + + void MinFunctionSum :: Grad (const Vector & x, Vector & g) const + { + g = 0.; + VectorMem<3> gi; + for(int i=0; iGrad(x,gi); + for(int j=0; j gi; + for(int i=0; iFuncGrad(x,gi); + for(int j=0; jFuncDeriv(x,dir,derivi); + deriv += derivi; + } + return retval; + } + + double MinFunctionSum :: GradStopping (const Vector & x) const + { + double minfs(0), mini; + for(int i=0; iGradStopping(x); + if(i==0 || mini < minfs) + minfs = mini; + } + return minfs; + } + + + void MinFunctionSum :: AddFunction(MinFunction & fun) + { + functions.Append(&fun); + } + + const MinFunction & MinFunctionSum :: Function(int i) const + { + return *functions[i]; + } + MinFunction & MinFunctionSum :: Function(int i) + { + return *functions[i]; + } + + PointFunction1 :: PointFunction1 (Mesh::T_POINTS & apoints, + const Array & afaces, + const MeshingParameters & amp, + double ah) + : points(apoints), faces(afaces), mp(amp) + { + h = ah; + } + + + double PointFunction1 :: Func (const Vector & vp) const + { + double badness = 0; + Point<3> pp(vp(0), vp(1), vp(2)); + + for (int j = 0; j < faces.Size(); j++) + { + const INDEX_3 & el = faces[j]; + + double bad = CalcTetBadness (points[PointIndex (el.I1())], + points[PointIndex (el.I3())], + points[PointIndex (el.I2())], + pp, 0, mp); + badness += bad; + } + + return badness; + } + + + double PointFunction1 :: + FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const + { + VectorMem<3> hx; + const double eps = 1e-6; + + double dirlen = dir.L2Norm(); + if (dirlen < 1e-14) + { + deriv = 0; + return Func(x); + } + + hx.Set(1, x); + hx.Add(eps * h / dirlen, dir); + double fr = Func (hx); + hx.Set(1, x); + hx.Add(-eps * h / dirlen, dir); + double fl = Func (hx); + + deriv = (fr - fl) / (2 * eps * h) * dirlen; + + return Func(x); + } + + + double PointFunction1 :: FuncGrad (const Vector & x, Vector & g) const + { + VectorMem<3> hx; + double eps = 1e-6; + + hx = x; + for (int i = 0; i < 3; i++) + { + hx(i) = x(i) + eps * h; + double fr = Func (hx); + hx(i) = x(i) - eps * h; + double fl = Func (hx); + hx(i) = x(i); + + g(i) = (fr - fl) / (2 * eps * h); + } + + return Func(x); + } + + double PointFunction1 :: GradStopping (const Vector & x) const + { + double f = Func(x); + return 1e-8 * f * f; + } + + + /* Cheap Functional depending of inner point inside triangular surface */ + + // is it used ???? + class CheapPointFunction1 : public MinFunction + { + Mesh::T_POINTS & points; + const Array & faces; + DenseMatrix m; + double h; + public: + CheapPointFunction1 (Mesh::T_POINTS & apoints, + const Array & afaces, + double ah); + + virtual double Func (const Vector & x) const; + virtual double FuncGrad (const Vector & x, Vector & g) const; + }; + + CheapPointFunction1 :: CheapPointFunction1 (Mesh::T_POINTS & apoints, + const Array & afaces, + double ah) + : points(apoints), faces(afaces) + { + h = ah; + + + int nf = faces.Size(); + + m.SetSize (nf, 4); + + for (int i = 1; i <= nf; i++) + { + const Point3d & p1 = points[PointIndex(faces.Get(i).I1())]; + const Point3d & p2 = points[PointIndex(faces.Get(i).I2())]; + const Point3d & p3 = points[PointIndex(faces.Get(i).I3())]; + Vec3d v1 (p1, p2); + Vec3d v2 (p1, p3); + Vec3d n; + Cross (v1, v2, n); + n /= n.Length(); + + m.Elem(i, 1) = n.X(); + m.Elem(i, 2) = n.Y(); + m.Elem(i, 3) = n.Z(); + m.Elem(i, 4) = - (n.X() * p1.X() + n.Y() * p1.Y() + n.Z() * p1.Z()); + } + } + + double CheapPointFunction1 :: Func (const Vector & vp) const + { + + /* + int j; + double badness = 0; + Point3d pp(vp.Get(1), vp.Get(2), vp.Get(3)); + + for (j = 1; j <= faces.Size(); j++) + { + const INDEX_3 & el = faces.Get(j); + + double bad = CalcTetBadness (points.Get(el.I1()), + points.Get(el.I3()), + points.Get(el.I2()), + pp, 0); + badness += bad; + } + */ + + int i; + double badness = 0; + VectorMem<4> hv; + Vector res(m.Height()); + + for (i = 0;i < 3; i++) + hv(i) = vp(i); + hv(3) = 1; + m.Mult (hv, res); + + for (i = 1; i <= res.Size(); i++) + { + if (res(i-1) < 1e-10) + badness += 1e24; + else + badness += 1 / res(i-1); + } + + return badness; + } + + + double CheapPointFunction1 :: FuncGrad (const Vector & x, Vector & g) const + { + VectorMem<3> hx; + double eps = 1e-6; + + hx = x; + for (int i = 0; i < 3; i++) + { + hx(i) = x(i) + eps * h; + double fr = Func (hx); + hx(i) = x(i) - eps * h; + double fl = Func (hx); + hx(i) = x(i); + + g(i) = (fr - fl) / (2 * eps * h); + } + + return Func(x); + } + + + + + + + + + + + + + + + /* ************* PointFunction **************************** */ + + + class PointFunction + { + public: + Mesh::T_POINTS & points; + const Mesh::T_VOLELEMENTS & elements; + TABLE elementsonpoint; + const MeshingParameters & mp; + PointIndex actpind; + double h; + + public: + PointFunction (Mesh::T_POINTS & apoints, + const Mesh::T_VOLELEMENTS & aelements, + const MeshingParameters & amp); + + virtual void SetPointIndex (PointIndex aactpind); + void SetLocalH (double ah) { h = ah; } + double GetLocalH () const { return h; } + virtual double PointFunctionValue (const Point<3> & pp) const; + virtual double PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const; + virtual double PointFunctionValueDeriv (const Point<3> & pp, const Vec<3> & dir, double & deriv) const; + + int MovePointToInner (); + }; + + + PointFunction :: PointFunction (Mesh::T_POINTS & apoints, + const Mesh::T_VOLELEMENTS & aelements, + const MeshingParameters & amp) + : points(apoints), elements(aelements), elementsonpoint(apoints.Size()), mp(amp) + { + for (int i = 0; i < elements.Size(); i++) + if (elements[i].NP() == 4) + for (int j = 0; j < elements[i].NP(); j++) + elementsonpoint.Add (elements[i][j], i); + } + + void PointFunction :: SetPointIndex (PointIndex aactpind) + { + actpind = aactpind; + } + + double PointFunction :: PointFunctionValue (const Point<3> & pp) const + { + double badness; + Point<3> hp; + + badness = 0; + + hp = points[actpind]; + points[actpind] = Point<3> (pp); + + for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + { + const Element & el = elements[elementsonpoint[actpind][j]]; + badness += CalcTetBadness (points[el[0]], points[el[1]], + points[el[2]], points[el[3]], -1, mp); + } + + points[actpind] = Point<3> (hp); + return badness; + } + + + double PointFunction :: PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const + { + double f = 0; + + Point<3> hp = points[actpind]; + Vec<3> vgradi, vgrad(0,0,0); + points[actpind] = Point<3> (pp); + + for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + { + const Element & el = elements[elementsonpoint[actpind][j]]; + for (int k = 0; k < 4; k++) + if (el[k] == actpind) + { + f += CalcTetBadnessGrad (points[el[0]], points[el[1]], + points[el[2]], points[el[3]], + -1, k+1, vgradi, mp); + + vgrad += vgradi; + } + } + + points[actpind] = Point<3> (hp); + + grad = vgrad; + return f; + } + + + double PointFunction :: PointFunctionValueDeriv (const Point<3> & pp, const Vec<3> & dir, + double & deriv) const + { + Vec<3> vgradi, vgrad(0,0,0); + + Point<3> hp = points[actpind]; + points[actpind] = pp; + double f = 0; + + for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + { + const Element & el = elements[elementsonpoint[actpind][j]]; + + for (int k = 1; k <= 4; k++) + if (el.PNum(k) == actpind) + { + f += CalcTetBadnessGrad (points[el.PNum(1)], + points[el.PNum(2)], + points[el.PNum(3)], + points[el.PNum(4)], -1, k, vgradi, mp); + + vgrad += vgradi; + } + } + + points[actpind] = Point<3> (hp); + deriv = dir * vgrad; + return f; + } + + int PointFunction :: MovePointToInner () + { + // try point movement + Array faces; + + for (int j = 0; j < elementsonpoint[actpind].Size(); j++) + { + const Element & el = + elements[elementsonpoint[actpind][j]]; + + for (int k = 1; k <= 4; k++) + if (el.PNum(k) == actpind) + { + Element2d face; + el.GetFace (k, face); + Swap (face.PNum(2), face.PNum(3)); + faces.Append (face); + } + } + + Point3d hp; + int hi = FindInnerPoint (points, faces, hp); + if (hi) + { + // cout << "inner point found" << endl; + points[actpind] = Point<3> (hp); + } + else + ; + // cout << "no inner point found" << endl; + + /* + Point3d hp2; + int hi2 = FindInnerPoint (points, faces, hp2); + if (hi2) + { + cout << "new: inner point found" << endl; + } + else + cout << "new: no inner point found" << endl; + + (*testout) << "hi(orig) = " << hi << ", hi(new) = " << hi2; + if (hi != hi2) (*testout) << "hi different" << endl; + */ + + return hi; + } + + + + + + + class CheapPointFunction : public PointFunction + { + DenseMatrix m; + public: + CheapPointFunction (Mesh::T_POINTS & apoints, + const Mesh::T_VOLELEMENTS & aelements, + const MeshingParameters & amp); + virtual void SetPointIndex (PointIndex aactpind); + virtual double PointFunctionValue (const Point<3> & pp) const; + virtual double PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const; + }; + + + CheapPointFunction :: CheapPointFunction (Mesh::T_POINTS & apoints, + const Mesh::T_VOLELEMENTS & aelements, + const MeshingParameters & amp) + : PointFunction (apoints, aelements, amp) + { + ; + } + + + void CheapPointFunction :: SetPointIndex (PointIndex aactpind) + { + actpind = aactpind; + + int ne = elementsonpoint[actpind].Size(); + int i, j; + PointIndex pi1, pi2, pi3; + + m.SetSize (ne, 4); + + for (i = 0; i < ne; i++) + { + pi1 = 0; + pi2 = 0; + pi3 = 0; + + const Element & el = elements[elementsonpoint[actpind][i]]; + for (j = 1; j <= 4; j++) + if (el.PNum(j) != actpind) + { + pi3 = pi2; + pi2 = pi1; + pi1 = el.PNum(j); + } + + const Point3d & p1 = points[pi1]; + Vec3d v1 (p1, points[pi2]); + Vec3d v2 (p1, points[pi3]); + Vec3d n; + Cross (v1, v2, n); + n /= n.Length(); + + Vec3d v (p1, points[actpind]); + double c = v * n; + + if (c < 0) + n *= -1; + + // n is inner normal + + m.Elem(i+1, 1) = n.X(); + m.Elem(i+1, 2) = n.Y(); + m.Elem(i+1, 3) = n.Z(); + m.Elem(i+1, 4) = - (n.X() * p1.X() + n.Y() * p1.Y() + n.Z() * p1.Z()); + } + } + + double CheapPointFunction :: PointFunctionValue (const Point<3> & pp) const + { + VectorMem<4> p4; + Vector di; + int n = m.Height(); + + p4(0) = pp(0); + p4(1) = pp(1); + p4(2) = pp(2); + p4(3) = 1; + + di.SetSize (n); + m.Mult (p4, di); + + double sum = 0; + for (int i = 0; i < n; i++) + { + if (di(i) > 0) + sum += 1 / di(i); + else + return 1e16; + } + return sum; + } + + + + + double CheapPointFunction :: PointFunctionValueGrad (const Point<3> & pp, Vec<3> & grad) const + { + VectorMem<4> p4; + Vector di; + + int n = m.Height(); + + p4(0) = pp(0); + p4(1) = pp(1); + p4(2) = pp(2); + p4(3) = 1; + + di.SetSize (n); + m.Mult (p4, di); + + double sum = 0; + grad = 0; + for (int i = 0; i < n; i++) + { + if (di(i) > 0) + { + double idi = 1 / di(i); + sum += idi; + grad(0) -= idi * idi * m(i, 0); + grad(1) -= idi * idi * m(i, 1); + grad(2) -= idi * idi * m(i, 2); + } + else + { + return 1e16; + } + } + return sum; + } + + + + + + + + + class Opti3FreeMinFunction : public MinFunction + { + const PointFunction & pf; + Point<3> sp1; + + public: + Opti3FreeMinFunction (const PointFunction & apf); + void SetPoint (const Point<3> & asp1) { sp1 = asp1; } + virtual double Func (const Vector & x) const; + virtual double FuncGrad (const Vector & x, Vector & g) const; + virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; + virtual double GradStopping (const Vector & x) const; + virtual void ApproximateHesse (const Vector & x, + DenseMatrix & hesse) const; + }; + + Opti3FreeMinFunction :: Opti3FreeMinFunction (const PointFunction & apf) + : pf(apf) + { + ; + } + + double Opti3FreeMinFunction :: Func (const Vector & x) const + { + Point<3> pp; + for (int j = 0; j < 3; j++) + pp(j) = sp1(j) + x(j); + return pf.PointFunctionValue (pp); + } + + double Opti3FreeMinFunction :: FuncGrad (const Vector & x, Vector & grad) const + { + Vec<3> vgrad; + Point<3> pp; + + for (int j = 0; j < 3; j++) + pp(j) = sp1(j) + x(j); + + double val = pf.PointFunctionValueGrad (pp, vgrad); + + for (int j = 0; j < 3; j++) + grad(j) = vgrad(j); + + return val; + } + + double Opti3FreeMinFunction :: FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const + { + Point<3> pp; + + for (int j = 0; j < 3; j++) + pp(j) = sp1(j) + x(j); + + Vec<3> vdir; + for (int j = 0; j < 3; j++) + vdir(j) = dir(j); + + return pf.PointFunctionValueDeriv (pp, vdir, deriv); + } + + double Opti3FreeMinFunction :: GradStopping (const Vector & x) const + { + double f = Func(x); + return 1e-3 * f / pf.GetLocalH(); + } + + + void Opti3FreeMinFunction :: ApproximateHesse (const Vector & x, + DenseMatrix & hesse) const + { + int n = x.Size(); + + Vector hx; + hx.SetSize(n); + + double eps = 1e-8; + double f, f11, f22; //, f12, f21 + + f = Func(x); + + for (int i = 1; i <= n; i++) + { + for (int j = 1; j < i; j++) + { + /* + hx = x; + hx.Elem(i) = x.Get(i) + eps; + hx.Elem(j) = x.Get(j) + eps; + f11 = Func(hx); + hx.Elem(i) = x.Get(i) + eps; + hx.Elem(j) = x.Get(j) - eps; + f12 = Func(hx); + hx.Elem(i) = x.Get(i) - eps; + hx.Elem(j) = x.Get(j) + eps; + f21 = Func(hx); + hx.Elem(i) = x.Get(i) - eps; + hx.Elem(j) = x.Get(j) - eps; + f22 = Func(hx); + */ + hesse.Elem(i, j) = hesse.Elem(j, i) = 0; + // (f11 + f22 - f12 - f21) / (2 * eps * eps); + } + + hx = x; + hx(i-1) = x(i-1) + eps; + f11 = Func(hx); + hx(i-1) = x(i-1) - eps; + f22 = Func(hx); + + hesse.Elem(i, i) = (f11 + f22 - 2 * f) / (eps * eps) + 1e-12; + } + } + + + + + + +#ifdef SOLIDGEOM + class Opti3SurfaceMinFunction : public MinFunction + { + const PointFunction & pf; + Point3d sp1; + const Surface * surf; + Vec3d t1, t2; + + public: + Opti3SurfaceMinFunction (const PointFunction & apf); + + void SetPoint (const Surface * asurf, const Point3d & asp1); + + void CalcNewPoint (const Vector & x, Point3d & np) const; + virtual double Func (const Vector & x) const; + virtual double FuncGrad (const Vector & x, Vector & g) const; + }; + + + Opti3SurfaceMinFunction :: Opti3SurfaceMinFunction (const PointFunction & apf) + : MinFunction(), pf(apf) + { + ; + } + + void Opti3SurfaceMinFunction :: SetPoint (const Surface * asurf, const Point3d & asp1) + { + Vec3d n; + sp1 = asp1; + surf = asurf; + + Vec<3> hn; + surf -> GetNormalVector (sp1, hn); + n = hn; + + n.GetNormal (t1); + t1 /= t1.Length(); + t2 = Cross (n, t1); + } + + + void Opti3SurfaceMinFunction :: CalcNewPoint (const Vector & x, + Point3d & np) const + { + np.X() = sp1.X() + x.Get(1) * t1.X() + x.Get(2) * t2.X(); + np.Y() = sp1.Y() + x.Get(1) * t1.Y() + x.Get(2) * t2.Y(); + np.Z() = sp1.Z() + x.Get(1) * t1.Z() + x.Get(2) * t2.Z(); + + Point<3> hnp = np; + surf -> Project (hnp); + np = hnp; + } + + + double Opti3SurfaceMinFunction :: Func (const Vector & x) const + { + Point3d pp1; + + CalcNewPoint (x, pp1); + return pf.PointFunctionValue (pp1); + } + + + + double Opti3SurfaceMinFunction :: FuncGrad (const Vector & x, Vector & grad) const + { + Vec3d n, vgrad; + Point3d pp1; + VectorMem<3> freegrad; + + CalcNewPoint (x, pp1); + + double badness = pf.PointFunctionValueGrad (pp1, freegrad); + vgrad.X() = freegrad.Get(1); + vgrad.Y() = freegrad.Get(2); + vgrad.Z() = freegrad.Get(3); + + Vec<3> hn; + surf -> GetNormalVector (pp1, hn); + n = hn; + + vgrad -= (vgrad * n) * n; + + grad.Elem(1) = vgrad * t1; + grad.Elem(2) = vgrad * t2; + + return badness; + } +#endif + + + + + + + + +#ifdef SOLIDGEOM + class Opti3EdgeMinFunction : public MinFunction + { + const PointFunction & pf; + Point3d sp1; + const Surface *surf1, *surf2; + Vec3d t1; + + public: + Opti3EdgeMinFunction (const PointFunction & apf); + + void SetPoint (const Surface * asurf1, const Surface * asurf2, + const Point3d & asp1); + void CalcNewPoint (const Vector & x, Point3d & np) const; + virtual double FuncGrad (const Vector & x, Vector & g) const; + virtual double Func (const Vector & x) const; + }; + + Opti3EdgeMinFunction :: Opti3EdgeMinFunction (const PointFunction & apf) + : MinFunction(), pf(apf) + { + ; + } + + void Opti3EdgeMinFunction :: SetPoint (const Surface * asurf1, + const Surface * asurf2, + const Point3d & asp1) + { + Vec3d n1, n2; + sp1 = asp1; + surf1 = asurf1; + surf2 = asurf2; + + Vec<3> hn1, hn2; + surf1 -> GetNormalVector (sp1, hn1); + surf2 -> GetNormalVector (sp1, hn2); + n1 = hn1; + n2 = hn2; + t1 = Cross (n1, n2); + } + + void Opti3EdgeMinFunction :: CalcNewPoint (const Vector & x, + Point3d & np) const +{ + np.X() = sp1.X() + x.Get(1) * t1.X(); + np.Y() = sp1.Y() + x.Get(1) * t1.Y(); + np.Z() = sp1.Z() + x.Get(1) * t1.Z(); + Point<3> hnp = np; + ProjectToEdge (surf1, surf2, hnp); + np = hnp; +} + +double Opti3EdgeMinFunction :: Func (const Vector & x) const +{ + Vector g(x.Size()); + return FuncGrad (x, g); +} + + +double Opti3EdgeMinFunction :: FuncGrad (const Vector & x, Vector & grad) const +{ + Vec3d n1, n2, v1, vgrad; + Point3d pp1; + double badness; + VectorMem<3> freegrad; + + CalcNewPoint (x, pp1); + + + badness = pf.PointFunctionValueGrad (pp1, freegrad); + + vgrad.X() = freegrad.Get(1); + vgrad.Y() = freegrad.Get(2); + vgrad.Z() = freegrad.Get(3); + + Vec<3> hn1, hn2; + surf1 -> GetNormalVector (pp1, hn1); + surf2 -> GetNormalVector (pp1, hn2); + n1 = hn1; + n2 = hn2; + + v1 = Cross (n1, n2); + v1 /= v1.Length(); + + grad.Elem(1) = (vgrad * v1) * (t1 * v1); + return badness; +} +#endif + + + + + +double CalcTotalBad (const Mesh::T_POINTS & points, + const Mesh::T_VOLELEMENTS & elements, + const MeshingParameters & mp) +{ + double sum = 0; + double elbad; + + tets_in_qualclass.SetSize(20); + tets_in_qualclass = 0; + + double teterrpow = mp.opterrpow; + + for (int i = 1; i <= elements.Size(); i++) + { + elbad = pow (max2(CalcBad (points, elements.Get(i), 0, mp),1e-10), + 1/teterrpow); + + int qualclass = int (20 / elbad + 1); + if (qualclass < 1) qualclass = 1; + if (qualclass > 20) qualclass = 20; + tets_in_qualclass.Elem(qualclass)++; + + sum += elbad; + } + return sum; +} + +int WrongOrientation (const Mesh::T_POINTS & points, const Element & el) +{ + const Point3d & p1 = points[el.PNum(1)]; + const Point3d & p2 = points[el.PNum(2)]; + const Point3d & p3 = points[el.PNum(3)]; + const Point3d & p4 = points[el.PNum(4)]; + + Vec3d v1(p1, p2); + Vec3d v2(p1, p3); + Vec3d v3(p1, p4); + Vec3d n; + + Cross (v1, v2, n); + double vol = n * v3; + + return (vol > 0); +} + + + + + + + + + + + +/* ************* JacobianPointFunction **************************** */ + + + + +// class JacobianPointFunction : public MinFunction +// { +// public: +// Mesh::T_POINTS & points; +// const Mesh::T_VOLELEMENTS & elements; +// TABLE elementsonpoint; +// PointIndex actpind; + +// public: +// JacobianPointFunction (Mesh::T_POINTS & apoints, +// const Mesh::T_VOLELEMENTS & aelements); + +// virtual void SetPointIndex (PointIndex aactpind); +// virtual double Func (const Vector & x) const; +// virtual double FuncGrad (const Vector & x, Vector & g) const; +// virtual double FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const; +// }; + + +JacobianPointFunction :: +JacobianPointFunction (Mesh::T_POINTS & apoints, + const Mesh::T_VOLELEMENTS & aelements) + : points(apoints), elements(aelements), elementsonpoint(apoints.Size()) +{ + INDEX i; + int j; + + for (i = 1; i <= elements.Size(); i++) + { + for (j = 1; j <= elements.Get(i).NP(); j++) + elementsonpoint.Add1 (elements.Get(i).PNum(j), i); + } + + onplane = false; +} + +void JacobianPointFunction :: SetPointIndex (PointIndex aactpind) +{ + actpind = aactpind; +} + + +double JacobianPointFunction :: Func (const Vector & v) const +{ + int j; + double badness = 0; + + Point<3> hp = points.Elem(actpind); + + points.Elem(actpind) = hp + Vec<3> (v(0), v(1), v(2)); + + if(onplane) + points.Elem(actpind) -= (v(0)*nv(0)+v(1)*nv(1)+v(2)*nv(2)) * nv; + + + for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) + { + int eli = elementsonpoint.Get(actpind, j); + badness += elements.Get(eli).CalcJacobianBadness (points); + } + + points.Elem(actpind) = hp; + + return badness; +} + + + + + +double JacobianPointFunction :: +FuncGrad (const Vector & x, Vector & g) const +{ + int j, k; + int lpi; + double badness = 0;//, hbad; + + Point<3> hp = points.Elem(actpind); + points.Elem(actpind) = hp + Vec<3> (x(0), x(1), x(2)); + + if(onplane) + points.Elem(actpind) -= (x(0)*nv(0)+x(1)*nv(1)+x(2)*nv(2)) * nv; + + Vec<3> hderiv; + //Vec3d vdir; + g.SetSize(3); + g = 0; + + for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) + { + int eli = elementsonpoint.Get(actpind, j); + const Element & el = elements.Get(eli); + + lpi = 0; + for (k = 1; k <= el.GetNP(); k++) + if (el.PNum(k) == actpind) + lpi = k; + if (!lpi) cerr << "loc point not found" << endl; + + badness += elements.Get(eli). + CalcJacobianBadnessGradient (points, lpi, hderiv); + + for(k=0; k<3; k++) + g(k) += hderiv(k); + + /* + for (k = 1; k <= 3; k++) + { + vdir = Vec3d(0,0,0); + vdir.X(k) = 1; + + hbad = elements.Get(eli). + CalcJacobianBadnessDirDeriv (points, lpi, vdir, hderiv); + //(*testout) << "hderiv " << k << ": " << hderiv << endl; + g.Elem(k) += hderiv; + if (k == 1) + badness += hbad; + } + */ + } + + if(onplane) + { + double scal = nv(0)*g(0) + nv(1)*g(1) + nv(2)*g(2); + g(0) -= scal*nv(0); + g(1) -= scal*nv(1); + g(2) -= scal*nv(2); + } + + //(*testout) << "g = " << g << endl; + + + points.Elem(actpind) = hp; + + return badness; +} + + +double JacobianPointFunction :: +FuncDeriv (const Vector & x, const Vector & dir, double & deriv) const +{ + int j, k; + int lpi; + double badness = 0; + + Point<3> hp = points.Elem(actpind); + points.Elem(actpind) = Point<3> (hp + Vec3d (x(0), x(1), x(2))); + + if(onplane) + points.Elem(actpind) -= (Vec3d (x(0), x(1), x(2))*nv) * nv; + + double hderiv; + deriv = 0; + Vec<3> vdir(dir(0), dir(1), dir(2)); + + if(onplane) + { + double scal = vdir * nv; + vdir -= scal*nv; + } + + for (j = 1; j <= elementsonpoint.EntrySize(actpind); j++) + { + int eli = elementsonpoint.Get(actpind, j); + const Element & el = elements.Get(eli); + + lpi = 0; + for (k = 1; k <= el.GetNP(); k++) + if (el.PNum(k) == actpind) + lpi = k; + if (!lpi) cerr << "loc point not found" << endl; + + badness += elements.Get(eli). + CalcJacobianBadnessDirDeriv (points, lpi, vdir, hderiv); + deriv += hderiv; + } + + points.Elem(actpind) = hp; + + return badness; + +} + + + + + + + + + + +#ifdef SOLIDGEOMxxxx +void Mesh :: ImproveMesh (const CSGeometry & geometry, OPTIMIZEGOAL goal) +{ + INDEX i, eli; + int j; + int typ = 1; + + if (!&geometry || geometry.GetNSurf() == 0) + { + ImproveMesh (goal); + return; + } + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh"; + + + TABLE surfelementsonpoint(points.Size()); + Vector x(3), xsurf(2), xedge(1); + int surf, surf1, surf2, surf3; + + int uselocalh = mparam.uselocalh; + + (*testout) << setprecision(8); + (*testout) << "Improve Mesh" << "\n"; + PrintMessage (3, "ImproveMesh"); + // (*mycout) << "Vol = " << CalcVolume (points, volelements) << endl; + + + for (i = 1; i <= surfelements.Size(); i++) + for (j = 1; j <= 3; j++) + surfelementsonpoint.Add1 (surfelements.Get(i).PNum(j), i); + + + PointFunction * pf; + if (typ == 1) + pf = new PointFunction(points, volelements); + else + pf = new CheapPointFunction(points, volelements); + + // pf->SetLocalH (h); + + Opti3FreeMinFunction freeminf(*pf); + Opti3SurfaceMinFunction surfminf(*pf); + Opti3EdgeMinFunction edgeminf(*pf); + + OptiParameters par; + par.maxit_linsearch = 20; + par.maxit_bfgs = 20; + + int printmod = 1; + char printdot = '.'; + if (points.Size() > 1000) + { + printmod = 10; + printdot = '+'; + } + if (points.Size() > 10000) + { + printmod = 100; + printdot = '*'; + } + + for (i = 1; i <= points.Size(); i++) + { + // if (ptyps.Get(i) == FIXEDPOINT) continue; + if (ptyps.Get(i) != INNERPOINT) continue; + + if (multithread.terminate) + throw NgException ("Meshing stopped"); + /* + if (multithread.terminate) + break; + */ + multithread.percent = 100.0 * i /points.Size(); + + /* + if (points.Size() < 1000) + PrintDot (); + else + if (i % 10 == 0) + PrintDot ('+'); + */ + if (i % printmod == 0) PrintDot (printdot); + + // (*testout) << "Now point " << i << "\n"; + // (*testout) << "Old: " << points.Get(i) << "\n"; + + pf->SetPointIndex (i); + + // if (uselocalh) + { + double lh = GetH (points.Get(i)); + pf->SetLocalH (GetH (points.Get(i))); + par.typx = lh / 10; + // (*testout) << "lh(" << points.Get(i) << ") = " << lh << "\n"; + } + + surf1 = surf2 = surf3 = 0; + + for (j = 1; j <= surfelementsonpoint.EntrySize(i); j++) + { + eli = surfelementsonpoint.Get(i, j); + int surfi = surfelements.Get(eli).GetIndex(); + + if (surfi) + { + surf = GetFaceDescriptor(surfi).SurfNr(); + + if (!surf1) + surf1 = surf; + else if (surf1 != surf) + { + if (!surf2) + surf2 = surf; + else if (surf2 != surf) + surf3 = surf; + } + } + else + { + surf1 = surf2 = surf3 = 1; // simulates corner point + } + } + + + if (surf2 && !surf3) + { + // (*testout) << "On Edge" << "\n"; + /* + xedge = 0; + edgeminf.SetPoint (geometry.GetSurface(surf1), + geometry.GetSurface(surf2), + points.Elem(i)); + BFGS (xedge, edgeminf, par); + + edgeminf.CalcNewPoint (xedge, points.Elem(i)); + */ + } + + if (surf1 && !surf2) + { + // (*testout) << "In Surface" << "\n"; + /* + xsurf = 0; + surfminf.SetPoint (geometry.GetSurface(surf1), + points.Get(i)); + BFGS (xsurf, surfminf, par); + + surfminf.CalcNewPoint (xsurf, points.Elem(i)); + */ + } + + if (!surf1) + { + // (*testout) << "In Volume" << "\n"; + x = 0; + freeminf.SetPoint (points.Elem(i)); + // par.typx = + BFGS (x, freeminf, par); + + points.Elem(i).X() += x.Get(1); + points.Elem(i).Y() += x.Get(2); + points.Elem(i).Z() += x.Get(3); + } + + // (*testout) << "New Point: " << points.Elem(i) << "\n" << "\n"; + + } + PrintDot ('\n'); + // (*mycout) << "Vol = " << CalcVolume (points, volelements) << endl; + + multithread.task = savetask; + +} +#endif + + + + +void Mesh :: ImproveMesh (const MeshingParameters & mp, OPTIMIZEGOAL goal) +{ + int typ = 1; + + (*testout) << "Improve Mesh" << "\n"; + PrintMessage (3, "ImproveMesh"); + + int np = GetNP(); + int ne = GetNE(); + + + Array perrs(np); + perrs = 1.0; + + double bad1 = 0; + double badmax = 0; + + if (goal == OPT_QUALITY) + { + for (int i = 1; i <= ne; i++) + { + const Element & el = VolumeElement(i); + if (el.GetType() != TET) + continue; + + double hbad = CalcBad (points, el, 0, mp); + for (int j = 0; j < 4; j++) + perrs[el[j]] += hbad; + + bad1 += hbad; + } + + for (int i = perrs.Begin(); i < perrs.End(); i++) + if (perrs[i] > badmax) + badmax = perrs[i]; + badmax = 0; + } + + if (goal == OPT_QUALITY) + { + bad1 = CalcTotalBad (points, volelements, mp); + (*testout) << "Total badness = " << bad1 << endl; + PrintMessage (5, "Total badness = ", bad1); + } + + Vector x(3); + + (*testout) << setprecision(8); + + //int uselocalh = mparam.uselocalh; + + + PointFunction * pf; + + if (typ == 1) + pf = new PointFunction(points, volelements, mp); + else + pf = new CheapPointFunction(points, volelements, mp); + + // pf->SetLocalH (h); + + Opti3FreeMinFunction freeminf(*pf); + + OptiParameters par; + par.maxit_linsearch = 20; + par.maxit_bfgs = 20; + + Array pointh (points.Size()); + + if(lochfunc) + { + for(int i=1; i<=points.Size(); i++) + pointh[i] = GetH(points.Get(i)); + } + else + { + pointh = 0; + for(int i=0; i pointh[el.PNum(j)]) + pointh[el.PNum(j)] = h; + } + } + + + int printmod = 1; + char printdot = '.'; + if (points.Size() > 1000) + { + printmod = 10; + printdot = '+'; + } + if (points.Size() > 10000) + { + printmod = 100; + printdot = '*'; + } + + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh"; + + for (PointIndex pi = points.Begin(); pi < points.End(); pi++) + if ( (*this)[pi].Type() == INNERPOINT && perrs[pi] > 0.01 * badmax) + { + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + multithread.percent = 100.0 * (pi+1-PointIndex::BASE) / points.Size(); + /* + if (points.Size() < 1000) + PrintDot (); + else + if ( (i+1-PointIndex::BASE) % 10 == 0) + PrintDot ('+'); + */ + if ( (pi+1-PointIndex::BASE) % printmod == 0) PrintDot (printdot); + + double lh = pointh[pi]; + pf->SetLocalH (lh); + par.typx = lh; + + freeminf.SetPoint (points[pi]); + pf->SetPointIndex (pi); + + x = 0; + int pok; + pok = freeminf.Func (x) < 1e10; + + if (!pok) + { + pok = pf->MovePointToInner (); + + freeminf.SetPoint (points[pi]); + pf->SetPointIndex (pi); + } + + if (pok) + { + //*testout << "start BFGS, pok" << endl; + BFGS (x, freeminf, par); + //*testout << "BFGS complete, pok" << endl; + points[pi](0) += x(0); + points[pi](1) += x(1); + points[pi](2) += x(2); + } + } + PrintDot ('\n'); + + + delete pf; + + multithread.task = savetask; + + if (goal == OPT_QUALITY) + { + bad1 = CalcTotalBad (points, volelements, mp); + (*testout) << "Total badness = " << bad1 << endl; + PrintMessage (5, "Total badness = ", bad1); + } +} + + + + +// Improve Condition number of Jacobian, any elements +void Mesh :: ImproveMeshJacobian (const MeshingParameters & mp, + OPTIMIZEGOAL goal, const BitArray * usepoint) +{ + int i, j; + + (*testout) << "Improve Mesh Jacobian" << "\n"; + PrintMessage (3, "ImproveMesh Jacobian"); + + int np = GetNP(); + int ne = GetNE(); + + + Vector x(3); + + (*testout) << setprecision(8); + + JacobianPointFunction pf(points, volelements); + + + OptiParameters par; + par.maxit_linsearch = 20; + par.maxit_bfgs = 20; + + BitArray badnodes(np); + badnodes.Clear(); + + for (i = 1; i <= ne; i++) + { + const Element & el = VolumeElement(i); + double bad = el.CalcJacobianBadness (Points()); + if (bad > 1) + for (j = 1; j <= el.GetNP(); j++) + badnodes.Set (el.PNum(j)); + } + + Array pointh (points.Size()); + + if(lochfunc) + { + for(i = 1; i<=points.Size(); i++) + pointh[i] = GetH(points.Get(i)); + } + else + { + pointh = 0; + for(i=0; i pointh[el.PNum(j)]) + pointh[el.PNum(j)] = h; + } + } + + + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh Jacobian"; + + for (PointIndex pi = points.Begin(); i < points.End(); pi++) + { + if ((*this)[pi].Type() != INNERPOINT) + continue; + + if(usepoint && !usepoint->Test(i)) + continue; + + //(*testout) << "improvejac, p = " << i << endl; + + if (goal == OPT_WORSTCASE && !badnodes.Test(i)) + continue; + // (*testout) << "smoot p " << i << endl; + + /* + if (multithread.terminate) + break; + */ + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + multithread.percent = 100.0 * i / points.Size(); + + if (points.Size() < 1000) + PrintDot (); + else + if (i % 10 == 0) + PrintDot ('+'); + + double lh = pointh[i]; + par.typx = lh; + + pf.SetPointIndex (pi); + + x = 0; + int pok = (pf.Func (x) < 1e10); + + if (pok) + { + //*testout << "start BFGS, Jacobian" << endl; + BFGS (x, pf, par); + //*testout << "end BFGS, Jacobian" << endl; + points.Elem(i)(0) += x(0); + points.Elem(i)(1) += x(1); + points.Elem(i)(2) += x(2); + } + else + { + cout << "el not ok" << endl; + } + } + PrintDot ('\n'); + + + multithread.task = savetask; +} + + + + +// Improve Condition number of Jacobian, any elements +void Mesh :: ImproveMeshJacobianOnSurface (const MeshingParameters & mp, + const BitArray & usepoint, + const Array< Vec<3>* > & nv, + OPTIMIZEGOAL goal, + const Array< Array* > * idmaps) +{ + int i, j; + + (*testout) << "Improve Mesh Jacobian" << "\n"; + PrintMessage (3, "ImproveMesh Jacobian"); + + int np = GetNP(); + int ne = GetNE(); + + + Vector x(3); + + (*testout).precision(8); + + JacobianPointFunction pf(points, volelements); + + Array< Array* > locidmaps; + const Array< Array* > * used_idmaps; + + if(idmaps) + used_idmaps = idmaps; + else + { + used_idmaps = &locidmaps; + + for(i=1; i<=GetIdentifications().GetMaxNr(); i++) + { + if(GetIdentifications().GetType(i) == Identifications::PERIODIC) + { + locidmaps.Append(new Array); + GetIdentifications().GetMap(i,*locidmaps.Last(),true); + } + } + } + + + bool usesum = (used_idmaps->Size() > 0); + MinFunctionSum pf_sum; + + JacobianPointFunction * pf2ptr = NULL; + if(usesum) + { + pf2ptr = new JacobianPointFunction(points, volelements); + pf_sum.AddFunction(pf); + pf_sum.AddFunction(*pf2ptr); + } + + + OptiParameters par; + par.maxit_linsearch = 20; + par.maxit_bfgs = 20; + + BitArray badnodes(np); + badnodes.Clear(); + + for (i = 1; i <= ne; i++) + { + const Element & el = VolumeElement(i); + double bad = el.CalcJacobianBadness (Points()); + if (bad > 1) + for (j = 1; j <= el.GetNP(); j++) + badnodes.Set (el.PNum(j)); + } + + Array pointh (points.Size()); + + if(lochfunc) + { + for(i=1; i<=points.Size(); i++) + pointh[i] = GetH(points.Get(i)); + } + else + { + pointh = 0; + for(i=0; i pointh[el.PNum(j)]) + pointh[el.PNum(j)] = h; + } + } + + + const char * savetask = multithread.task; + multithread.task = "Smooth Mesh Jacobian"; + + for (PointIndex pi = points.Begin(); pi <= points.End(); pi++) + if ( usepoint.Test(i) ) + { + //(*testout) << "improvejac, p = " << i << endl; + + if (goal == OPT_WORSTCASE && !badnodes.Test(i)) + continue; + // (*testout) << "smoot p " << i << endl; + + /* + if (multithread.terminate) + break; + */ + if (multithread.terminate) + throw NgException ("Meshing stopped"); + + multithread.percent = 100.0 * i / points.Size(); + + if (points.Size() < 1000) + PrintDot (); + else + if (i % 10 == 0) + PrintDot ('+'); + + double lh = pointh[i];//GetH(points.Get(i)); + par.typx = lh; + + pf.SetPointIndex (pi); + + PointIndex brother (-1); + if(usesum) + { + for(j=0; brother == -1 && jSize(); j++) + { + if(i < (*used_idmaps)[j]->Size() + PointIndex::BASE) + { + brother = (*(*used_idmaps)[j])[i]; + if(brother == i || brother == 0) + brother = -1; + } + } + if(brother >= i) + { + pf2ptr->SetPointIndex(brother); + pf2ptr->SetNV(*nv[brother-1]); + } + } + + if(usesum && brother < i) + continue; + + //pf.UnSetNV(); x = 0; + //(*testout) << "before " << pf.Func(x); + + pf.SetNV(*nv[i-1]); + + x = 0; + int pok = (brother == -1) ? (pf.Func (x) < 1e10) : (pf_sum.Func (x) < 1e10); + + if (pok) + { + + if(brother == -1) + BFGS (x, pf, par); + else + BFGS (x, pf_sum, par); + + + for(j=0; j<3; j++) + points.Elem(i)(j) += x(j);// - scal*nv[i-1].X(j); + + if(brother != -1) + for(j=0; j<3; j++) + points.Elem(brother)(j) += x(j);// - scal*nv[brother-1].X(j); + + + } + else + { + cout << "el not ok" << endl; + (*testout) << "el not ok" << endl + << " func " << ((brother == -1) ? pf.Func(x) : pf_sum.Func (x)) << endl; + if(brother != -1) + (*testout) << " func1 " << pf.Func(x) << endl + << " func2 " << pf2ptr->Func(x) << endl; + } + } + + PrintDot ('\n'); + + delete pf2ptr; + for(i=0; i +#include "meshing.hpp" + + +namespace netgen +{ + +// A special function for Hermann Landes, Erlangen + + +void CutOffAndCombine (Mesh & mesh, const Mesh & othermesh) +{ + int i, j; + int nse = othermesh.GetNSE(); + int onp = othermesh.GetNP(); + + int ne = mesh.GetNE(); + + PrintMessage (1, "other mesh has ", + othermesh.GetNP(), " points, ", + othermesh.GetNSE(), " surface elements."); + + Array otherbounds(nse); + Box3d otherbox; + + double maxh = 0; + for (i = 1; i <= nse; i++) + { + const Element2d & sel = othermesh.SurfaceElement(i); + sel.GetBox(othermesh.Points(), otherbounds.Elem(i)); + + double loch = othermesh.GetH (othermesh.Point (sel.PNum(1))); + otherbounds.Elem(i).Increase(loch); + if (loch > maxh) maxh = loch; + } + + otherbox.SetPoint (othermesh.Point(1)); + for (i = 1; i <= othermesh.GetNP(); i++) + otherbox.AddPoint (othermesh.Point(i)); + otherbox.Increase (maxh); + + for (i = 1; i <= ne; i++) + { + Box3d box; + int remove = 0; + + const Element & el = mesh.VolumeElement(i); + el.GetBox(mesh.Points(), box); + + if (i % 10000 == 0) + cout << "+" << flush; + + if (box.Intersect(otherbox)) + { + for (j = 1; j <= nse && !remove; j++) + if (box.Intersect(otherbounds.Get(j))) + remove = 1; + } + + if (remove) + mesh.VolumeElement(i).Delete(); + } + cout << endl; + + BitArray connected(mesh.GetNP()); + connected.Clear(); + for (i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & el = mesh.SurfaceElement(i); + for (j = 1; j <= 3; j++) + connected.Set(el.PNum(j)); + } + + bool changed; + do + { + changed = 0; + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement(i); + int has = 0, hasnot = 0; + if (el[0]) + { + for (j = 0; j < 4; j++) + { + if (connected.Test(el[j])) + has = 1; + else + hasnot = 1; + } + if (has && hasnot) + { + changed = 1; + for (j = 0; j < 4; j++) + connected.Set (el[j]); + } + } + } + cout << "." << flush; + } + while (changed); + cout << endl; + + for (i = 1; i <= mesh.GetNE(); i++) + { + const Element & el = mesh.VolumeElement(i); + int hasnot = 0; + if (el[0]) + { + for (j = 0; j < 4; j++) + { + if (!connected.Test(el[j])) + hasnot = 1; + } + if (hasnot) + mesh.VolumeElement(i).Delete(); + } + } + + mesh.Compress(); + + mesh.FindOpenElements(); + BitArray locked(mesh.GetNP()); + locked.Set(); + for (i = 1; i <= mesh.GetNOpenElements(); i++) + for (j = 1; j <= 3; j++) + locked.Clear (mesh.OpenElement(i).PNum(j)); + + for (PointIndex i (1); i <= locked.Size(); i++) + if (locked.Test(i)) + { + mesh.AddLockedPoint (i); + } + + + + + Array pmat(onp); + + for (i = 1; i <= onp; i++) + pmat.Elem(i) = mesh.AddPoint (othermesh.Point(i)); + + int fnum = + mesh.AddFaceDescriptor (FaceDescriptor(0,0,1,0)); + + for (i = 1; i <= othermesh.GetNSE(); i++) + { + Element2d tri = othermesh.SurfaceElement(i); + for (j = 1; j <= 3; j++) + tri.PNum(j) = pmat.Get(tri.PNum(j)); + tri.SetIndex(fnum); + mesh.AddSurfaceElement (tri); + } + + for (i = 1; i <= onp; i++) + mesh.AddLockedPoint (pmat.Elem(i)); + + mesh.CalcSurfacesOfNode(); + mesh.CalcLocalH(0.3); +} + + + + +void HelmholtzMesh (Mesh & mesh) +{ + int i; + double ri, ra, rinf; + + cout << "ri = "; + cin >> ri; + cout << "ra = "; + cin >> ra; + cout << "rinf = "; + cin >> rinf; + + double det = ri * ra * rinf - ri * ri * rinf; + double a = (ri - rinf) / det; + double b = (ri*ri - ra * rinf) / det; + for (i = 1; i <= mesh.GetNP(); i++) + { + Point<3> & p = mesh.Point(i); + double rold = sqrt (sqr(p(0)) + sqr(p(1)) + sqr(p(2))); + if (rold < ri) continue; + + double rnew = 1 / (a * rold - b); + double fac = rnew / rold; + p(0) *= fac; + p(1) *= fac; + p(2) *= fac; + } +} +} diff --git a/libsrc/meshing/specials.hpp b/libsrc/meshing/specials.hpp new file mode 100644 index 00000000..700ba459 --- /dev/null +++ b/libsrc/meshing/specials.hpp @@ -0,0 +1,16 @@ +#ifndef FILE_SPECIALS +#define FILE_SPECIALS + +/* + + Very special implementations .. + + */ + + +/// +extern void CutOffAndCombine (Mesh & mesh, const Mesh & othermesh); + +extern void HelmholtzMesh (Mesh & mesh); + +#endif diff --git a/libsrc/meshing/tetrarls.cpp b/libsrc/meshing/tetrarls.cpp new file mode 100644 index 00000000..cb28648b --- /dev/null +++ b/libsrc/meshing/tetrarls.cpp @@ -0,0 +1,1466 @@ +namespace netgen +{ +const char * tetrules[] = { +"tolfak 0.5\n",\ +"\n",\ +"rule \"Free Tetrahedron\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0);\n",\ +"(0.5, 0.866, 0);\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.288, -0.816)\n",\ +" { 0.333 X1, 0.333 X2, 0.333 X3 }\n",\ +" { 0.333 Y1, 0.333 Y2, 0.333 Y3 } { };\n",\ +"\n",\ +"newfaces\n",\ +"(4, 1, 2);\n",\ +"(4, 2, 3);\n",\ +"(4, 3, 1);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1.6 P4, -0.2 P1, -0.2 P2, -0.2 P3 };\n",\ +"{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 };\n",\ +"{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 };\n",\ +"{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron 60\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"flags c;\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 } ;\n",\ +"(0.5, 0.866, 0) { 0.5 };\n",\ +"(0.5, 0.288, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 4, 3);\n",\ +"(4, 2, 3);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ +"\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.65 P3, 0.35 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron 60 with edge(1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"flags c;\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.8 };\n",\ +"(0.5, 0.866, 0) { 0.8 };\n",\ +"(0.5, 0.288, -0.816) { 0.8 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"\n",\ +"mapedges\n",\ +"(3, 4);\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 4, 3);\n",\ +"(4, 2, 3);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 };\n",\ +"{ 0.4 P2, 0.4 P4, 0.4 P3, -0.2 P1 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P4, 0.3334 P3 };\n",\ +"{ 0.3333 P2, 0.3333 P4, 0.3334 P3 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron Vis a Vis Point (1)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 0.866, 0) { 0.5 };\n",\ +"(0.5, 0.288, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(4, 3, 1);\n",\ +"(4, 2, 3);\n",\ +"(4, 1, 2);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ -0.5 P1, 0.5 P2, 0.5 P3, 0.5 P4 };\n",\ +"{ 0.5 P1, -0.5 P2, 0.5 P3, 0.5 P4 };\n",\ +"{ 0.5 P1, 0.5 P2, -0.5 P3, 0.5 P4 };\n",\ +"{ 0.8 P1, -0.1 P2, -0.1 P3, 0.4 P4 };\n",\ +"{ -0.1 P1, 0.8 P2, -0.1 P3, 0.4 P4 };\n",\ +"{ -0.1 P1, -0.1 P2, 0.8 P3, 0.4 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ +"{ 0.7 P1, 0.3 P4 };\n",\ +"{ 0.7 P2, 0.3 P4 };\n",\ +"{ 0.7 P3, 0.3 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron Vis a Vis Point with edge(1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 0.866, 0) { 0.5 };\n",\ +"(0.5, 0.288, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"\n",\ +"mapedges\n",\ +"(1, 4);\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(4, 3, 1);\n",\ +"(4, 2, 3);\n",\ +"(4, 1, 2);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ +"{ -0.05 P1, 0.7 P2, -0.05 P3, 0.4 P4 };\n",\ +"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ +"{ 0.65 P2, 0.35 P4 };\n",\ +"{ 0.65 P3, 0.35 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron Vis a Vis Point with 2 edges (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 0.866, 0) { 0.5 };\n",\ +"(0.5, 0.288, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"\n",\ +"mapedges\n",\ +"(1, 4);\n",\ +"(2, 4);\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(4, 3, 1);\n",\ +"(4, 2, 3);\n",\ +"(4, 1, 2);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ +"{ -0.05 P1, -0.05 P2, 0.7 P3, 0.4 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ +"{ 0.65 P3, 0.35 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron Vis a Vis Point with 3 edges (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 0.866, 0) { 0.5 };\n",\ +"(0.5, 0.288, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"\n",\ +"mapedges\n",\ +"(1, 4);\n",\ +"(2, 4);\n",\ +"(3, 4);\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(4, 3, 1);\n",\ +"(4, 2, 3);\n",\ +"(4, 1, 2);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ -0.35 P1, 0.45 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ 0.45 P1, -0.35 P2, 0.45 P3, 0.45 P4 };\n",\ +"{ 0.45 P1, 0.45 P2, -0.35 P3, 0.45 P4 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.3333 P2, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P2, 0.3334 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron Vis a Vis Triangle (1)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 0.866, 0) { 0.5 };\n",\ +"(0, 0, -0.816) { 0.5 };\n",\ +"(1, 0, -0.816) { 0.5 };\n",\ +"(0.5, 0.866, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(4, 6, 5) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 4);\n",\ +"(2, 5, 4);\n",\ +"(2, 3, 6);\n",\ +"(2, 6, 5);\n",\ +"(3, 1, 4);\n",\ +"(3, 4, 6);\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"(4, 2, 3, 6);\n",\ +"(4, 2, 6, 5);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ -0.2 P1, 0.35 P2, 0.35 P3, -0.2 P4, 0.35 P5, 0.35 P6 };\n",\ +"{ 0.35 P1, -0.2 P2, 0.35 P3, 0.35 P4, -0.2 P5, 0.35 P6 };\n",\ +"{ 0.35 P1, 0.35 P2, -0.2 P3, 0.35 P4, 0.35 P5, -0.2 P6 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Octaeder 1\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.95 };\n",\ +"(0.5, 0.866, 0) { 0.95 };\n",\ +"(0.5, -0.288, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ +"(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(2, 3, 5);\n",\ +"(3, 1, 6);\n",\ +"(3, 6, 5);\n",\ +"(2, 5, 4);\n",\ +"(1, 4, 6);\n",\ +"(4, 5, 6);\n",\ +"\n",\ +"elements\n",\ +"(3, 4, 1, 2);\n",\ +"(3, 4, 2, 5);\n",\ +"(3, 4, 5, 6);\n",\ +"(3, 4, 6, 1);\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ +"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 };\n",\ +"( 1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 1 Z4 };\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Octaeder 2\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.95 };\n",\ +"(0.5, 0.866, 0) { 0.95 };\n",\ +"(0.5, -0.288, -0.816) { 0.5 };\n",\ +"(1, 0.578, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(2, 3, 5);\n",\ +"(3, 1, 6);\n",\ +"(3, 6, 5);\n",\ +"(2, 5, 4);\n",\ +"(1, 4, 6);\n",\ +"(4, 5, 6);\n",\ +"\n",\ +"elements\n",\ +"(3, 4, 1, 2);\n",\ +"(3, 4, 2, 5);\n",\ +"(3, 4, 5, 6);\n",\ +"(3, 4, 6, 1);\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ +"(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ +"\n",\ +"(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 }\n",\ +" { 0.333 Y2, 0.333 Y4, 0.333 Y5 }\n",\ +" { 0.333 Z2, 0.333 Z4, 0.333 Z5 };\n",\ +"(0.9, 0.481, -0.272) { 0.333 X2, 0.333 X3, 0.333 X5 }\n",\ +" { 0.333 Y2, 0.333 Y3, 0.333 Y5 }\n",\ +" { 0.333 Z2, 0.333 Z3, 0.333 Z5 };\n",\ +"\n",\ +"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 };\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"rule \"Octaeder 2a\"\n",\ +"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.95 };\n",\ +"(0.5, 0.866, 0) { 0.95 };\n",\ +"(0.5, -0.288, -0.816) { 0.5 };\n",\ +"(1, 0.578, -0.816) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(3, 2, 5) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0, 0.578, -0.816)\n",\ +" { -1 X2, 1 X3, 1 X4 }\n",\ +" { -1 Y2, 1 Y3, 1 Y4 }\n",\ +" { -1 Z2, 1 Z3, 1 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(1, 2, 4);\n",\ +"(3, 1, 6);\n",\ +"(3, 6, 5);\n",\ +"(2, 5, 4);\n",\ +"(1, 4, 6);\n",\ +"(4, 5, 6);\n",\ +"\n",\ +"elements\n",\ +"(3, 4, 1, 2);\n",\ +"(3, 4, 2, 5);\n",\ +"(3, 4, 5, 6);\n",\ +"(3, 4, 6, 1);\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ +"(1, 0.578, -0.816) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ +"\n",\ +"(0.9, 0.097, -0.544) { 0.333 X2, 0.333 X4, 0.333 X5 }\n",\ +" { 0.333 Y2, 0.333 Y4, 0.333 Y5 }\n",\ +" { 0.333 Z2, 0.333 Z4, 0.333 Z5 };\n",\ +"\n",\ +"(0.5, -0.097, -0.272) { 0.333 X2, 0.333 X4, 0.333 X1 }\n",\ +" { 0.333 Y2, 0.333 Y4, 0.333 Y1 }\n",\ +" { 0.333 Z2, 0.333 Z4, 0.333 Z1 };\n",\ +"\n",\ +"(-0.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 } { 0.5 Z4, 0.5 Z5 };\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Pyramid 1\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 };\n",\ +"(0.5, 0.866, 0) { 1 };\n",\ +"(0.5, -0.288, -0.816) { 1 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(1, 0.578, -0.816) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(1, 4, 3);\n",\ +"(2, 3, 5);\n",\ +"(2, 5, 4);\n",\ +"(4, 5, 3);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"(4, 2, 3, 5);\n",\ +"\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, -0.288, -0.816) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ +"(0, 1, -1) { 0.5 X3, 0.5 X4 } { 1 Y3 } { 1 Z4 };\n",\ +"(1.5, 1, -1.5) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron 2 times 60\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.3 };\n",\ +"(0.5, 0.866, 0) { 0.3 };\n",\ +"(0.5, 0.288, -0.816) { 0.3 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(2, 4, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"(1, 4, 3);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.4 P1, 0.4 P4, 0.4 P3, -0.2 P2 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 0.3333 P1, 0.3333 P3, 0.3334 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Fill Tetrahedron (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.2 };\n",\ +"(0.5, 0.866, 0) { 0.2 };\n",\ +"(0.5, 0.288, -0.816) { 0.2 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(2, 4, 3) del;\n",\ +"(3, 4, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newfaces\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron 120 (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 };\n",\ +"(0.5, 0.866, 0) { 1 };\n",\ +"(0.5, -0.674, -0.544) { 1 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.288, -0.816)\n",\ +" { -0.5 X1, -0.5 X2, 1 X3, 1 X4 }\n",\ +" { -0.5 Y1, -0.5 Y2, 1 Y3, 1 Y4}\n",\ +" { -0.5 Z1, -0.5 Z2, 1 Z3, 1 Z4};\n",\ +"\n",\ +"newfaces\n",\ +"(1, 5, 3);\n",\ +"(3, 5, 2);\n",\ +"(1, 4, 5);\n",\ +"(2, 5, 4);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 5);\n",\ +"(1, 4, 2, 5);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.3 P5, -0.3 P1 };\n",\ +"{ 1.3 P5, -0.3 P2 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P5 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron 2 times 120 (1)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 };\n",\ +"(0.5, 0.866, 0) { 1 };\n",\ +"(0.5, -0.674, -0.544) { 0.8 };\n",\ +"(1.334, 0.77, -0.544) { 0.8 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(3, 2, 5) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.288, -0.816) { 0.25 X1, -0.5 X2, 0.25 X3, 0.5 X4, 0.5 X5 }\n",\ +" { 0.25 Y1, -0.5 Y2, 0.25 Y3, 0.5 Y4, 0.5 Y5 }\n",\ +" { 0.25 Z1, -0.5 Z2, 0.25 Z3, 0.5 Z4, 0.5 Z5 };\n",\ +"\n",\ +"newfaces\n",\ +"(6, 3, 1);\n",\ +"(6, 1, 4);\n",\ +"(6, 4, 2);\n",\ +"(6, 2, 5);\n",\ +"(6, 5, 3);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 6);\n",\ +"(1, 4, 2, 6);\n",\ +"(2, 5, 3, 6);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1.4 P6, -0.4 P2 };\n",\ +"{ 1.4 P6, -0.4 P1 };\n",\ +"{ 1.4 P6, -0.4 P3 };\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"four Tetrahedron non convex (4)\"\n",\ +"\n",\ +"quality 4\n",\ +"flags l;\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.1 };\n",\ +"(0.5, 1, 0) { 0.1 };\n",\ +"(0.5, 0, -1) { 0.1 };\n",\ +"(0.5, 0.3, -0.3) { 0.1 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(1, 5, 4) del;\n",\ +"(1, 3, 5) del;\n",\ +"\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.1, -0.1)\n",\ +" { 0.333 X1, 0.333 X2, 0.334 X5 }\n",\ +" { 0.333 Y1, 0.333 Y2, 0.334 Y5 }\n",\ +" { 0.333 Z1, 0.333 Z2, 0.334 Z5 };\n",\ +"\n",\ +"newfaces\n",\ +"(6, 2, 3) del;\n",\ +"(6, 4, 2) del;\n",\ +"(6, 5, 4) del;\n",\ +"(6, 3, 5) del;\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 6);\n",\ +"(1, 4, 2, 6);\n",\ +"(1, 5, 4, 6);\n",\ +"(1, 3, 5, 6);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1.5 P6, -0.5 P1 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"\n",\ +"\n",\ +"\n",\ +"freeset\n",\ +"1 6 2 3;\n",\ +"\n",\ +"freeset\n",\ +"1 6 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 6 5 4;\n",\ +"\n",\ +"freeset\n",\ +"1 6 4 2;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"five Tetrahedron non convex (4)\"\n",\ +"\n",\ +"quality 4\n",\ +"flags l;\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 1, 0) { 0.5 };\n",\ +"(0, 0.8, -0.2) { 0.5 };\n",\ +"(0, 0.2, -0.8) { 0.5 };\n",\ +"(0.5, 0, -1) { 0.5 };\n",\ +"\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 3, 4) del;\n",\ +"(1, 4, 5) del;\n",\ +"(1, 5, 6) del;\n",\ +"(1, 6, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.1, 0.1, -0.1)\n",\ +" { 0.75 X1, 0.05 X2, 0.05 X3, 0.05 X4, 0.05 X5, 0.05 X6 }\n",\ +" { 0.75 Y1, 0.05 Y2, 0.05 Y3, 0.05 Y4, 0.05 Y5, 0.05 Y6 }\n",\ +" { 0.75 Z1, 0.05 Z2, 0.05 Z3, 0.05 Z4, 0.05 Z5, 0.05 Z6 };\n",\ +"\n",\ +"newfaces\n",\ +"(7, 2, 3);\n",\ +"(7, 3, 4);\n",\ +"(7, 4, 5);\n",\ +"(7, 5, 6);\n",\ +"(7, 6, 2);\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 7);\n",\ +"(1, 3, 4, 7);\n",\ +"(1, 4, 5, 7);\n",\ +"(1, 5, 6, 7);\n",\ +"(1, 6, 2, 7);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 1.5 P7, -0.5 P1 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"{ 1 P7 };\n",\ +"\n",\ +"\n",\ +"\n",\ +"freeset\n",\ +"1 7 2 3;\n",\ +"\n",\ +"freeset\n",\ +"1 7 3 4;\n",\ +"\n",\ +"freeset\n",\ +"1 7 4 5;\n",\ +"\n",\ +"freeset\n",\ +"1 7 5 6;\n",\ +"\n",\ +"freeset\n",\ +"1 7 6 2;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"four Tetrahedron non convex (6)\"\n",\ +"\n",\ +"quality 6\n",\ +"flags l;\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 1, 0) { 0.5 };\n",\ +"(0.5, 0, -1) { 0.5 };\n",\ +"(0.5, 0.3, -0.3) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(1, 5, 4) del;\n",\ +"(1, 3, 5) del;\n",\ +"\n",\ +"\n",\ +"newpoints\n",\ +"(0.095, 0.003, -0.003)\n",\ +" { 0.9 X1, 0.09 X2, 0.01 X5 }\n",\ +" { 0.9 Y1, 0.09 Y2, 0.01 Y5 }\n",\ +" { 0.9 Z1, 0.09 Z2, 0.01 Z5 };\n",\ +"\n",\ +"newfaces\n",\ +"(6, 2, 3) del;\n",\ +"(6, 4, 2) del;\n",\ +"(6, 5, 4) del;\n",\ +"(6, 3, 5) del;\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 6);\n",\ +"(1, 4, 2, 6);\n",\ +"(1, 5, 4, 6);\n",\ +"(1, 3, 5, 6);\n",\ +"\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1.499 P6, -0.5 P1, 0.001 P2 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"\n",\ +"\n",\ +"\n",\ +"freeset\n",\ +"1 6 2 3;\n",\ +"\n",\ +"freeset\n",\ +"1 6 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 6 5 4;\n",\ +"\n",\ +"freeset\n",\ +"1 6 4 2;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"four Tetrahedron non convex (6)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 1, 0) { 0.5 };\n",\ +"(0.5, 0, -1) { 0.5 };\n",\ +"(0.5, 0.4, -0.4) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(4, 5, 2) del;\n",\ +"(5, 3, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.925, 0.02, -0.02)\n",\ +" { 0.05 X1, 0.9 X2, 0.05 X5 }\n",\ +" { 0.05 Y1, 0.9 Y2, 0.05 Y5 }\n",\ +" { 0.05 Z1, 0.9 Z2, 0.05 Z5 };\n",\ +"\n",\ +"newfaces\n",\ +"(3, 1, 6);\n",\ +"(1, 4, 6);\n",\ +"(4, 5, 6);\n",\ +"(5, 3, 6);\n",\ +"\n",\ +"elements\n",\ +"(3, 1, 2, 6);\n",\ +"(1, 4, 2, 6);\n",\ +"(4, 5, 2, 6);\n",\ +"(5, 3, 2, 6);\n",\ +"\n",\ +"orientations\n",\ +"(3, 1, 2, 5);\n",\ +"(1, 4, 2, 5);\n",\ +"(2, 4, 5, 1);\n",\ +"(3, 2, 5, 1);\n",\ +"(5, 4, 2, 3);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1.5 P6, -0.5 P2 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"{ 1 P6 };\n",\ +"\n",\ +"freeset\n",\ +"3 1 2 6;\n",\ +"\n",\ +"freeset\n",\ +"1 4 2 6;\n",\ +"\n",\ +"freeset\n",\ +"4 5 2 6;\n",\ +"\n",\ +"freeset\n",\ +"5 3 2 6;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"three Tetrahedron non convex (4)\"\n",\ +"\n",\ +"quality 4\n",\ +"flags l;\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 1, 0) { 0.5 };\n",\ +"(0.5, 0, -1) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(1, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.25, -0.25)\n",\ +" { 0.25 X1, 0.25 X2, 0.25 X3, 0.25 X4 }\n",\ +" { 0.25 Y1, 0.25 Y2, 0.25 Y3, 0.25 Y4 }\n",\ +" { 0.25 Z1, 0.25 Z2, 0.25 Z3, 0.25 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(5, 2, 3);\n",\ +"(5, 4, 2);\n",\ +"(5, 3, 4);\n",\ +"\n",\ +"elements\n",\ +"(2, 3, 1, 5);\n",\ +"(3, 4, 1, 5);\n",\ +"(4, 2, 1, 5;\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 4, 3);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.5 P5, -0.5 P1 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"freeset\n",\ +"1 4 2 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"three Tetrahedron non convex (6)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 1, 0) { 0.5 };\n",\ +"(0.5, 0, -1) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(1, 3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.2, 0.1, -0.1)\n",\ +" { 0.7 X1, 0.1 X2, 0.1 X3, 0.1 X4 }\n",\ +" { 0.7 Y1, 0.1 Y2, 0.1 Y3, 0.1 Y4 }\n",\ +" { 0.7 Z1, 0.1 Z2, 0.1 Z3, 0.1 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(5, 2, 3);\n",\ +"(5, 4, 2);\n",\ +"(5, 3, 4);\n",\ +"\n",\ +"elements\n",\ +"(2, 3, 1, 5);\n",\ +"(3, 4, 1, 5);\n",\ +"(4, 2, 1, 5;\n",\ +"\n",\ +"orientations\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.5 P5, -0.5 P1 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 3 4 5;\n",\ +"\n",\ +"freeset\n",\ +"1 4 2 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"four Tetrahedron non convex (6)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 1, 0) { 0.5 };\n",\ +"(0.5, 0, -1) { 0.5 };\n",\ +"(0.5, 0.4, -0.4) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"(4, 5, 2) del;\n",\ +"(5, 3, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.7, 0.08, -0.08) { 0.6 X2, 0.2 X5 } { 0.2 Y5 } { 0.2 Z5 };\n",\ +"\n",\ +"newfaces\n",\ +"(3, 1, 6);\n",\ +"(1, 4, 6);\n",\ +"(4, 5, 6);\n",\ +"(5, 3, 6);\n",\ +"\n",\ +"elements\n",\ +"(3, 1, 2, 6);\n",\ +"(1, 4, 2, 6);\n",\ +"(4, 5, 2, 6);\n",\ +"(5, 3, 2, 6);\n",\ +"\n",\ +"\n",\ +"orientations\n",\ +"(3, 1, 2, 5);\n",\ +"(5, 1, 2, 4);\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 1, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, 0, -1) { 1 X4 } { 1 Y4 } { 1 Z4 };\n",\ +"(0.5, 0.4, -0.4) { 1 X5 } { 1 Y5 } { 1 Z5 };\n",\ +"(0.55, 0.12, -0.12) { 0.4 X2, 0.3 X5 } { 0.3 Y5 } { 0.3 Z5 };\n",\ +"\n",\ +"freeset\n",\ +"3 1 2 6;\n",\ +"\n",\ +"freeset\n",\ +"1 4 2 6;\n",\ +"\n",\ +"freeset\n",\ +"4 5 2 6;\n",\ +"\n",\ +"freeset\n",\ +"5 3 2 6;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron 2 in 60 (12)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 0.5 };\n",\ +"(0.5, 1, 0) { 0.5 };\n",\ +"(0.5, 0, -1) { 0.5 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.1, -0.1)\n",\ +" { 0.4 X1, 0.4 X2, 0.1 X3, 0.1 X4 }\n",\ +" { 0.4 Y1, 0.4 Y2, 0.1 Y3, 0.1 Y4 }\n",\ +" { 0.4 Z1, 0.4 Z2, 0.1 Z3, 0.1 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(5, 2, 3);\n",\ +"(5, 3, 1);\n",\ +"(5, 4, 2);\n",\ +"(5, 1, 4);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 5);\n",\ +"(1, 2, 5, 4);\n",\ +"\n",\ +"freezone2\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1.5 P5, -0.25 P1, -0.25 P2 };\n",\ +"\n",\ +"freezonelimit\n",\ +"{ 1 P1 };\n",\ +"{ 1 P2 };\n",\ +"{ 1 P3 };\n",\ +"{ 1 P4 };\n",\ +"{ 1 P5 };\n",\ +"\n",\ +"freeset\n",\ +"1 2 3 5;\n",\ +"\n",\ +"freeset\n",\ +"1 2 4 5;\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Tetrahedron 120, but more than 180 (13)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 };\n",\ +"(0.5, 0.866, 0) { 1 };\n",\ +"(0.5, -0.866, 0) { 1 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"(1, 4, 2);\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0, -0.3) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ +"\n",\ +"newfaces\n",\ +"(1, 5, 3);\n",\ +"(3, 5, 2);\n",\ +"(2, 5, 1);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 5);\n",\ +"\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, -0.1, -0.4) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4} { 0.5 Z3, 0.5 Z4 };\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Free Tetrahedron (14)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1.0 };\n",\ +"(0.5, 0.866, 0) { 1.0 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.288, -0.2) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ +"\n",\ +"newfaces\n",\ +"(4, 1, 2);\n",\ +"(4, 2, 3);\n",\ +"(4, 3, 1);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, 0.288, -0.25) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Free Tetrahedron (15)\"\n",\ +"\n",\ +"quality 100\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1.0 };\n",\ +"(0.5, 0.866, 0) { 1.0 };\n",\ +"\n",\ +"mapfaces\n",\ +"(1, 2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.288, -0.1) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ +"\n",\ +"newfaces\n",\ +"(4, 1, 2);\n",\ +"(4, 2, 3);\n",\ +"(4, 3, 1);\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3, 4);\n",\ +"\n",\ +"freezone\n",\ +"(0, 0, 0);\n",\ +"(1, 0, 0) { 1 X2 } { } { };\n",\ +"(0.5, 0.866, 0) { 1 X3 } { 1 Y3 } { };\n",\ +"(0.5, 0.288, -0.15) { 0.333 X2, 0.333 X3 } { 0.333 Y3 } { };\n",\ +"\n",\ +"endrule\n", +0}; +} diff --git a/libsrc/meshing/topology.cpp b/libsrc/meshing/topology.cpp new file mode 100644 index 00000000..26ef075e --- /dev/null +++ b/libsrc/meshing/topology.cpp @@ -0,0 +1,1752 @@ +#include +#include "meshing.hpp" + +namespace netgen +{ + template + void QuickSortRec (FlatArray & data, + int left, int right) + { + int i = left; + int j = right; + T midval = data[(left+right)/2]; + + do + { + while (data[i] < midval) i++; + while (midval < data[j]) j--; + + if (i <= j) + { + Swap (data[i], data[j]); + i++; j--; + } + } + while (i <= j); + if (left < j) QuickSortRec (data, left, j); + if (i < right) QuickSortRec (data, i, right); + } + + template + void QuickSort (FlatArray & data) + { + if (data.Size() > 1) + QuickSortRec (data, 0, data.Size()-1); + } + + + + + + + MeshTopology :: MeshTopology (const Mesh & amesh) + : mesh(amesh) + { + buildedges = 1; + buildfaces = 1; + vert2element = 0; + vert2surfelement = 0; + vert2segment = 0; + timestamp = -1; + } + + MeshTopology :: ~MeshTopology () + { + delete vert2element; + delete vert2surfelement; + delete vert2segment; + } + + void MeshTopology :: Update() + { + static int timer = NgProfiler::CreateTimer ("topology"); + NgProfiler::RegionTimer reg (timer); + +#ifdef PARALLEL + // ParallelMeshTopology & paralleltop = mesh.GetParallelTopology(); +#endif + + + if (timestamp > mesh.GetTimeStamp()) return; + + int ne = mesh.GetNE(); + int nse = mesh.GetNSE(); + int nseg = mesh.GetNSeg(); + int np = mesh.GetNP(); + int nv = mesh.GetNV(); + int nfa = 0; + int ned = edge2vert.Size(); + + if (id == 0) + PrintMessage (3, "Update mesh topology"); + + (*testout) << " UPDATE MESH TOPOLOGY " << endl; + (*testout) << "ne = " << ne << endl; + (*testout) << "nse = " << nse << endl; + (*testout) << "nseg = " << nseg << endl; + (*testout) << "np = " << np << endl; + (*testout) << "nv = " << nv << endl; + + delete vert2element; + delete vert2surfelement; + delete vert2segment; + + Array cnt(nv); + Array vnums; + + /* + generate: + vertex to element + vertex to surface element + vertex to segment + */ + + + cnt = 0; + for (ElementIndex ei = 0; ei < ne; ei++) + { + const Element & el = mesh[ei]; + for (int j = 0; j < el.GetNV(); j++) + cnt[el[j]]++; + } + + vert2element = new TABLE (cnt); + for (ElementIndex ei = 0; ei < ne; ei++) + { + const Element & el = mesh[ei]; + for (int j = 0; j < el.GetNV(); j++) + vert2element->AddSave (el[j], ei); + } + + cnt = 0; + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = mesh[sei]; + for (int j = 0; j < el.GetNV(); j++) + cnt[el[j]]++; + } + + vert2surfelement = new TABLE (cnt); + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = mesh[sei]; + for (int j = 0; j < el.GetNV(); j++) + vert2surfelement->AddSave (el[j], sei+1); + } + + cnt = 0; + for (int i = 1; i <= nseg; i++) + { + const Segment & seg = mesh.LineSegment(i); + cnt[seg[0]]++; + cnt[seg[1]]++; + } + + vert2segment = new TABLE (cnt); + for (int i = 1; i <= nseg; i++) + { + const Segment & seg = mesh.LineSegment(i); + vert2segment->AddSave (seg[0], i); + vert2segment->AddSave (seg[1], i); + } + + if (buildedges) + { + static int timer1 = NgProfiler::CreateTimer ("topology::buildedges"); + NgProfiler::RegionTimer reg1 (timer1); + + if (id == 0) + PrintMessage (5, "Update edges "); + + edges.SetSize(ne); + surfedges.SetSize(nse); + segedges.SetSize(nseg); + + for (int i = 0; i < ne; i++) + for (int j = 0; j < 12; j++) + edges[i][j].nr = -1; + for (int i = 0; i < nse; i++) + for (int j = 0; j < 4; j++) + surfedges[i][j].nr = -1; + + // keep existing edges + cnt = 0; + for (int i = 0; i < edge2vert.Size(); i++) + cnt[edge2vert[i][0]]++; + TABLE vert2edge (cnt); + for (int i = 0; i < edge2vert.Size(); i++) + vert2edge.AddSave (edge2vert[i][0], i+1); + + // ensure all coarse grid and intermediate level edges + cnt = 0; + for (int i = mesh.mlbetweennodes.Begin(); i < mesh.mlbetweennodes.End(); i++) + { + INDEX_2 parents = Sort (mesh.mlbetweennodes[i]); + if (parents[0] >= PointIndex::BASE) cnt[parents[0]]++; + } + TABLE vert2vertcoarse (cnt); + for (int i = mesh.mlbetweennodes.Begin(); i < mesh.mlbetweennodes.End(); i++) + { + INDEX_2 parents = Sort (mesh.mlbetweennodes[i]); + if (parents[0] > PointIndex::BASE) vert2vertcoarse.AddSave (parents[0], parents[1]); + } + + Array edgenr(nv); + Array edgeflag(nv); + Array vertex2; + + edgeflag = PointIndex::BASE-1; + + ned = edge2vert.Size(); + + for (int i = PointIndex::BASE; i < nv+PointIndex::BASE; i++) + { + vertex2.SetSize (0); + + for (int j = 0; j < vert2edge[i].Size(); j++) + { + int ednr = vert2edge[i][j]; + int i2 = edge2vert.Get(ednr)[1]; + edgeflag[i2] = i; + edgenr[i2] = ednr; + } + + for (int j = 0; j < vert2vertcoarse[i].Size(); j++) + { + int v2 = vert2vertcoarse[i][j]; + if (edgeflag[v2] < i) + { + edgeflag[v2] = i; + vertex2.Append (v2); + } + } + + FlatArray v2els = (*vert2element)[i]; + for (int j = 0; j < v2els.Size(); j++) + { + const Element & el = mesh[v2els[j]]; + int neledges = GetNEdges (el.GetType()); + const ELEMENT_EDGE * eledges = GetEdges0 (el.GetType()); + for (int k = 0; k < neledges; k++) + { + INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]); + edge.Sort(); + if (edge.I1() != i) continue; + + if (edgeflag[edge.I2()] < i) + { + vertex2.Append (edge.I2()); + edgeflag[edge.I2()] = i; + } + } + } + + for (int j = 0; j < (*vert2surfelement)[i].Size(); j++) + { + int elnr = (*vert2surfelement)[i][j]; + const Element2d & el = mesh.SurfaceElement (elnr); + + int neledges = GetNEdges (el.GetType()); + const ELEMENT_EDGE * eledges = GetEdges0 (el.GetType()); + + for (int k = 0; k < neledges; k++) + { + INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]); + edge.Sort(); + if (edge.I1() != i) continue; + + if (edgeflag[edge.I2()] < i) + { + vertex2.Append (edge.I2()); + edgeflag[edge.I2()] = i; + } + } + } + + for (int j = 0; j < (*vert2segment)[i].Size(); j++) + { + int elnr = (*vert2segment)[i][j]; + const Segment & el = mesh.LineSegment (elnr); + + INDEX_2 edge(el[0], el[1]); + edge.Sort(); + if (edge.I1() != i) continue; + + if (edgeflag[edge.I2()] < i) + { + vertex2.Append (edge.I2()); + edgeflag[edge.I2()] = i; + } + } + + QuickSort (vertex2); + for (int j = 0; j < vertex2.Size(); j++) + { + edgenr[vertex2[j]] = ++ned; + edge2vert.Append (INDEX_2 (i, vertex2[j])); + } + + + for (int j = 0; j < (*vert2element)[i].Size(); j++) + { + ElementIndex elnr = (*vert2element)[i][j]; + const Element & el = mesh[elnr]; + + int neledges = GetNEdges (el.GetType()); + const ELEMENT_EDGE * eledges = GetEdges0 (el.GetType()); + + for (int k = 0; k < neledges; k++) + { + INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]); + + int edgedir = (edge.I1() > edge.I2()); + if (edgedir) swap (edge.I1(), edge.I2()); + + if (edge.I1() != i) continue; + + int edgenum = edgenr[edge.I2()]; + /* + if (edgedir) edgenum *= -1; + edges[elnr][k] = edgenum; + */ + edges[elnr][k].nr = edgenum-1; + edges[elnr][k].orient = edgedir; + } + } + + for (int j = 0; j < (*vert2surfelement)[i].Size(); j++) + { + int elnr = (*vert2surfelement)[i][j]; + const Element2d & el = mesh.SurfaceElement (elnr); + + int neledges = GetNEdges (el.GetType()); + const ELEMENT_EDGE * eledges = GetEdges0 (el.GetType()); + + for (int k = 0; k < neledges; k++) + { + INDEX_2 edge(el[eledges[k][0]], el[eledges[k][1]]); + + int edgedir = (edge.I1() > edge.I2()); + if (edgedir) swap (edge.I1(), edge.I2()); + + if (edge.I1() != i) continue; + + int edgenum = edgenr[edge.I2()]; + // if (edgedir) edgenum *= -1; + // surfedges.Elem(elnr)[k] = edgenum; + surfedges.Elem(elnr)[k].nr = edgenum-1; + surfedges.Elem(elnr)[k].orient = edgedir; + + } + } + + for (int j = 0; j < (*vert2segment)[i].Size(); j++) + { + int elnr = (*vert2segment)[i][j]; + const Segment & el = mesh.LineSegment (elnr); + + INDEX_2 edge(el[0], el[1]); + + int edgedir = (edge.I1() > edge.I2()); + if (edgedir) swap (edge.I1(), edge.I2()); + + if (edge.I1() != i) continue; + + int edgenum = edgenr[edge.I2()]; + /* + if (edgedir) edgenum *= -1; + segedges.Elem(elnr) = edgenum; + */ + segedges.Elem(elnr).nr = edgenum-1; + segedges.Elem(elnr).orient = edgedir; + } + } + } + + + + // generate faces + if (buildfaces) + { + static int timer2 = NgProfiler::CreateTimer ("topology::buildfaces"); + static int timer2a = NgProfiler::CreateTimer ("topology::buildfacesa"); + static int timer2b = NgProfiler::CreateTimer ("topology::buildfacesb"); + static int timer2c = NgProfiler::CreateTimer ("topology::buildfacesc"); + static int timer2d = NgProfiler::CreateTimer ("topology::buildfacesd"); + NgProfiler::RegionTimer reg2 (timer2); + + if (id == 0) + PrintMessage (5, "Update faces "); + + NgProfiler::StartTimer (timer2a); + + faces.SetSize(ne); + surffaces.SetSize(nse); + + int oldnfa = face2vert.Size(); + + cnt = 0; + for (int i = 0; i < face2vert.Size(); i++) + cnt[face2vert[i][0]]++; + TABLE vert2oldface(cnt); + for (int i = 0; i < face2vert.Size(); i++) + vert2oldface.AddSave (face2vert[i][0], i); + + + for (int elnr = 0; elnr < ne; elnr++) + for (int j = 0; j < 6; j++) + faces[elnr][j].fnr = -1; + + + int max_face_on_vertex = 0; + for (int i = PointIndex::BASE; i < nv+PointIndex::BASE; i++) + { + int onv = vert2oldface[i].Size() + (*vert2element)[i].Size() + (*vert2surfelement)[i].Size(); + max_face_on_vertex = max (onv, max_face_on_vertex); + } + + + + + + NgProfiler::StopTimer (timer2a); + NgProfiler::StartTimer (timer2b); + + /* + for (int pass = 1; pass <= 2; pass++) + { + cout << "pass = " << pass << endl; + nfa = oldnfa; + for (int v = PointIndex::BASE; v < nv+PointIndex::BASE; v++) + { + int first_fa = nfa; + + INDEX_3_CLOSED_HASHTABLE vert2face(2*max_face_on_vertex+10); + + for (int j = 0; j < vert2oldface[v].Size(); j++) + { + int fnr = vert2oldface[v][j]; + INDEX_3 face (face2vert[fnr].I1(), + face2vert[fnr].I2(), + face2vert[fnr].I3()); + vert2face.Set (face, fnr+1); + } + + + if (pass == 2) + { + // *testout << "pass 2, nfa = " << nfa << "; face2vert.Size() = " << face2vert.Size() << endl; + for (int j = nfa; j < face2vert.Size(); j++) + { + if (face2vert[j][0] == v) + { + INDEX_3 face (face2vert[j].I1(), + face2vert[j].I2(), + face2vert[j].I3()); + vert2face.Set (face, j+1); + nfa++; + } + else + break; + } + } + + // cout << "inherited faces: " << endl << vert2face << endl; + + + for (int j = 0; j < (*vert2element)[v].Size(); j++) + { + // NgProfiler::RegionTimer reg3 (timer2d); + + ElementIndex elnr = (*vert2element)[v][j]; + const Element & el = mesh[elnr]; + + int nelfaces = GetNFaces (el.GetType()); + const ELEMENT_FACE * elfaces = GetFaces0 (el.GetType()); + + for (int j = 0; j < nelfaces; j++) + if (elfaces[j][3] < 0) + + { // triangle + int facenum, facedir; + INDEX_3 face(el[elfaces[j][0]], el[elfaces[j][1]], + el[elfaces[j][2]]); + + facedir = 0; + if (face.I1() > face.I2()) + { swap (face.I1(), face.I2()); facedir += 1; } + if (face.I2() > face.I3()) + { swap (face.I2(), face.I3()); facedir += 2; } + if (face.I1() > face.I2()) + { swap (face.I1(), face.I2()); facedir += 4; } + + if (face.I1() != v) continue; + + if (vert2face.Used (face)) + facenum = vert2face.Get(face); + else + { + if (pass == 2) cout << "hier in pass 2" << endl; + nfa++; + vert2face.Set (face, nfa); + facenum = nfa; + + INDEX_4 hface(face.I1(),face.I2(),face.I3(),0); + face2vert.Append (hface); + } + faces[elnr][j] = 8*(facenum-1)+facedir+1; + } + + else + + { + // quad + int facenum, facedir; + INDEX_4Q face4(el[elfaces[j][0]], el[elfaces[j][1]], + el[elfaces[j][2]], el[elfaces[j][3]]); + + facedir = 0; + if (min2 (face4.I1(), face4.I2()) > + min2 (face4.I4(), face4.I3())) + { // z - flip + facedir += 1; + swap (face4.I1(), face4.I4()); + swap (face4.I2(), face4.I3()); + } + if (min2 (face4.I1(), face4.I4()) > + min2 (face4.I2(), face4.I3())) + { // x - flip + facedir += 2; + swap (face4.I1(), face4.I2()); + swap (face4.I3(), face4.I4()); + } + if (face4.I2() > face4.I4()) + { // diagonal flip + facedir += 4; + swap (face4.I2(), face4.I4()); + } + + + INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); + + if (face.I1() != v) continue; + + if (vert2face.Used (face)) + { + facenum = vert2face.Get(face); + } + else + { + if (pass == 2) cout << "hier in pass 2" << endl; + nfa++; + vert2face.Set (face, nfa); + facenum = nfa; + + INDEX_4 hface(face4.I1(),face4.I2(),face4.I3(),face4.I4()); + face2vert.Append (hface); + } + + faces[elnr][j] = 8*(facenum-1)+facedir+1; + } + } + + for (int j = 0; j < (*vert2surfelement)[v].Size(); j++) + { + int elnr = (*vert2surfelement)[v][j]; + // cout << "surfelnr = " << elnr << endl; + const Element2d & el = mesh.SurfaceElement (elnr); + + const ELEMENT_FACE * elfaces = GetFaces1 (el.GetType()); + + if (elfaces[0][3] == 0) + + { // triangle + + int facenum; + int facedir; + + INDEX_3 face(el.PNum(elfaces[0][0]), + el.PNum(elfaces[0][1]), + el.PNum(elfaces[0][2])); + + // cout << "face = " << face << endl; + + facedir = 0; + if (face.I1() > face.I2()) + { + swap (face.I1(), face.I2()); + facedir += 1; + } + if (face.I2() > face.I3()) + { + swap (face.I2(), face.I3()); + facedir += 2; + } + if (face.I1() > face.I2()) + { + swap (face.I1(), face.I2()); + facedir += 4; + } + + if (face.I1() != v) continue; + + if (vert2face.Used (face)) + facenum = vert2face.Get(face); + else + { + nfa++; + vert2face.Set (face, nfa); + facenum = nfa; + + INDEX_4 hface(face.I1(),face.I2(),face.I3(),0); + face2vert.Append (hface); + } + + surffaces.Elem(elnr) = 8*(facenum-1)+facedir+1; + } + + else + + { + // quad + int facenum; + int facedir; + + INDEX_4Q face4(el.PNum(elfaces[0][0]), + el.PNum(elfaces[0][1]), + el.PNum(elfaces[0][2]), + el.PNum(elfaces[0][3])); + + facedir = 0; + if (min2 (face4.I1(), face4.I2()) > + min2 (face4.I4(), face4.I3())) + { // z - orientation + facedir += 1; + swap (face4.I1(), face4.I4()); + swap (face4.I2(), face4.I3()); + } + if (min2 (face4.I1(), face4.I4()) > + min2 (face4.I2(), face4.I3())) + { // x - orientation + facedir += 2; + swap (face4.I1(), face4.I2()); + swap (face4.I3(), face4.I4()); + } + if (face4.I2() > face4.I4()) + { + facedir += 4; + swap (face4.I2(), face4.I4()); + } + + INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); + if (face.I1() != v) continue; + + if (vert2face.Used (face)) + facenum = vert2face.Get(face); + else + { + nfa++; + vert2face.Set (face, nfa); + facenum = nfa; + + INDEX_4 hface(face4.I1(),face4.I2(),face4.I3(),face4.I3()); + face2vert.Append (hface); + } + + surffaces.Elem(elnr) = 8*(facenum-1)+facedir+1; + } + } + + // sort faces + // *testout << "faces = " << face2vert << endl; + if (pass == 1) + { + // *testout << "pass1, sort from " << first_fa << " to " << nfa << endl; + for (int i = first_fa; i < nfa; i++) + for (int j = first_fa+1; j < nfa; j++) + if (face2vert[j] < face2vert[j-1]) + Swap (face2vert[j-1], face2vert[j]); + } + // *testout << "faces, sorted = " << face2vert << endl; + } + + + face2vert.SetAllocSize (nfa); + } + */ + + /* + // timing tests + static int timer_touch = NgProfiler::CreateTimer ("topology::buildfaces - touch els"); + static int timer_touch2 = NgProfiler::CreateTimer ("topology::buildfaces - touch els vert"); + + NgProfiler::StartTimer (timer_touch); + + int sum = 0; + for (ElementIndex ei = 0; ei < mesh.GetNE(); ei++) + { + const Element & el = mesh[ei]; + for (int j = 0; j < el.GetNP(); j++) + sum += el[j]; + } + + NgProfiler::StopTimer (timer_touch); + + NgProfiler::StartTimer (timer_touch2); + + for (int v = PointIndex::BASE; v < nv+PointIndex::BASE; v++) + { + INDEX_3_CLOSED_HASHTABLE vert2face(2*max_face_on_vertex+10); + + for (int pass = 1; pass <= 2; pass++) + for (int j = 0; j < (*vert2element)[v].Size(); j++) + { + // NgProfiler::RegionTimer reg3 (timer2d); + + ElementIndex elnr = (*vert2element)[v][j]; + const Element & el = mesh[elnr]; + + + int nelfaces = GetNFaces (el.GetType()); + const ELEMENT_FACE * elfaces = GetFaces0 (TET); + + for (int j = 0; j < 4; j++) + { // triangle + INDEX_3 face(el[elfaces[j][0]], el[elfaces[j][1]], + el[elfaces[j][2]]); + + int facedir = 0; + if (face.I1() > face.I2()) + { swap (face.I1(), face.I2()); facedir += 1; } + if (face.I2() > face.I3()) + { swap (face.I2(), face.I3()); facedir += 2; } + if (face.I1() > face.I2()) + { swap (face.I1(), face.I2()); facedir += 4; } + + sum += face.I1(); + sum += face.I1() < face.I2(); + } + } + } + + NgProfiler::StopTimer (timer_touch2); + *testout << "sum" << sum << endl; + */ + + + + nfa = oldnfa; + for (int v = PointIndex::BASE; v < nv+PointIndex::BASE; v++) + { + int first_fa = nfa; + + INDEX_3_CLOSED_HASHTABLE vert2face(2*max_face_on_vertex+10); + + for (int j = 0; j < vert2oldface[v].Size(); j++) + { + int fnr = vert2oldface[v][j]; + INDEX_3 face (face2vert[fnr].I1(), + face2vert[fnr].I2(), + face2vert[fnr].I3()); + vert2face.Set (face, fnr+1); + } + + + for (int pass = 1; pass <= 2; pass++) + { + + if (pass == 2) + { + for (int j = first_fa; j < face2vert.Size(); j++) + { + if (face2vert[j][0] == v) + { + INDEX_3 face (face2vert[j].I1(), + face2vert[j].I2(), + face2vert[j].I3()); + vert2face.Set (face, j+1); + } + else + break; + } + } + + + + for (int j = 0; j < (*vert2element)[v].Size(); j++) + { + // NgProfiler::RegionTimer reg3 (timer2d); + + ElementIndex elnr = (*vert2element)[v][j]; + const Element & el = mesh[elnr]; + + int nelfaces = GetNFaces (el.GetType()); + const ELEMENT_FACE * elfaces = GetFaces0 (el.GetType()); + + for (int j = 0; j < nelfaces; j++) + if (elfaces[j][3] < 0) + + { // triangle + INDEX_3 face(el[elfaces[j][0]], el[elfaces[j][1]], + el[elfaces[j][2]]); + + int facedir = 0; + if (face.I1() > face.I2()) + { swap (face.I1(), face.I2()); facedir += 1; } + if (face.I2() > face.I3()) + { swap (face.I2(), face.I3()); facedir += 2; } + if (face.I1() > face.I2()) + { swap (face.I1(), face.I2()); facedir += 4; } + + if (face.I1() != v) continue; + + if (pass == 1) + { + if (!vert2face.Used (face)) + { + nfa++; + vert2face.Set (face, nfa); + INDEX_4 hface(face.I1(),face.I2(),face.I3(),0); + face2vert.Append (hface); + } + } + else + { + int facenum = vert2face.Get(face); + // faces[elnr][j] = 8*(facenum-1)+facedir+1; + faces[elnr][j].fnr = facenum-1; + faces[elnr][j].forient = facedir; + } + } + + else + + { + // quad + int facenum; + INDEX_4Q face4(el[elfaces[j][0]], el[elfaces[j][1]], + el[elfaces[j][2]], el[elfaces[j][3]]); + + int facedir = 0; + if (min2 (face4.I1(), face4.I2()) > + min2 (face4.I4(), face4.I3())) + { // z - flip + facedir += 1; + swap (face4.I1(), face4.I4()); + swap (face4.I2(), face4.I3()); + } + if (min2 (face4.I1(), face4.I4()) > + min2 (face4.I2(), face4.I3())) + { // x - flip + facedir += 2; + swap (face4.I1(), face4.I2()); + swap (face4.I3(), face4.I4()); + } + if (face4.I2() > face4.I4()) + { // diagonal flip + facedir += 4; + swap (face4.I2(), face4.I4()); + } + + + INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); + + if (face.I1() != v) continue; + + if (vert2face.Used (face)) + { + facenum = vert2face.Get(face); + } + else + { + if (pass == 2) cout << "hier in pass 2" << endl; + nfa++; + vert2face.Set (face, nfa); + facenum = nfa; + + INDEX_4 hface(face4.I1(),face4.I2(),face4.I3(),face4.I4()); + face2vert.Append (hface); + } + + // faces[elnr][j] = 8*(facenum-1)+facedir+1; + faces[elnr][j].fnr = facenum-1; + faces[elnr][j].forient = facedir; + } + } + + for (int j = 0; j < (*vert2surfelement)[v].Size(); j++) + { + int elnr = (*vert2surfelement)[v][j]; + // cout << "surfelnr = " << elnr << endl; + const Element2d & el = mesh.SurfaceElement (elnr); + + const ELEMENT_FACE * elfaces = GetFaces1 (el.GetType()); + + if (elfaces[0][3] == 0) + + { // triangle + + int facenum; + int facedir; + + INDEX_3 face(el.PNum(elfaces[0][0]), + el.PNum(elfaces[0][1]), + el.PNum(elfaces[0][2])); + + // cout << "face = " << face << endl; + + facedir = 0; + if (face.I1() > face.I2()) + { + swap (face.I1(), face.I2()); + facedir += 1; + } + if (face.I2() > face.I3()) + { + swap (face.I2(), face.I3()); + facedir += 2; + } + if (face.I1() > face.I2()) + { + swap (face.I1(), face.I2()); + facedir += 4; + } + + if (face.I1() != v) continue; + + if (vert2face.Used (face)) + facenum = vert2face.Get(face); + else + { + nfa++; + vert2face.Set (face, nfa); + facenum = nfa; + + INDEX_4 hface(face.I1(),face.I2(),face.I3(),0); + face2vert.Append (hface); + } + + // surffaces.Elem(elnr) = 8*(facenum-1)+facedir+1; + surffaces.Elem(elnr).fnr = facenum-1; + surffaces.Elem(elnr).forient = facedir; + } + + else + + { + // quad + int facenum; + int facedir; + + INDEX_4Q face4(el.PNum(elfaces[0][0]), + el.PNum(elfaces[0][1]), + el.PNum(elfaces[0][2]), + el.PNum(elfaces[0][3])); + + facedir = 0; + if (min2 (face4.I1(), face4.I2()) > + min2 (face4.I4(), face4.I3())) + { // z - orientation + facedir += 1; + swap (face4.I1(), face4.I4()); + swap (face4.I2(), face4.I3()); + } + if (min2 (face4.I1(), face4.I4()) > + min2 (face4.I2(), face4.I3())) + { // x - orientation + facedir += 2; + swap (face4.I1(), face4.I2()); + swap (face4.I3(), face4.I4()); + } + if (face4.I2() > face4.I4()) + { + facedir += 4; + swap (face4.I2(), face4.I4()); + } + + INDEX_3 face(face4.I1(), face4.I2(), face4.I3()); + if (face.I1() != v) continue; + + if (vert2face.Used (face)) + facenum = vert2face.Get(face); + else + { + nfa++; + vert2face.Set (face, nfa); + facenum = nfa; + + INDEX_4 hface(face4.I1(),face4.I2(),face4.I3(),face4.I3()); + face2vert.Append (hface); + } + + // surffaces.Elem(elnr) = 8*(facenum-1)+facedir+1; + surffaces.Elem(elnr).fnr = facenum-1; + surffaces.Elem(elnr).forient = facedir; + } + } + + // sort faces + if (pass == 1) + { + for (int i = 0; i < nfa-first_fa; i++) + for (int j = first_fa+1; j < nfa-i; j++) + if (face2vert[j] < face2vert[j-1]) + Swap (face2vert[j-1], face2vert[j]); + } + } + } + + + face2vert.SetAllocSize (nfa); + + + + + + // *testout << "face2vert = " << endl << face2vert << endl; + + + + NgProfiler::StopTimer (timer2b); + NgProfiler::StartTimer (timer2c); + + + + + + face2surfel.SetSize (nfa); + face2surfel = 0; + for (int i = 1; i <= nse; i++) + face2surfel.Elem(GetSurfaceElementFace(i)) = i; + + /* + cout << "build table complete" << endl; + + cout << "faces = " << endl; + + cout << "face2vert = " << endl << face2vert << endl; + cout << "surffaces = " << endl << surffaces << endl; + cout << "face2surfel = " << endl << face2surfel << endl; + */ + + + surf2volelement.SetSize (nse); + for (int i = 1; i <= nse; i++) + { + surf2volelement.Elem(i)[0] = 0; + surf2volelement.Elem(i)[1] = 0; + } + for (int i = 1; i <= ne; i++) + for (int j = 0; j < 6; j++) + { + // int fnum = (faces.Get(i)[j]+7) / 8; + int fnum = faces.Get(i)[j].fnr+1; + if (fnum > 0 && face2surfel.Elem(fnum)) + { + int sel = face2surfel.Elem(fnum); + surf2volelement.Elem(sel)[1] = + surf2volelement.Elem(sel)[0]; + surf2volelement.Elem(sel)[0] = i; + } + } + + face2vert.SetAllocSize (face2vert.Size()); + + // face table complete + + +#ifdef PARALLEL + // (*testout) << " RESET Paralleltop" << endl; + // paralleltop.Reset (); +#endif + + Array face_els(nfa), face_surfels(nfa); + face_els = 0; + face_surfels = 0; + Array hfaces; + for (int i = 1; i <= ne; i++) + { + GetElementFaces (i, hfaces); + for (int j = 0; j < hfaces.Size(); j++) + face_els[hfaces[j]-1]++; + } + for (int i = 1; i <= nse; i++) + face_surfels[GetSurfaceElementFace (i)-1]++; + + + if (ne) + { + int cnt_err = 0; + for (int i = 0; i < nfa; i++) + { + /* + (*testout) << "face " << i << " has " << int(face_els[i]) << " els, " + << int(face_surfels[i]) << " surfels, tot = " + << face_els[i] + face_surfels[i] << endl; + */ + if (face_els[i] + face_surfels[i] == 1) + { + cnt_err++; +#ifdef PARALLEL + if ( ntasks > 1 ) + { + continue; + // if ( !paralleltop.DoCoarseUpdate() ) continue; + } + else +#endif + { + (*testout) << "illegal face : " << i << endl; + (*testout) << "points = " << face2vert[i] << endl; + (*testout) << "pos = "; + for (int j = 0; j < 4; j++) + if (face2vert[i].I(j+1) >= 1) + (*testout) << mesh[(PointIndex)face2vert[i].I(j+1)] << " "; + (*testout) << endl; + + FlatArray vertels = GetVertexElements (face2vert[i].I(1)); + for (int k = 0; k < vertels.Size(); k++) + { + int elfaces[10], orient[10]; + int nf = GetElementFaces (vertels[k]+1, elfaces, orient); + for (int l = 0; l < nf; l++) + if (elfaces[l] == i) + { + // (*testout) << "is face of element " << vertels[k] << endl; + + if (mesh.coarsemesh && mesh.hpelements->Size() == mesh.GetNE() ) + { + const HPRefElement & hpref_el = + (*mesh.hpelements) [ mesh[vertels[k]].hp_elnr]; + (*testout) << "coarse eleme = " << hpref_el.coarse_elnr << endl; + } + + } + } + } + } + } + + if (cnt_err && ntasks == 1) + cout << cnt_err << " elements are not matching !!!" << endl; + } + NgProfiler::StopTimer (timer2c); + } + + +#ifdef PARALLEL + if (id != 0) + { + // if ( paralleltop.DoCoarseUpdate() ) + // paralleltop.UpdateCoarseGrid(); + } +#endif + + + + /* + for (i = 1; i <= ne; i++) + { + (*testout) << "Element " << i << endl; + (*testout) << "PNums " << endl; + for( int l=1;l<=8;l++) *testout << mesh.VolumeElement(i).PNum(l) << "\t"; + *testout << endl; + (*testout) << "edges: " << endl; + for (j = 0; j < 9; j++) + (*testout) << edges.Elem(i)[j] << " "; + (*testout) << "faces: " << endl; + for (j = 0; j < 6; j++)m + (*testout) << faces.Elem(i)[j] << " "; + } + + for (i = 1; i <= nse; i++) + { + (*testout) << "SElement " << i << endl; + (*testout) << "PNums " << endl; + for( int l=1;l<=4;l++) *testout << mesh.SurfaceElement(i).PNum(l) << "\t"; + *testout << endl; + } + */ + timestamp = NextTimeStamp(); + } + + + + + + const Point3d * MeshTopology :: GetVertices (ELEMENT_TYPE et) + { + static Point3d segm_points [] = + { Point3d (1, 0, 0), + Point3d (0, 0, 0) }; + + static Point3d trig_points [] = + { Point3d ( 1, 0, 0 ), + Point3d ( 0, 1, 0 ), + Point3d ( 0, 0, 0 ) }; + + static Point3d quad_points [] = + { Point3d ( 0, 0, 0 ), + Point3d ( 1, 0, 0 ), + Point3d ( 1, 1, 0 ), + Point3d ( 0, 1, 0 ) }; + + static Point3d tet_points [] = + { Point3d ( 1, 0, 0 ), + Point3d ( 0, 1, 0 ), + Point3d ( 0, 0, 1 ), + Point3d ( 0, 0, 0 ) }; + + static Point3d pyramid_points [] = + { + Point3d ( 0, 0, 0 ), + Point3d ( 1, 0, 0 ), + Point3d ( 1, 1, 0 ), + Point3d ( 0, 1, 0 ), + Point3d ( 0, 0, 1-1e-7 ), + }; + + static Point3d prism_points[] = + { + Point3d ( 1, 0, 0 ), + Point3d ( 0, 1, 0 ), + Point3d ( 0, 0, 0 ), + Point3d ( 1, 0, 1 ), + Point3d ( 0, 1, 1 ), + Point3d ( 0, 0, 1 ) + }; + + + static Point3d hex_points [] = + { Point3d ( 0, 0, 0 ), + Point3d ( 1, 0, 0 ), + Point3d ( 1, 1, 0 ), + Point3d ( 0, 1, 0 ), + Point3d ( 0, 0, 1 ), + Point3d ( 1, 0, 1 ), + Point3d ( 1, 1, 1 ), + Point3d ( 0, 1, 1 ) }; + + + switch (et) + { + case SEGMENT: + case SEGMENT3: + return segm_points; + + case TRIG: + case TRIG6: + return trig_points; + + case QUAD: + case QUAD6: + case QUAD8: + return quad_points; + + case TET: + case TET10: + return tet_points; + + case PYRAMID: + return pyramid_points; + + case PRISM: + case PRISM12: + return prism_points; + + case HEX: + return hex_points; + default: + cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; + } + return 0; + } + + + + + + + + + void MeshTopology :: GetElementEdges (int elnr, Array & eledges) const + { + int ned = GetNEdges (mesh.VolumeElement(elnr).GetType()); + eledges.SetSize (ned); + for (int i = 0; i < ned; i++) + eledges[i] = edges.Get(elnr)[i].nr+1; + // eledges[i] = abs (edges.Get(elnr)[i]); + } + void MeshTopology :: GetElementFaces (int elnr, Array & elfaces, bool withorientation) const + { + int nfa = GetNFaces (mesh.VolumeElement(elnr).GetType()); + elfaces.SetSize (nfa); + + if (!withorientation) + + for (int i = 1; i <= nfa; i++) + { + // elfaces.Elem(i) = (faces.Get(elnr)[i-1]-1) / 8 + 1; + elfaces.Elem(i) = faces.Get(elnr)[i-1].fnr+1; + } + + else + { + cerr << "GetElementFaces with orientation currently not supported" << endl; + /* + for (int i = 1; i <= nfa; i++) + { + elfaces.Elem(i) = (faces.Get(elnr)[i-1]-1) / 8 + 1; + int orient = (faces.Get(elnr)[i-1]-1) % 8; + if(orient == 1 || orient == 2 || orient == 4 || orient == 7) + elfaces.Elem(i) *= -1; + } + */ + } + } + + void MeshTopology :: GetElementEdgeOrientations (int elnr, Array & eorient) const + { + int ned = GetNEdges (mesh.VolumeElement(elnr).GetType()); + eorient.SetSize (ned); + for (int i = 1; i <= ned; i++) + // eorient.Elem(i) = (edges.Get(elnr)[i-1] > 0) ? 1 : -1; + eorient.Elem(i) = (edges.Get(elnr)[i-1].orient) ? -1 : 1; + } + + void MeshTopology :: GetElementFaceOrientations (int elnr, Array & forient) const + { + int nfa = GetNFaces (mesh.VolumeElement(elnr).GetType()); + forient.SetSize (nfa); + for (int i = 1; i <= nfa; i++) + forient.Elem(i) = faces.Get(elnr)[i-1].forient; + // forient.Elem(i) = (faces.Get(elnr)[i-1]-1) % 8; + } + + + + int MeshTopology :: GetElementEdges (int elnr, int * eledges, int * orient) const + { + // int ned = GetNEdges (mesh.VolumeElement(elnr).GetType()); + + if (mesh.GetDimension()==3 || 1) + { + if (orient) + { + for (int i = 0; i < 12; i++) + { + /* + if (!edges.Get(elnr)[i]) return i; + eledges[i] = abs (edges.Get(elnr)[i]); + orient[i] = (edges.Get(elnr)[i] > 0 ) ? 1 : -1; + */ + if (edges.Get(elnr)[i].nr == -1) return i; + eledges[i] = edges.Get(elnr)[i].nr+1; + orient[i] = edges.Get(elnr)[i].orient ? -1 : 1; + } + } + else + { + for (int i = 0; i < 12; i++) + { + // if (!edges.Get(elnr)[i]) return i; + // eledges[i] = abs (edges.Get(elnr)[i]); + if (edges.Get(elnr)[i].nr == -1) return i; + eledges[i] = edges.Get(elnr)[i].nr+1; + + } + } + return 12; + } + else + { + throw NgException("rethink implementation"); + /* + if (orient) + { + for (i = 0; i < 4; i++) + { + if (!surfedges.Get(elnr)[i]) return i; + eledges[i] = abs (surfedges.Get(elnr)[i]); + orient[i] = (surfedges.Get(elnr)[i] > 0 ) ? 1 : -1; + } + } + else + { + if (!surfedges.Get(elnr)[i]) return i; + for (i = 0; i < 4; i++) + eledges[i] = abs (surfedges.Get(elnr)[i]); + } + */ + return 4; + // return GetSurfaceElementEdges (elnr, eledges, orient); + } + } + + int MeshTopology :: GetElementFaces (int elnr, int * elfaces, int * orient) const + { + // int nfa = GetNFaces (mesh.VolumeElement(elnr).GetType()); + if (orient) + { + for (int i = 0; i < 6; i++) + { + /* + if (!faces.Get(elnr)[i]) return i; + elfaces[i] = (faces.Get(elnr)[i]-1) / 8 + 1; + orient[i] = (faces.Get(elnr)[i]-1) % 8; + */ + if (faces.Get(elnr)[i].fnr == -1) return i; + elfaces[i] = faces.Get(elnr)[i].fnr+1; + orient[i] = faces.Get(elnr)[i].forient; + } + } + else + { + for (int i = 0; i < 6; i++) + { + // if (!faces.Get(elnr)[i]) return i; + // elfaces[i] = (faces.Get(elnr)[i]-1) / 8 + 1; + if (faces.Get(elnr)[i].fnr == -1) return i; + elfaces[i] = faces.Get(elnr)[i].fnr+1; + } + } + return 6; + } + + void MeshTopology :: GetSurfaceElementEdges (int elnr, Array & eledges) const + { + int ned = GetNEdges (mesh.SurfaceElement(elnr).GetType()); + eledges.SetSize (ned); + for (int i = 0; i < ned; i++) + // eledges[i] = abs (surfedges.Get(elnr)[i]); + eledges[i] = surfedges.Get(elnr)[i].nr+1; + } + + void MeshTopology :: GetEdges (SurfaceElementIndex elnr, Array & eledges) const + { + int ned = GetNEdges (mesh[elnr].GetType()); + eledges.SetSize (ned); + for (int i = 0; i < ned; i++) + // eledges[i] = abs (surfedges[elnr][i])-1; + eledges[i] = surfedges[elnr][i].nr; + } + + int MeshTopology :: GetSurfaceElementFace (int elnr) const + { + // return (surffaces.Get(elnr)-1) / 8 + 1; + return surffaces.Get(elnr).fnr+1; + } + + int MeshTopology :: GetFace (SurfaceElementIndex elnr) const + { + // return (surffaces[elnr]-1) / 8; + return surffaces[elnr].fnr; + } + + + void MeshTopology :: + GetSurfaceElementEdgeOrientations (int elnr, Array & eorient) const + { + int ned = GetNEdges (mesh.SurfaceElement(elnr).GetType()); + eorient.SetSize (ned); + for (int i = 0; i < ned; i++) + // eorient[i] = (surfedges.Get(elnr)[i] > 0) ? 1 : -1; + eorient[i] = (surfedges.Get(elnr)[i].orient) ? -1 : 1; + } + + int MeshTopology :: GetSurfaceElementFaceOrientation (int elnr) const + { + // return (surffaces.Get(elnr)-1) % 8; + return surffaces.Get(elnr).forient; + } + + int MeshTopology :: GetSurfaceElementEdges (int elnr, int * eledges, int * orient) const + { + int i; + if (mesh.GetDimension() == 3 || 1) + { + if (orient) + { + for (i = 0; i < 4; i++) + { + /* + if (!surfedges.Get(elnr)[i]) return i; + eledges[i] = abs (surfedges.Get(elnr)[i]); + orient[i] = (surfedges.Get(elnr)[i] > 0 ) ? 1 : -1; + */ + if (surfedges.Get(elnr)[i].nr == -1) return i; + eledges[i] = surfedges.Get(elnr)[i].nr+1; + orient[i] = (surfedges.Get(elnr)[i].orient) ? -1 : 1; + + } + } + else + { + for (i = 0; i < 4; i++) + { + /* + if (!surfedges.Get(elnr)[i]) return i; + eledges[i] = abs (surfedges.Get(elnr)[i]); + */ + if (surfedges.Get(elnr)[i].nr == -1) return i; + eledges[i] = surfedges.Get(elnr)[i].nr+1; + } + } + return 4; + } + else + { + /* + eledges[0] = abs (segedges.Get(elnr)); + if (orient) + orient[0] = segedges.Get(elnr) > 0 ? 1 : -1; + */ + eledges[0] = segedges.Get(elnr).nr+1; + if (orient) + orient[0] = segedges.Get(elnr).orient ? -1 : 1; + } + return 1; + } + + + void MeshTopology :: GetFaceVertices (int fnr, Array & vertices) const + { + vertices.SetSize(4); + for (int i = 0; i < 4; i++) + vertices[i] = face2vert.Get(fnr)[i]; + if (vertices[3] == 0) + vertices.SetSize(3); + } + + void MeshTopology :: GetFaceVertices (int fnr, int * vertices) const + { + for (int i = 0; i <= 3; i++) + vertices[i] = face2vert.Get(fnr)[i]; + } + + + void MeshTopology :: GetEdgeVertices (int ednr, int & v1, int & v2) const + { + v1 = edge2vert.Get(ednr)[0]; + v2 = edge2vert.Get(ednr)[1]; + } + + void MeshTopology :: GetEdgeVertices (int ednr, PointIndex & v1, PointIndex & v2) const + { + v1 = edge2vert.Get(ednr)[0]; + v2 = edge2vert.Get(ednr)[1]; + } + + + void MeshTopology :: GetFaceEdges (int fnr, Array & fedges, bool withorientation) const + { + ArrayMem pi(4); + ArrayMem eledges; + + fedges.SetSize (0); + GetFaceVertices(fnr, pi); + + // Sort Edges according to global vertex numbers + // e1 = fmax, f2 + // e2 = fmax, f1 + // e3 = op e1(f2,f3) + // e4 = op e2(f1,f3) + + /* ArrayMem fp; + fp[0] = pi[0]; + for(int k=1;kfp[0]) swap(fp[k],fp[0]); + + fp[1] = fp[0]+ */ + + + // GetVertexElements (pi[0], els); + FlatArray els = GetVertexElements (pi[0]); + + // find one element having all vertices of the face + for (int i = 0; i < els.Size(); i++) + { + const Element & el = mesh[els[i]]; + int nref_faces = GetNFaces (el.GetType()); + const ELEMENT_FACE * ref_faces = GetFaces1 (el.GetType()); + int nfa_ref_edges = GetNEdges (GetFaceType(fnr)); + + int cntv = 0,fa=-1; + for(int m=0;m0;j++) + for(int k=0;k=0) + { + const ELEMENT_EDGE * fa_ref_edges = GetEdges1 (GetFaceType(fnr)); + fedges.SetSize(nfa_ref_edges); + GetElementEdges (els[i]+1, eledges); + + for (int j = 0; j < eledges.Size(); j++) + { + int vi1, vi2; + GetEdgeVertices (eledges[j], vi1, vi2); + + bool has1 = 0; + bool has2 = 0; + for (int k = 0; k < pi.Size(); k++) + { + if (vi1 == pi[k]) has1 = 1; + if (vi2 == pi[k]) has2 = 1; + + } + + if (has1 && has2) // eledges[j] is on face + { + // fedges.Append (eledges[j]); + for(int k=0;k & elements) const + { + if (vert2element) + { + int ne = vert2element->EntrySize(vnr); + elements.SetSize(ne); + for (int i = 1; i <= ne; i++) + elements.Elem(i) = vert2element->Get(vnr, i); + } + } + + + FlatArray MeshTopology :: GetVertexElements (int vnr) const + { + if (vert2element) + return (*vert2element)[vnr]; + return FlatArray (0,0); + } + + FlatArray MeshTopology :: GetVertexSurfaceElements (int vnr) const + { + if (vert2surfelement) + return (*vert2surfelement)[vnr]; + return FlatArray (0,0); + } + + + void MeshTopology :: GetVertexSurfaceElements( int vnr, + Array& elements ) const + { + if (vert2surfelement) + { + int i; + int ne = vert2surfelement->EntrySize(vnr); + elements.SetSize(ne); + for (i = 1; i <= ne; i++) + elements.Elem(i) = vert2surfelement->Get(vnr, i); + } + } + + + int MeshTopology :: GetVerticesEdge ( int v1, int v2 ) const + { + Array elements_v1; + Array elementedges; + GetVertexElements ( v1, elements_v1); + int edv1, edv2; + + for ( int i = 0; i < elements_v1.Size(); i++ ) + { + GetElementEdges( elements_v1[i]+1, elementedges ); + for ( int ed = 0; ed < elementedges.Size(); ed ++) + { + GetEdgeVertices( elementedges[ed], edv1, edv2 ); + if ( ( edv1 == v1 && edv2 == v2 ) || ( edv1 == v2 && edv2 == v1 ) ) + return elementedges[ed]; + } + } + + return -1; + } + + + + void MeshTopology :: + GetSegmentVolumeElements ( int segnr, Array & volels ) const + { + int v1, v2; + GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 ); + Array volels1, volels2; + GetVertexElements ( v1, volels1 ); + GetVertexElements ( v2, volels2 ); + volels.SetSize(0); + + for ( int eli1=1; eli1 <= volels1.Size(); eli1++) + if ( volels2.Contains( volels1.Elem(eli1) ) ) + volels.Append ( volels1.Elem(eli1)+1 ); + } + + void MeshTopology :: + GetSegmentSurfaceElements (int segnr, Array & els) const + { + int v1, v2; + GetEdgeVertices ( GetSegmentEdge (segnr), v1, v2 ); + Array els1, els2; + GetVertexSurfaceElements ( v1, els1 ); + GetVertexSurfaceElements ( v2, els2 ); + els.SetSize(0); + + for ( int eli1=1; eli1 <= els1.Size(); eli1++) + if ( els2.Contains( els1.Elem(eli1) ) ) + els.Append ( els1.Elem(eli1) ); + } + + + + +} diff --git a/libsrc/meshing/topology.hpp b/libsrc/meshing/topology.hpp new file mode 100644 index 00000000..fe5e3db0 --- /dev/null +++ b/libsrc/meshing/topology.hpp @@ -0,0 +1,706 @@ +#ifndef TOPOLOGY +#define TOPOLOGY + +/**************************************************************************/ +/* File: topology.hh */ +/* Author: Joachim Schoeberl */ +/* Date: 27. Apr. 01 */ +/**************************************************************************/ + +/* + Mesh topology + (Elements, Faces, Edges, Vertices +*/ + + +struct T_EDGE +{ + int orient:1; + int nr:31; // 0-based +}; + +struct T_FACE +{ + int forient:3; + int fnr:29; // 0-based +}; + + +class MeshTopology +{ + const Mesh & mesh; + bool buildedges; + bool buildfaces; + + Array edge2vert; + Array face2vert; + Array edges; + Array faces; + Array surfedges; + Array segedges; + Array surffaces; + Array surf2volelement; + Array face2surfel; + TABLE *vert2element; + TABLE *vert2surfelement; + TABLE *vert2segment; + int timestamp; +public: + int GetNSurfedges() const {return surfedges.Size();} + + MeshTopology (const Mesh & amesh); + ~MeshTopology (); + + void SetBuildEdges (bool be) + { buildedges = be; } + void SetBuildFaces (bool bf) + { buildfaces = bf; } + + bool HasEdges () const + { return buildedges; } + bool HasFaces () const + { return buildfaces; } + + void Update(); + + + int GetNEdges () const { return edge2vert.Size(); } + int GetNFaces () const { return face2vert.Size(); } + + static inline int GetNVertices (ELEMENT_TYPE et); + static inline int GetNPoints (ELEMENT_TYPE et); + static inline int GetNEdges (ELEMENT_TYPE et); + static inline int GetNFaces (ELEMENT_TYPE et); + + static const Point3d * GetVertices (ELEMENT_TYPE et); + inline static const ELEMENT_EDGE * GetEdges1 (ELEMENT_TYPE et); + inline static const ELEMENT_EDGE * GetEdges0 (ELEMENT_TYPE et); + inline static const ELEMENT_FACE * GetFaces1 (ELEMENT_TYPE et); + inline static const ELEMENT_FACE * GetFaces0 (ELEMENT_TYPE et); + + + // int GetSegmentEdge (int segnr) const { return abs(segedges[segnr-1]); } + // int GetSegmentEdgeOrientation (int segnr) const { return sgn(segedges[segnr-1]); } + // int GetEdge (SegmentIndex segnr) const { return abs(segedges[segnr])-1; } + int GetSegmentEdge (int segnr) const { return segedges[segnr-1].nr+1; } + int GetEdge (SegmentIndex segnr) const { return segedges[segnr].nr; } + + void GetSegmentEdge (int segnr, int & enr, int & orient) const + { + /* + enr = abs(segedges.Get(segnr)); + orient = segedges.Get(segnr) > 0 ? 1 : -1; + */ + enr = segedges.Get(segnr).nr+1; + orient = segedges.Get(segnr).orient; + } + + void GetElementEdges (int elnr, Array & edges) const; + void GetElementFaces (int elnr, Array & faces, bool withorientation = false) const; + void GetElementEdgeOrientations (int elnr, Array & eorient) const; + void GetElementFaceOrientations (int elnr, Array & forient) const; + + int GetElementEdges (int elnr, int * edges, int * orient) const; + int GetElementFaces (int elnr, int * faces, int * orient) const; + + void GetFaceVertices (int fnr, Array & vertices) const; + void GetFaceVertices (int fnr, int * vertices) const; + void GetEdgeVertices (int enr, int & v1, int & v2) const; + void GetEdgeVertices (int enr, PointIndex & v1, PointIndex & v2) const; + const int * GetEdgeVerticesPtr (int enr) const { return &edge2vert[enr][0]; } + const int * GetFaceVerticesPtr (int fnr) const { return &face2vert[fnr][0]; } + void GetFaceEdges (int fnr, Array & edges, bool withorientation = false) const; + + ELEMENT_TYPE GetFaceType (int fnr) const; + + void GetSurfaceElementEdges (int elnr, Array & edges) const; + int GetSurfaceElementFace (int elnr) const; + void GetSurfaceElementEdgeOrientations (int elnr, Array & eorient) const; + int GetSurfaceElementFaceOrientation (int elnr) const; + void GetEdges (SurfaceElementIndex elnr, Array & edges) const; + int GetFace (SurfaceElementIndex elnr) const; + + int GetSurfaceElementEdges (int elnr, int * edges, int * orient) const; + + const T_EDGE * GetElementEdgesPtr (int elnr) const { return &edges[elnr][0]; } + const T_EDGE * GetSurfaceElementEdgesPtr (int selnr) const { return &surfedges[selnr][0]; } + const T_EDGE * GetSegmentElementEdgesPtr (int selnr) const { return &segedges[selnr]; } + + const T_FACE * GetElementFacesPtr (int elnr) const { return &faces[elnr][0]; } + const T_FACE * GetSurfaceElementFacesPtr (int selnr) const { return &surffaces[selnr]; } + + + void GetSurface2VolumeElement (int selnr, int & elnr1, int & elnr2) const + { + elnr1 = surf2volelement.Get(selnr)[0]; + elnr2 = surf2volelement.Get(selnr)[1]; + } + + int GetFace2SurfaceElement (int fnr) const { return face2surfel[fnr-1]; } + + void GetVertexElements (int vnr, Array & elements) const; + FlatArray GetVertexElements (int vnr) const; + + void GetVertexSurfaceElements( int vnr, Array& elements ) const; + FlatArray GetVertexSurfaceElements (int vnr) const; + + + + int GetVerticesEdge ( int v1, int v2) const; + void GetSegmentVolumeElements ( int segnr, Array & els ) const; + void GetSegmentSurfaceElements ( int segnr, Array & els ) const; +}; + + + + + + + + + + +inline int MeshTopology :: GetNVertices (ELEMENT_TYPE et) +{ + switch (et) + { + case SEGMENT: + case SEGMENT3: + return 2; + + case TRIG: + case TRIG6: + return 3; + + case QUAD: + case QUAD6: + case QUAD8: + return 4; + + case TET: + case TET10: + return 4; + + case PYRAMID: + return 5; + + case PRISM: + case PRISM12: + return 6; + + case HEX: + return 8; + + // default: + // cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; + } + return 0; +} + + +inline int MeshTopology :: GetNPoints (ELEMENT_TYPE et) +{ + switch (et) + { + case SEGMENT: + return 2; + case SEGMENT3: + return 3; + + case TRIG: + return 3; + case TRIG6: + return 6; + + case QUAD: + case QUAD6: + case QUAD8: + return 4; + + case TET: + return 4; + case TET10: + return 10; + + case PYRAMID: + return 5; + + case PRISM: + case PRISM12: + return 6; + + case HEX: + return 8; + + // default: + // cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; + } + return 0; +} + + + +inline int MeshTopology :: GetNEdges (ELEMENT_TYPE et) +{ + switch (et) + { + case SEGMENT: + case SEGMENT3: + return 1; + + case TRIG: + case TRIG6: + return 3; + + case QUAD: + case QUAD6: + case QUAD8: + return 4; + + case TET: + case TET10: + return 6; + + case PYRAMID: + return 8; + + case PRISM: + case PRISM12: + return 9; + + case HEX: + return 12; + + // default: + // cerr << "Ng_ME_GetNEdges, illegal element type " << et << endl; + } + return 0; +} + + +inline int MeshTopology :: GetNFaces (ELEMENT_TYPE et) +{ + switch (et) + { + case SEGMENT: + case SEGMENT3: + return 0; + + case TRIG: + case TRIG6: + return 1; + + case QUAD: + case QUAD6: + case QUAD8: + return 1; + + case TET: + case TET10: + return 4; + + case PYRAMID: + return 5; + + case PRISM: + case PRISM12: + return 5; + + case HEX: + return 6; + + // default: + // cerr << "Ng_ME_GetNVertices, illegal element type " << et << endl; + } + return 0; +} + + + + + + +const ELEMENT_EDGE * MeshTopology :: GetEdges1 (ELEMENT_TYPE et) +{ + static int segm_edges[1][2] = + { { 1, 2 }}; + + static int trig_edges[3][2] = + { { 3, 1 }, + { 2, 3 }, + { 1, 2 }}; + + static int quad_edges[4][2] = + { { 1, 2 }, + { 3, 4 }, + { 4, 1 }, + { 2, 3 }}; + + + static int tet_edges[6][2] = + { { 4, 1 }, + { 4, 2 }, + { 4, 3 }, + { 1, 2 }, + { 1, 3 }, + { 2, 3 }}; + + static int prism_edges[9][2] = + { { 3, 1 }, + { 1, 2 }, + { 3, 2 }, + { 6, 4 }, + { 4, 5 }, + { 6, 5 }, + { 3, 6 }, + { 1, 4 }, + { 2, 5 }}; + + static int pyramid_edges[8][2] = + { { 1, 2 }, + { 2, 3 }, + { 1, 4 }, + { 4, 3 }, + { 1, 5 }, + { 2, 5 }, + { 3, 5 }, + { 4, 5 }}; + + static int hex_edges[12][2] = + { + { 1, 2 }, + { 3, 4 }, + { 4, 1 }, + { 2, 3 }, + { 5, 6 }, + { 7, 8 }, + { 8, 5 }, + { 6, 7 }, + { 1, 5 }, + { 2, 6 }, + { 3, 7 }, + { 4, 8 }, + }; + + switch (et) + { + case SEGMENT: + case SEGMENT3: + return segm_edges; + + case TRIG: + case TRIG6: + return trig_edges; + + case QUAD: + case QUAD6: + case QUAD8: + return quad_edges; + + case TET: + case TET10: + return tet_edges; + + case PYRAMID: + return pyramid_edges; + + case PRISM: + case PRISM12: + return prism_edges; + + case HEX: + return hex_edges; + // default: + // cerr << "Ng_ME_GetEdges, illegal element type " << et << endl; + } + return 0; +} + + + +const ELEMENT_EDGE * MeshTopology :: GetEdges0 (ELEMENT_TYPE et) +{ + static int segm_edges[1][2] = + { { 0, 1 }}; + + static int trig_edges[3][2] = + { { 2, 0 }, + { 1, 2 }, + { 0, 1 }}; + + static int quad_edges[4][2] = + { { 0, 1 }, + { 2, 3 }, + { 3, 0 }, + { 1, 2 }}; + + + static int tet_edges[6][2] = + { { 3, 0 }, + { 3, 1 }, + { 3, 2 }, + { 0, 1 }, + { 0, 2 }, + { 1, 2 }}; + + static int prism_edges[9][2] = + { { 2, 0 }, + { 0, 1 }, + { 2, 1 }, + { 5, 3 }, + { 3, 4 }, + { 5, 4 }, + { 2, 5 }, + { 0, 3 }, + { 1, 4 }}; + + static int pyramid_edges[8][2] = + { { 0, 1 }, + { 1, 2 }, + { 0, 3 }, + { 3, 2 }, + { 0, 4 }, + { 1, 4 }, + { 2, 4 }, + { 3, 4 }}; + + static int hex_edges[12][2] = + { + { 0, 1 }, + { 2, 3 }, + { 3, 0 }, + { 1, 2 }, + { 4, 5 }, + { 6, 7 }, + { 7, 4 }, + { 5, 6 }, + { 0, 4 }, + { 1, 5 }, + { 2, 6 }, + { 3, 7 }, + }; + + switch (et) + { + case SEGMENT: + case SEGMENT3: + return segm_edges; + + case TRIG: + case TRIG6: + return trig_edges; + + case QUAD: + case QUAD6: + case QUAD8: + return quad_edges; + + case TET: + case TET10: + return tet_edges; + + case PYRAMID: + return pyramid_edges; + + case PRISM: + case PRISM12: + return prism_edges; + + case HEX: + return hex_edges; + // default: + // cerr << "Ng_ME_GetEdges, illegal element type " << et << endl; + } + return 0; +} + + + + + + + + + + +inline const ELEMENT_FACE * MeshTopology :: GetFaces1 (ELEMENT_TYPE et) +{ + static const int trig_faces[1][4] = + { { 1, 2, 3, 0 } }; + static const int quad_faces[1][4] = + { { 1, 2, 3, 4 } }; + + static const int tet_faces[4][4] = + { { 4, 2, 3, 0 }, + { 4, 3, 1, 0 }, + { 4, 1, 2, 0 }, + { 1, 3, 2, 0 } }; + + static const int prism_faces[5][4] = + { + { 1, 3, 2, 0 }, + { 4, 5, 6, 0 }, + { 3, 1, 4, 6 }, + { 1, 2, 5, 4 }, + { 2, 3, 6, 5 } + }; + + static const int pyramid_faces[5][4] = + { + { 1, 2, 5, 0 }, + { 2, 3, 5, 0 }, + { 3, 4, 5, 0 }, + { 4, 1, 5, 0 }, + { 1, 4, 3, 2 } + }; + + static const int hex_faces[6][4] = + { + { 1, 4, 3, 2 }, + { 5, 6, 7, 8 }, + { 1, 2, 6, 5 }, + { 2, 3, 7, 6 }, + { 3, 4, 8, 7 }, + { 4, 1, 5, 8 } + }; + + + + switch (et) + { + case TRIG: + case TRIG6: + return trig_faces; + + case QUAD: + case QUAD6: + case QUAD8: + return quad_faces; + + + case TET: + case TET10: + return tet_faces; + + case PRISM: + case PRISM12: + return prism_faces; + + case PYRAMID: + return pyramid_faces; + + case SEGMENT: + case SEGMENT3: + + case HEX: + return hex_faces; + + // default: + // cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; + } + return 0; +} + + + + + +inline const ELEMENT_FACE * MeshTopology :: GetFaces0 (ELEMENT_TYPE et) +{ + static const int trig_faces[1][4] = + { { 0, 1, 2, -1 } }; + static const int quad_faces[1][4] = + { { 0, 1, 2, 3 } }; + + static const int tet_faces[4][4] = + { { 3, 1, 2, -1 }, + { 3, 2, 0, -1 }, + { 3, 0, 1, -1 }, + { 0, 2, 1, -1 } }; + + static const int prism_faces[5][4] = + { + { 0, 2, 1, -1 }, + { 3, 4, 5, -1 }, + { 2, 0, 3, 5 }, + { 0, 1, 4, 3 }, + { 1, 2, 5, 4 } + }; + + static const int pyramid_faces[5][4] = + { + { 0, 1, 4, -1 }, + { 1, 2, 4, -1 }, + { 2, 3, 4, -1 }, + { 3, 0, 4, -1 }, + { 0, 3, 2, 1 } + }; + + static const int hex_faces[6][4] = + { + { 0, 3, 2, 1 }, + { 4, 5, 6, 7 }, + { 0, 1, 5, 4 }, + { 1, 2, 6, 5 }, + { 2, 3, 7, 6 }, + { 3, 0, 4, 7 } + }; + + + + switch (et) + { + case TRIG: + case TRIG6: + return trig_faces; + + case QUAD: + case QUAD6: + case QUAD8: + return quad_faces; + + + case TET: + case TET10: + return tet_faces; + + case PRISM: + case PRISM12: + return prism_faces; + + case PYRAMID: + return pyramid_faces; + + case SEGMENT: + case SEGMENT3: + + case HEX: + return hex_faces; + + // default: + // cerr << "Ng_ME_GetVertices, illegal element type " << et << endl; + } + return 0; +} + + + + + + + + + + + + + + + + + + + + + +#endif diff --git a/libsrc/meshing/triarls.cpp b/libsrc/meshing/triarls.cpp new file mode 100644 index 00000000..d82806e9 --- /dev/null +++ b/libsrc/meshing/triarls.cpp @@ -0,0 +1,468 @@ +namespace netgen +{ +const char * triarules[] = { +"rule \"Free Triangle (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0) { 1.0, 0, 1.0 };\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 0.5 X2 } { };\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.7) { 0.5 X2 } { };\n",\ +"(0.5, 1.5) { 0.5 X2 } { };\n",\ +"(-0.5, 0.7) { 0.5 X2 } { };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.866) { 0.5 X2 } { };\n",\ +"(0.5, 0.866) { 0.5 X2 } { };\n",\ +"(0.5, 0.866) { 0.5 X2 } { };\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"rule \"Free Triangle (5)\"\n",\ +"\n",\ +"quality 5\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0) { 1.0, 0, 1.0 };\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.5) { 0.5 X2 } { };\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.7) { 1 X2 } { };\n",\ +"(0, 0.7) { } { };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.5) { 0.5 X2 } { };\n",\ +"(0.5, 0.5) { 0.5 X2 } { };\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Free Triangle (10)\"\n",\ +"\n",\ +"quality 10\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0) { 1.0, 0, 1.0 };\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.3) { 0.5 X2 } { };\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.5) { 1 X2 } { };\n",\ +"(0, 0.5) { } { };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.3) { 0.5 X2 } { };\n",\ +"(0.5, 0.3) { 0.5 X2 } { };\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Free Triangle (20)\"\n",\ +"\n",\ +"quality 20\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0) { 1.0, 0, 1.0 };\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.1) { 0.5 X2 } { };\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1, 0.2) { 1 X2 } { };\n",\ +"(0, 0.2) { } { };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.1) { 0.5 X2 } { };\n",\ +"(0.5, 0.1) { 0.5 X2 } { };\n",\ +"\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Right 60 (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0) { 0.5, 0, 1.0 };\n",\ +"(0.5, 0.866) { 0.6, 0, 0.8 };\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(-0.125, 0.6495) { -0.5 X2, 0.75 X3 } { -0.5 Y2, 0.75 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left 60 (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.125, 0.6495) { 0.75 X2, 0.75 X3 } { 0.75 Y3 };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Right 120 (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 1 X3, -1 X2 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 4);\n",\ +"(4, 3);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(1, 1.732) { -2 X2, 2 X3 } { 2 Y3 };\n",\ +"(0, 1.732) { -3 X2, 2 X3 } { 2 Y3 };\n",\ +"(-0.5, 0.866) { -2 X2, 1 X3 } {1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4);\n",\ +"(2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left 120 (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(-0.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 1 X3, 1 X2 } { 1 Y3 };\n",\ +"\n",\ +"newlines\n",\ +"(3, 4);\n",\ +"(4, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.866) { 2 X2, 1 X3 } { 1 Y3 };\n",\ +"(1, 1.732) { 2 X2, 2 X3 } { 2 Y3 };\n",\ +"(0, 1.732) { -1 X2, 2 X3 } { 2 Y3 };\n",\ +"(-0.5, 0.866) { 1 X3 } {1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 4);\n",\ +"(2, 3, 4);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Left Right 120 (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(-0.5, 0.866);\n",\ +"(1.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 1) del;\n",\ +"(2, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 0.5 X3, 0.5 X4 } { 0.5 Y3, 0.5 Y4 };\n",\ +"\n",\ +"newlines\n",\ +"(3, 5);\n",\ +"(5, 4);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.5, 0.866) { 1 X4 } { 1 Y4 };\n",\ +"(1, 1.299) { -0.5 X2, 0.375 X3, 1.125 X4 } { -0.5 Y2, 0.375 Y3, 1.125 Y4 };\n",\ +"(0, 1.299) { 1.125 X3, 0.375 X4 } { 1.125 Y3, 0.375 Y4 };\n",\ +"(-0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 5);\n",\ +"(3, 1, 5);\n",\ +"(2, 4, 5);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"rule \"Fill Triangle\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(2, 3) del;\n",\ +"(3, 1) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { 1 Y2 };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"Vis A Vis (1)\"\n",\ +"\n",\ +"quality 1\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(0.5, 0.866);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"\n",\ +"newpoints\n",\ +"\n",\ +"newlines\n",\ +"(1, 3);\n",\ +"(3, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(1.2, 0.693) { 0.8 X2, 0.8 X3 } { 0.8 Y2, 0.8 Y3 };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(-0.2, 0.693) { -0.6 X2, 0.8 X3 } { -0.6 Y2, 0.8 Y3 };\n",\ +"\n",\ +"freearea2\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { };\n",\ +"(0.75, 0.433) { 0.5 X2, 0.5 X3 } { 0.5 Y2, 0.5 Y3 };\n",\ +"(0.5, 0.866) { 1 X3 } { 1 Y3 };\n",\ +"(0.25, 0.433) { 0.5 X3 } { 0.5 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 3);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"rule \"2 h Vis A Vis (1)\"\n",\ +"\n",\ +"quality 3\n",\ +"\n",\ +"mappoints\n",\ +"(0, 0);\n",\ +"(1, 0);\n",\ +"(1, 1.732);\n",\ +"(0, 1.732);\n",\ +"\n",\ +"maplines\n",\ +"(1, 2) del;\n",\ +"(3, 4) del;\n",\ +"\n",\ +"newpoints\n",\ +"(0.5, 0.866) { 0.25 X2, 0.25 X3, 0.25 X4 } { 0.25 Y2, 0.25 Y3, 0.25 Y4 };\n",\ +"\n",\ +"newlines\n",\ +"(1, 5);\n",\ +"(5, 4);\n",\ +"(3, 5);\n",\ +"(5, 2);\n",\ +"\n",\ +"freearea\n",\ +"(0, 0);\n",\ +"(1, 0) { 1 X2 } { 1 Y2 };\n",\ +"(1.5, 0.866) { 0.75 X2, 0.75 X3, -0.25 X4 } { 0.75 Y2, 0.75 Y3, -0.25 Y4 };\n",\ +"(1, 1.732) { 1 X3 } { 1 Y3 };\n",\ +"(0, 1.732) { 1 X4 } { 1 Y4 };\n",\ +"(-0.5, 0.866) { 0.75 X4, -0.25 X2, -0.25 X3 } { 0.75 Y4, -0.25 Y3 };\n",\ +"\n",\ +"elements\n",\ +"(1, 2, 5);\n",\ +"(3, 4, 5);\n",\ +"\n",\ +"endrule\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +"\n",\ +0}; +} diff --git a/libsrc/meshing/validate.cpp b/libsrc/meshing/validate.cpp new file mode 100644 index 00000000..44b983cc --- /dev/null +++ b/libsrc/meshing/validate.cpp @@ -0,0 +1,591 @@ + +#include +#include "meshing.hpp" + + +namespace netgen +{ + void GetPureBadness(Mesh & mesh, Array & pure_badness, + const BitArray & isnewpoint) + { + //const int ne = mesh.GetNE(); + const int np = mesh.GetNP(); + + pure_badness.SetSize(np+PointIndex::BASE+1); + pure_badness = -1; + + Array< Point<3>* > backup(np); + + for(int i=0; i(mesh.Point(i+1)); + + if(isnewpoint.Test(i+PointIndex::BASE) && + mesh.mlbetweennodes[i+PointIndex::BASE][0] > 0) + { + mesh.Point(i+1) = Center(mesh.Point(mesh.mlbetweennodes[i+PointIndex::BASE][0]), + mesh.Point(mesh.mlbetweennodes[i+PointIndex::BASE][1])); + } + } + for (ElementIndex i = 0; i < mesh.GetNE(); i++) + { + double bad = mesh[i].CalcJacobianBadness (mesh.Points()); + for(int j=0; j pure_badness[mesh[i][j]]) + pure_badness[mesh[i][j]] = bad; + + // save maximum + if(bad > pure_badness.Last()) + pure_badness.Last() = bad; + } + + for(int i=0; i & bad_elements, + const Array & pure_badness, + double max_worsening, const bool uselocalworsening, + Array * quality_loss) + { + PrintMessage(3,"!!!! Validating !!!!"); + //if(max_worsening > 0) + // (*testout) << "badness " << counter++ << endl; + + bad_elements.SetSize(0); + + double loc_pure_badness = -1; + + if(!uselocalworsening) + loc_pure_badness = pure_badness.Last(); // maximum is saved at last position + + + double worsening = -1; + ElementIndex ind; + + if(quality_loss != NULL) + quality_loss->SetSize(mesh.GetNE()); + + for (ElementIndex i = 0; i < mesh.GetNE(); i++) + { + if(uselocalworsening) + { + loc_pure_badness = -1; + for(int j=0; j loc_pure_badness) + loc_pure_badness = pure_badness[mesh[i][j]]; + } + + + double bad = mesh[i].CalcJacobianBadness (mesh.Points()); + if (bad > 1e10 || + (max_worsening > 0 && bad > loc_pure_badness*max_worsening)) + bad_elements.Append(i); + + + if(max_worsening > 0) + { + double actw = bad/loc_pure_badness; + if(quality_loss != NULL) + (*quality_loss)[i] = actw; + + if(actw > worsening) + { + worsening = actw; + ind = i; + } + } + } + return worsening; + } + + + void GetWorkingArea(BitArray & working_elements, BitArray & working_points, + const Mesh & mesh, const Array & bad_elements, + const int width) + { + working_elements.Clear(); + working_points.Clear(); + + for(int i=0; i & bad_elements, + const BitArray & isnewpoint, const Refinement & refinement, + const Array & pure_badness, + double max_worsening, const bool uselocalworsening, + const Array< Array* > & idmaps) + { + ostringstream ostrstr; + + const int maxtrials = 100; + + //bool doit; + //cout << "DOIT: " << flush; + //cin >> doit; + + int ne = mesh.GetNE(); + int np = mesh.GetNP(); + + int numbadneighbours = 3; + const int numtopimprove = 3; + + PrintMessage(1,"repairing"); + + PushStatus("Repair Bisection"); + + Array* > should(np); + Array* > can(np); + Array* > nv(np); + for(int i=0; i; + should[i] = new Point<3>; + can[i] = new Point<3>; + } + + BitArray isboundarypoint(np),isedgepoint(np); + isboundarypoint.Clear(); + isedgepoint.Clear(); + + for(int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + isedgepoint.Set(seg[0]); + isedgepoint.Set(seg[1]); + } + + Array surfaceindex(np); + surfaceindex = -1; + + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + for (int j = 1; j <= sel.GetNP(); j++) + if(!isedgepoint.Test(sel.PNum(j))) + { + isboundarypoint.Set(sel.PNum(j)); + surfaceindex[sel.PNum(j) - PointIndex::BASE] = + mesh.GetFaceDescriptor(sel.GetIndex()).SurfNr(); + } + } + + + + Validate(mesh,bad_elements,pure_badness, + ((uselocalworsening) ? (0.8*(max_worsening-1.) + 1.) : (0.1*(max_worsening-1.) + 1.)), + uselocalworsening); // -> larger working area + BitArray working_elements(ne); + BitArray working_points(np); + + GetWorkingArea(working_elements,working_points,mesh,bad_elements,numbadneighbours); + //working_elements.Set(); + //working_points.Set(); + + ostrstr.str(""); + ostrstr << "worsening: " << + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + PrintMessage(4,ostrstr.str()); + + + + int auxnum=0; + for(int i=1; i<=np; i++) + if(working_points.Test(i)) + auxnum++; + + ostrstr.str(""); + ostrstr << "Percentage working points: " << 100.*double(auxnum)/np; + PrintMessage(5,ostrstr.str()); + + + BitArray isworkingboundary(np); + for(int i=1; i<=np; i++) + if(working_points.Test(i) && isboundarypoint.Test(i)) + isworkingboundary.Set(i); + else + isworkingboundary.Clear(i); + + + for(int i=0; i 0) + *can[i] = Center(*can[mesh.mlbetweennodes[i+PointIndex::BASE][0]-PointIndex::BASE], + *can[mesh.mlbetweennodes[i+PointIndex::BASE][1]-PointIndex::BASE]); + else + *can[i] = mesh.Point(i+1); + } + + + int cnttrials = 1; + + double lamedge = 0.5; + double lamface = 0.5; + + double facokedge = 0; + double facokface = 0; + double factryedge; + double factryface = 0; + + double oldlamedge,oldlamface; + + MeshOptimize2d * optimizer2d = refinement.Get2dOptimizer(); + if(!optimizer2d) + { + cerr << "No 2D Optimizer!" << endl; + return; + } + + while ((facokedge < 1.-1e-8 || facokface < 1.-1e-8) && + cnttrials < maxtrials && + multithread.terminate != 1) + { + (*testout) << " facokedge " << facokedge << " facokface " << facokface << " cnttrials " << cnttrials << endl + << " perc. " << 95. * max2( min2(facokedge,facokface), + double(cnttrials)/double(maxtrials)) << endl; + + SetThreadPercent(95. * max2( min2(facokedge,facokface), + double(cnttrials)/double(maxtrials))); + + ostrstr.str(""); + ostrstr << "max. worsening " << max_worsening; + PrintMessage(5,ostrstr.str()); + oldlamedge = lamedge; + lamedge *= 6; + if (lamedge > 2) + lamedge = 2; + + if(1==1 || facokedge < 1.-1e-8) + { + for(int i=0; i(0,0,0); + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & sel = mesh.SurfaceElement(i); + Vec<3> auxvec = Cross(mesh.Point(sel.PNum(2))-mesh.Point(sel.PNum(1)), + mesh.Point(sel.PNum(3))-mesh.Point(sel.PNum(1))); + auxvec.Normalize(); + for (int j = 1; j <= sel.GetNP(); j++) + if(!isedgepoint.Test(sel.PNum(j))) + *nv[sel.PNum(j) - PointIndex::BASE] += auxvec; + } + for(int i=0; iNormalize(); + + + do // move edges + { + lamedge *= 0.5; + cnttrials++; + if(cnttrials % 10 == 0) + max_worsening *= 1.1; + + + factryedge = lamedge + (1.-lamedge) * facokedge; + + ostrstr.str(""); + ostrstr << "lamedge = " << lamedge << ", trying: " << factryedge; + PrintMessage(5,ostrstr.str()); + + + for (int i = 1; i <= np; i++) + { + if (isedgepoint.Test(i)) + { + for (int j = 0; j < 3; j++) + mesh.Point(i)(j) = + lamedge * (*should.Get(i))(j) + + (1.-lamedge) * (*can.Get(i))(j); + } + else + mesh.Point(i) = *can.Get(i); + } + if(facokedge < 1.-1e-8) + { + ostrstr.str(""); + ostrstr << "worsening: " << + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + + PrintMessage(5,ostrstr.str()); + } + else + Validate(mesh,bad_elements,pure_badness,-1,uselocalworsening); + + + ostrstr.str(""); + ostrstr << bad_elements.Size() << " bad elements"; + PrintMessage(5,ostrstr.str()); + } + while (bad_elements.Size() > 0 && + cnttrials < maxtrials && + multithread.terminate != 1); + } + + if(cnttrials < maxtrials && + multithread.terminate != 1) + { + facokedge = factryedge; + + // smooth faces + mesh.CalcSurfacesOfNode(); + + MeshingParameters dummymp; + mesh.ImproveMeshJacobianOnSurface(dummymp,isworkingboundary,nv,OPT_QUALITY, &idmaps); + + for (int i = 1; i <= np; i++) + *can.Elem(i) = mesh.Point(i); + + if(optimizer2d) + optimizer2d->ProjectBoundaryPoints(surfaceindex,can,should); + } + + + oldlamface = lamface; + lamface *= 6; + if (lamface > 2) + lamface = 2; + + + if(cnttrials < maxtrials && + multithread.terminate != 1) + { + + do // move faces + { + lamface *= 0.5; + cnttrials++; + if(cnttrials % 10 == 0) + max_worsening *= 1.1; + factryface = lamface + (1.-lamface) * facokface; + + ostrstr.str(""); + ostrstr << "lamface = " << lamface << ", trying: " << factryface; + PrintMessage(5,ostrstr.str()); + + + for (int i = 1; i <= np; i++) + { + if (isboundarypoint.Test(i)) + { + for (int j = 0; j < 3; j++) + mesh.Point(i)(j) = + lamface * (*should.Get(i))(j) + + (1.-lamface) * (*can.Get(i))(j); + } + else + mesh.Point(i) = *can.Get(i); + } + + ostrstr.str(""); + ostrstr << "worsening: " << + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + PrintMessage(5,ostrstr.str()); + + + ostrstr.str(""); + ostrstr << bad_elements.Size() << " bad elements"; + PrintMessage(5,ostrstr.str()); + } + while (bad_elements.Size() > 0 && + cnttrials < maxtrials && + multithread.terminate != 1); + } + + + + if(cnttrials < maxtrials && + multithread.terminate != 1) + { + facokface = factryface; + // smooth interior + + mesh.CalcSurfacesOfNode(); + + MeshingParameters dummymp; + mesh.ImproveMeshJacobian (dummymp, OPT_QUALITY,&working_points); + //mesh.ImproveMeshJacobian (OPT_WORSTCASE,&working_points); + + + for (int i = 1; i <= np; i++) + *can.Elem(i) = mesh.Point(i); + } + + //! + if((facokedge < 1.-1e-8 || facokface < 1.-1e-8) && + cnttrials < maxtrials && + multithread.terminate != 1) + { + MeshingParameters dummymp; + MeshOptimize3d optmesh(dummymp); + for(int i=0; iProjectBoundaryPoints(surfaceindex,can,should); + + + for (int i = 1; i <= np; i++) + if(isboundarypoint.Test(i)) + for(int j=1; j<=3; j++) + mesh.Point(i).X(j) = should.Get(i).X(j); + } + */ + + + if(cnttrials == maxtrials) + { + for (int i = 1; i <= np; i++) + mesh.Point(i) = *should.Get(i); + + Validate(mesh,bad_elements,pure_badness,max_worsening,uselocalworsening); + + for(int i=0; i & pure_badness, + const BitArray & isnewpoint); + double Validate(const Mesh & mesh, Array & bad_elements, + const Array & pure_badness, + double max_worsening, const bool uselocalworsening, + Array * quality_loss = NULL); + void RepairBisection(Mesh & mesh, Array & bad_elements, + const BitArray & isnewpoint, const Refinement & refinement, + const Array & pure_badness, + double max_worsening, const bool uselocalworsening, + const Array< Array* > & idmaps); + +} + +#endif // VALIDATE_HPP diff --git a/libsrc/meshing/zrefine.cpp b/libsrc/meshing/zrefine.cpp new file mode 100644 index 00000000..be18f50b --- /dev/null +++ b/libsrc/meshing/zrefine.cpp @@ -0,0 +1,741 @@ +#include +#include "meshing.hpp" + +#include + +namespace netgen +{ + + // find singular edges + void SelectSingularEdges (const Mesh & mesh, const CSGeometry & geom, + INDEX_2_HASHTABLE & singedges, + ZRefinementOptions & opt) + { + // edges selected in csg input file + for (int i = 1; i <= geom.singedges.Size(); i++) + { + //if(geom.singedges.Get(i)->maxhinit > 0) + // continue; //!!!! + + const SingularEdge & se = *geom.singedges.Get(i); + for (int j = 1; j <= se.segms.Size(); j++) + { + INDEX_2 i2 = se.segms.Get(j); + singedges.Set (i2, 1); + } + } + + // edges interactively selected + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment(i); + if (seg.singedge_left || seg.singedge_right) + { + INDEX_2 i2(seg[0], seg[1]); + i2.Sort(); + singedges.Set (i2, 1); + } + } + } + + + /** + Convert elements (vol-tets, surf-trigs) into prisms/quads + */ + void MakePrismsSingEdge (Mesh & mesh, INDEX_2_HASHTABLE & singedges) + { + // volume elements + for (int i = 1; i <= mesh.GetNE(); i++) + { + Element & el = mesh.VolumeElement(i); + if (el.GetType() != TET) continue; + + for (int j = 1; j <= 3; j++) + for (int k = j+1; k <= 4; k++) + { + INDEX_2 edge(el.PNum(j), el.PNum(k)); + edge.Sort(); + if (singedges.Used (edge)) + { + int pi3 = 1, pi4 = 1; + while (pi3 == j || pi3 == k) pi3++; + pi4 = 10 - j - k - pi3; + + int p3 = el.PNum(pi3); + int p4 = el.PNum(pi4); + + el.SetType(PRISM); + el.PNum(1) = edge.I1(); + el.PNum(2) = p3; + el.PNum(3) = p4; + el.PNum(4) = edge.I2(); + el.PNum(5) = p3; + el.PNum(6) = p4; + } + } + } + + // surface elements + for (int i = 1; i <= mesh.GetNSE(); i++) + { + Element2d & el = mesh.SurfaceElement(i); + if (el.GetType() != TRIG) continue; + + for (int j = 1; j <= 3; j++) + { + int k = (j % 3) + 1; + INDEX_2 edge(el.PNum(j), el.PNum(k)); + edge.Sort(); + + if (singedges.Used (edge)) + { + int pi3 = 6-j-k; + int p3 = el.PNum(pi3); + int p1 = el.PNum(j); + int p2 = el.PNum(k); + + el.SetType(QUAD); + el.PNum(1) = p2; + el.PNum(2) = p3; + el.PNum(3) = p3; + el.PNum(4) = p1; + } + } + } + } + + + /* + Convert tets and pyramids next to close (identified) points into prisms + */ + void MakePrismsClosePoints (Mesh & mesh) + { + int i, j, k; + for (i = 1; i <= mesh.GetNE(); i++) + { + Element & el = mesh.VolumeElement(i); + if (el.GetType() == TET) + { + for (j = 1; j <= 3; j++) + for (k = j+1; k <= 4; k++) + { + INDEX_2 edge(el.PNum(j), el.PNum(k)); + edge.Sort(); + if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k))) + { + int pi3 = 1, pi4 = 1; + while (pi3 == j || pi3 == k) pi3++; + pi4 = 10 - j - k - pi3; + + int p3 = el.PNum(pi3); + int p4 = el.PNum(pi4); + + el.SetType(PRISM); + el.PNum(1) = edge.I1(); + el.PNum(2) = p3; + el.PNum(3) = p4; + el.PNum(4) = edge.I2(); + el.PNum(5) = p3; + el.PNum(6) = p4; + } + } + } + + if (el.GetType() == PYRAMID) + { + // pyramid, base face = 1,2,3,4 + + for (j = 0; j <= 1; j++) + { + PointIndex pi1 = el.PNum( (j+0) % 4 + 1); + PointIndex pi2 = el.PNum( (j+1) % 4 + 1); + PointIndex pi3 = el.PNum( (j+2) % 4 + 1); + PointIndex pi4 = el.PNum( (j+3) % 4 + 1); + PointIndex pi5 = el.PNum(5); + + INDEX_2 edge1(pi1, pi4); + INDEX_2 edge2(pi2, pi3); + edge1.Sort(); + edge2.Sort(); + if (mesh.GetIdentifications().GetSymmetric (pi1, pi4) && + mesh.GetIdentifications().GetSymmetric (pi2, pi3)) + { + //int p3 = el.PNum(pi3); + //int p4 = el.PNum(pi4); + + el.SetType(PRISM); + el.PNum(1) = pi1; + el.PNum(2) = pi2; + el.PNum(3) = pi5; + el.PNum(4) = pi4; + el.PNum(5) = pi3; + el.PNum(6) = pi5; + } + } + } + } + + for (i = 1; i <= mesh.GetNSE(); i++) + { + Element2d & el = mesh.SurfaceElement(i); + if (el.GetType() != TRIG) continue; + + for (j = 1; j <= 3; j++) + { + k = (j % 3) + 1; + INDEX_2 edge(el.PNum(j), el.PNum(k)); + edge.Sort(); + + if (mesh.GetIdentifications().GetSymmetric (el.PNum(j), el.PNum(k))) + { + int pi3 = 6-j-k; + int p3 = el.PNum(pi3); + int p1 = el.PNum(j); + int p2 = el.PNum(k); + + el.SetType(QUAD); + el.PNum(1) = p2; + el.PNum(2) = p3; + el.PNum(3) = p3; + el.PNum(4) = p1; + } + } + } + } + + + +#ifdef OLD + void MakeCornerNodes (Mesh & mesh, + INDEX_HASHTABLE & cornernodes) + { + int i, j; + int nseg = mesh.GetNSeg(); + Array edgesonpoint(mesh.GetNP()); + for (i = 1; i <= mesh.GetNP(); i++) + edgesonpoint.Elem(i) = 0; + + for (i = 1; i <= nseg; i++) + { + for (j = 1; j <= 2; j++) + { + int pi = (j == 1) ? + mesh.LineSegment(i)[0] : + mesh.LineSegment(i)[1]; + edgesonpoint.Elem(pi)++; + } + } + + /* + cout << "cornernodes: "; + for (i = 1; i <= edgesonpoint.Size(); i++) + if (edgesonpoint.Get(i) >= 6) + { + cornernodes.Set (i, 1); + cout << i << " "; + } + cout << endl; + */ + // cornernodes.Set (5, 1); + } +#endif + + + void RefinePrisms (Mesh & mesh, const CSGeometry * geom, + ZRefinementOptions & opt) + { + int i, j; + bool found, change; + int cnt = 0; + + + // markers for z-refinement: p1, p2, levels + // p1-p2 is an edge to be refined + Array ref_uniform; + Array ref_singular; + Array ref_slices; + + BitArray first_id(geom->identifications.Size()); + first_id.Set(); + + + INDEX_2_HASHTABLE & identpts = + mesh.GetIdentifications().GetIdentifiedPoints (); + + if (&identpts) + { + for (i = 1; i <= identpts.GetNBags(); i++) + for (j = 1; j <= identpts.GetBagSize(i); j++) + { + INDEX_2 pair; + int idnr; + identpts.GetData(i, j, pair, idnr); + const CloseSurfaceIdentification * csid = + dynamic_cast + (geom->identifications.Get(idnr)); + if (csid) + { + if (!csid->GetSlices().Size()) + { + if (first_id.Test (idnr)) + { + first_id.Clear(idnr); + ref_uniform.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels())); + ref_singular.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels1())); + ref_singular.Append (INDEX_3 (pair.I2(), pair.I1(), csid->RefLevels2())); + } + } + else + { + //const Array & slices = csid->GetSlices(); + INDEX_4 i4; + i4[0] = pair.I1(); + i4[1] = pair.I2(); + i4[2] = idnr; + i4[3] = csid->GetSlices().Size(); + ref_slices.Append (i4); + } + } + } + } + + + + Array epgi; + + while (1) + { + cnt++; + PrintMessage (3, "Z-Refinement, level = ", cnt); + INDEX_2_HASHTABLE refedges(mesh.GetNSE()+1); + + + found = 0; + // mark prisms due to close surface flags: + int oldsize = ref_uniform.Size(); + for (i = 1; i <= oldsize; i++) + { + int pi1 = ref_uniform.Get(i).I1(); + int pi2 = ref_uniform.Get(i).I2(); + int levels = ref_uniform.Get(i).I3(); + + if (levels > 0) + { + const Point3d & p1 = mesh.Point(pi1); + const Point3d & p2 = mesh.Point(pi2); + int npi(0); + + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (!refedges.Used(edge)) + { + Point3d np = Center (p1, p2); + npi = mesh.AddPoint (np); + refedges.Set (edge, npi); + found = 1; + } + + ref_uniform.Elem(i) = INDEX_3(pi1, npi, levels-1); + ref_uniform.Append (INDEX_3(pi2, npi, levels-1)); + } + } + for (i = 1; i <= ref_singular.Size(); i++) + { + int pi1 = ref_singular.Get(i).I1(); + int pi2 = ref_singular.Get(i).I2(); + int levels = ref_singular.Get(i).I3(); + + if (levels > 0) + { + const Point3d & p1 = mesh.Point(pi1); + const Point3d & p2 = mesh.Point(pi2); + int npi; + + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (!refedges.Used(edge)) + { + Point3d np = Center (p1, p2); + npi = mesh.AddPoint (np); + refedges.Set (edge, npi); + found = 1; + } + else + npi = refedges.Get (edge); + + ref_singular.Elem(i) = INDEX_3(pi1, npi, levels-1); + } + } + + for (i = 1; i <= ref_slices.Size(); i++) + { + int pi1 = ref_slices.Get(i)[0]; + int pi2 = ref_slices.Get(i)[1]; + int idnr = ref_slices.Get(i)[2]; + int slicenr = ref_slices.Get(i)[3]; + + if (slicenr > 0) + { + const Point3d & p1 = mesh.Point(pi1); + const Point3d & p2 = mesh.Point(pi2); + int npi; + + const CloseSurfaceIdentification * csid = + dynamic_cast + (geom->identifications.Get(idnr)); + + + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (!refedges.Used(edge)) + { + const Array & slices = csid->GetSlices(); + //(*testout) << "idnr " << idnr << " i " << i << endl; + //(*testout) << "slices " << slices << endl; + double slicefac = slices.Get(slicenr); + double slicefaclast = + (slicenr == slices.Size()) ? 1 : slices.Get(slicenr+1); + + Point3d np = p1 + (slicefac / slicefaclast) * (p2-p1); + //(*testout) << "slicenr " << slicenr << " slicefac " << slicefac << " quot " << (slicefac / slicefaclast) << " np " << np << endl; + npi = mesh.AddPoint (np); + refedges.Set (edge, npi); + found = 1; + } + else + npi = refedges.Get (edge); + + ref_slices.Elem(i)[1] = npi; + ref_slices.Elem(i)[3] --; + } + } + + + + + for (i = 1; i <= mesh.GetNE(); i++) + { + Element & el = mesh.VolumeElement (i); + if (el.GetType() != PRISM) + continue; + + for (j = 1; j <= 3; j++) + { + int pi1 = el.PNum(j); + int pi2 = el.PNum(j+3); + const Point3d & p1 = mesh.Point(pi1); + const Point3d & p2 = mesh.Point(pi2); + + bool ref = 0; + + /* + if (Dist (p1, p2) > mesh.GetH (Center (p1, p2))) + ref = 1; + */ + + /* + if (cnt <= opt.minref) + ref = 1; + */ + + /* + if ((pi1 == 460 || pi2 == 460 || + pi1 == 461 || pi2 == 461) && cnt <= 8) ref = 1; + */ + if (ref == 1) + { + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (!refedges.Used(edge)) + { + Point3d np = Center (p1, p2); + int npi = mesh.AddPoint (np); + refedges.Set (edge, npi); + found = 1; + } + } + } + } + + if (!found) break; + + // build closure: + PrintMessage (5, "start closure"); + do + { + PrintMessage (5, "start loop"); + change = 0; + for (i = 1; i <= mesh.GetNE(); i++) + { + Element & el = mesh.VolumeElement (i); + if (el.GetType() != PRISM) + continue; + + bool hasref = 0, hasnonref = 0; + for (j = 1; j <= 3; j++) + { + int pi1 = el.PNum(j); + int pi2 = el.PNum(j+3); + if (pi1 != pi2) + { + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (refedges.Used(edge)) + hasref = 1; + else + hasnonref = 1; + } + } + + if (hasref && hasnonref) + { + // cout << "el " << i << " in closure" << endl; + change = 1; + for (j = 1; j <= 3; j++) + { + int pi1 = el.PNum(j); + int pi2 = el.PNum(j+3); + const Point3d & p1 = mesh.Point(pi1); + const Point3d & p2 = mesh.Point(pi2); + + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (!refedges.Used(edge)) + { + Point3d np = Center (p1, p2); + int npi = mesh.AddPoint (np); + refedges.Set (edge, npi); + } + } + } + } + } + while (change); + + PrintMessage (5, "Do segments"); + + // (*testout) << "closure formed, np = " << mesh.GetNP() << endl; + + int oldns = mesh.GetNSeg(); + + for (i = 1; i <= oldns; i++) + { + const Segment & el = mesh.LineSegment(i); + + INDEX_2 i2(el[0], el[1]); + i2.Sort(); + + int pnew; + EdgePointGeomInfo ngi; + + if (refedges.Used(i2)) + { + pnew = refedges.Get(i2); + // ngi = epgi.Get(pnew); + } + else + { + continue; + + // Point3d pb; + + // /* + // geom->PointBetween (mesh.Point (el[0]), + // mesh.Point (el[1]), + // el.surfnr1, el.surfnr2, + // el.epgeominfo[0], el.epgeominfo[1], + // pb, ngi); + // */ + // pb = Center (mesh.Point (el[0]), mesh.Point (el[1])); + + // pnew = mesh.AddPoint (pb); + + // refedges.Set (i2, pnew); + + // if (pnew > epgi.Size()) + // epgi.SetSize (pnew); + // epgi.Elem(pnew) = ngi; + } + + Segment ns1 = el; + Segment ns2 = el; + ns1[1] = pnew; + ns1.epgeominfo[1] = ngi; + ns2[0] = pnew; + ns2.epgeominfo[0] = ngi; + + mesh.LineSegment(i) = ns1; + mesh.AddSegment (ns2); + } + + PrintMessage (5, "Segments done, NSeg = ", mesh.GetNSeg()); + + // do refinement + int oldne = mesh.GetNE(); + for (i = 1; i <= oldne; i++) + { + Element & el = mesh.VolumeElement (i); + if (el.GetNP() != 6) + continue; + + int npi[3]; + for (j = 1; j <= 3; j++) + { + int pi1 = el.PNum(j); + int pi2 = el.PNum(j+3); + + if (pi1 == pi2) + npi[j-1] = pi1; + else + { + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (refedges.Used (edge)) + npi[j-1] = refedges.Get(edge); + else + { + /* + (*testout) << "ERROR: prism " << i << " has hanging node !!" + << ", edge = " << edge << endl; + cerr << "ERROR: prism " << i << " has hanging node !!" << endl; + */ + npi[j-1] = 0; + } + } + } + + if (npi[0]) + { + Element nel1(6), nel2(6); + for (j = 1; j <= 3; j++) + { + nel1.PNum(j) = el.PNum(j); + nel1.PNum(j+3) = npi[j-1]; + nel2.PNum(j) = npi[j-1]; + nel2.PNum(j+3) = el.PNum(j+3); + } + nel1.SetIndex (el.GetIndex()); + nel2.SetIndex (el.GetIndex()); + mesh.VolumeElement (i) = nel1; + mesh.AddVolumeElement (nel2); + } + } + + + PrintMessage (5, "Elements done, NE = ", mesh.GetNE()); + + + // do surface elements + int oldnse = mesh.GetNSE(); + // cout << "oldnse = " << oldnse << endl; + for (i = 1; i <= oldnse; i++) + { + Element2d & el = mesh.SurfaceElement (i); + if (el.GetType() != QUAD) + continue; + + int index = el.GetIndex(); + int npi[2]; + for (j = 1; j <= 2; j++) + { + int pi1, pi2; + + if (j == 1) + { + pi1 = el.PNum(1); + pi2 = el.PNum(4); + } + else + { + pi1 = el.PNum(2); + pi2 = el.PNum(3); + } + + if (pi1 == pi2) + npi[j-1] = pi1; + else + { + INDEX_2 edge(pi1, pi2); + edge.Sort(); + if (refedges.Used (edge)) + npi[j-1] = refedges.Get(edge); + else + { + npi[j-1] = 0; + } + } + } + + if (npi[0]) + { + Element2d nel1(QUAD), nel2(QUAD); + for (j = 1; j <= 4; j++) + { + nel1.PNum(j) = el.PNum(j); + nel2.PNum(j) = el.PNum(j); + } + nel1.PNum(3) = npi[1]; + nel1.PNum(4) = npi[0]; + nel2.PNum(1) = npi[0]; + nel2.PNum(2) = npi[1]; + /* + for (j = 1; j <= 2; j++) + { + nel1.PNum(j) = el.PNum(j); + nel1.PNum(j+2) = npi[j-1]; + nel2.PNum(j) = npi[j-1]; + nel2.PNum(j+2) = el.PNum(j+2); + } + */ + nel1.SetIndex (el.GetIndex()); + nel2.SetIndex (el.GetIndex()); + + mesh.SurfaceElement (i) = nel1; + mesh.AddSurfaceElement (nel2); + + int si = mesh.GetFaceDescriptor (index).SurfNr(); + + Point<3> hp = mesh.Point(npi[0]); + geom->GetSurface(si)->Project (hp); + mesh.Point (npi[0]).SetPoint (hp); + + hp = mesh.Point(npi[1]); + geom->GetSurface(si)->Project (hp); + mesh.Point (npi[1]).SetPoint (hp); + + // geom->GetSurface(si)->Project (mesh.Point(npi[0])); + // geom->GetSurface(si)->Project (mesh.Point(npi[1])); + } + } + + mesh.RebuildSurfaceElementLists(); + PrintMessage (5, "Surface elements done, NSE = ", mesh.GetNSE()); + } + + } + + + + void ZRefinement (Mesh & mesh, const NetgenGeometry * hgeom, + ZRefinementOptions & opt) + { + const CSGeometry * geom = dynamic_cast (hgeom); + if (!geom) return; + + INDEX_2_HASHTABLE singedges(mesh.GetNSeg()); + + SelectSingularEdges (mesh, *geom, singedges, opt); + //MakePrismsSingEdge (mesh, singedges); + MakePrismsClosePoints (mesh); + + RefinePrisms (mesh, geom, opt); + } + + + + ZRefinementOptions :: ZRefinementOptions() + { + minref = 0; + } + +} diff --git a/libsrc/occ/Makefile.am b/libsrc/occ/Makefile.am new file mode 100644 index 00000000..6569192d --- /dev/null +++ b/libsrc/occ/Makefile.am @@ -0,0 +1,33 @@ +noinst_HEADERS = occgeom.hpp occmeshsurf.hpp \ +Partition_Inter2d.hxx Partition_Loop2d.hxx Partition_Loop.hxx \ +Partition_Inter3d.hxx Partition_Loop3d.hxx Partition_Spliter.hxx \ +Partition_Inter2d.ixx Partition_Loop2d.ixx Partition_Loop.ixx \ +Partition_Inter3d.ixx Partition_Loop3d.ixx Partition_Spliter.ixx \ +Partition_Inter2d.jxx Partition_Loop2d.jxx Partition_Loop.jxx \ +Partition_Inter3d.jxx Partition_Loop3d.jxx Partition_Spliter.jxx \ +utilities.h vsocc.hpp + + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(OCCFLAGS) $(TCL_INCLUDES) + +# $(OCC_INC_FLAG) + +METASOURCES = AUTO + +lib_LTLIBRARIES = libocc.la + +if NGGUI +lib_LTLIBRARIES += liboccvis.la +endif + + +libocc_la_SOURCES = Partition_Inter2d.cxx Partition_Inter3d.cxx \ + Partition_Loop.cxx Partition_Loop2d.cxx Partition_Loop3d.cxx Partition_Spliter.cxx \ + occconstruction.cpp occgenmesh.cpp occgeom.cpp occmeshsurf.cpp + +libocc_la_LIBADD = $(OCCLIBS) + +liboccvis_la_SOURCES = occpkg.cpp vsocc.cpp +liboccvis_la_LIBADD = libocc.la + + diff --git a/libsrc/occ/Makefile.in b/libsrc/occ/Makefile.in new file mode 100644 index 00000000..baea0e42 --- /dev/null +++ b/libsrc/occ/Makefile.in @@ -0,0 +1,649 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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@ +@NGGUI_TRUE@am__append_1 = liboccvis.la +subdir = libsrc/occ +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +libocc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libocc_la_OBJECTS = Partition_Inter2d.lo Partition_Inter3d.lo \ + Partition_Loop.lo Partition_Loop2d.lo Partition_Loop3d.lo \ + Partition_Spliter.lo occconstruction.lo occgenmesh.lo \ + occgeom.lo occmeshsurf.lo +libocc_la_OBJECTS = $(am_libocc_la_OBJECTS) +liboccvis_la_DEPENDENCIES = libocc.la +am_liboccvis_la_OBJECTS = occpkg.lo vsocc.lo +liboccvis_la_OBJECTS = $(am_liboccvis_la_OBJECTS) +@NGGUI_TRUE@am_liboccvis_la_rpath = -rpath $(libdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libocc_la_SOURCES) $(liboccvis_la_SOURCES) +DIST_SOURCES = $(libocc_la_SOURCES) $(liboccvis_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = occgeom.hpp occmeshsurf.hpp \ +Partition_Inter2d.hxx Partition_Loop2d.hxx Partition_Loop.hxx \ +Partition_Inter3d.hxx Partition_Loop3d.hxx Partition_Spliter.hxx \ +Partition_Inter2d.ixx Partition_Loop2d.ixx Partition_Loop.ixx \ +Partition_Inter3d.ixx Partition_Loop3d.ixx Partition_Spliter.ixx \ +Partition_Inter2d.jxx Partition_Loop2d.jxx Partition_Loop.jxx \ +Partition_Inter3d.jxx Partition_Loop3d.jxx Partition_Spliter.jxx \ +utilities.h vsocc.hpp + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(OCCFLAGS) $(TCL_INCLUDES) + +# $(OCC_INC_FLAG) +METASOURCES = AUTO +lib_LTLIBRARIES = libocc.la $(am__append_1) +libocc_la_SOURCES = Partition_Inter2d.cxx Partition_Inter3d.cxx \ + Partition_Loop.cxx Partition_Loop2d.cxx Partition_Loop3d.cxx Partition_Spliter.cxx \ + occconstruction.cpp occgenmesh.cpp occgeom.cpp occmeshsurf.cpp + +libocc_la_LIBADD = $(OCCLIBS) +liboccvis_la_SOURCES = occpkg.cpp vsocc.cpp +liboccvis_la_LIBADD = libocc.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .cxx .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) --foreign libsrc/occ/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/occ/Makefile +.PRECIOUS: 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): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libocc.la: $(libocc_la_OBJECTS) $(libocc_la_DEPENDENCIES) $(EXTRA_libocc_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libocc_la_OBJECTS) $(libocc_la_LIBADD) $(LIBS) +liboccvis.la: $(liboccvis_la_OBJECTS) $(liboccvis_la_DEPENDENCIES) $(EXTRA_liboccvis_la_DEPENDENCIES) + $(CXXLINK) $(am_liboccvis_la_rpath) $(liboccvis_la_OBJECTS) $(liboccvis_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Inter2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Inter3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Loop.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Loop2d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Loop3d.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Partition_Spliter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occconstruction.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occgenmesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occgeom.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occmeshsurf.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occpkg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsocc.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +.cxx.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + 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-libLTLIBRARIES + +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: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES 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 uninstall uninstall-am uninstall-libLTLIBRARIES + + +# 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/libsrc/occ/Partition_Inter2d.cxx b/libsrc/occ/Partition_Inter2d.cxx new file mode 100644 index 00000000..70095527 --- /dev/null +++ b/libsrc/occ/Partition_Inter2d.cxx @@ -0,0 +1,678 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R& D, LEG, PRINCIPIA R& D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter2d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Inter2d.cxx,v 1.5 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; + +#include "Partition_Inter2d.ixx" + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEB +static Standard_Boolean TestEdges = 0; +static Standard_Integer NbF2d = 0; +static Standard_Integer NbE2d = 0; +#endif + +//======================================================================= +//function : getOtherShape +//purpose : +//======================================================================= + +static TopoDS_Shape getOtherShape(const TopoDS_Shape& theS, + const TopTools_ListOfShape& theSList) +{ + TopTools_ListIteratorOfListOfShape anIt( theSList ); + for ( ; anIt.More(); anIt.Next() ) + if (!theS.IsSame( anIt.Value() )) + return anIt.Value(); + + return TopoDS_Shape(); +} + +//======================================================================= +//function : findVOnE +//purpose : on theE, find a vertex close to theV, such that an edge +// passing through it is an itersection of theF1 and theF2. +// theE intersects theE2 at theV +//======================================================================= + +static Standard_Boolean findVOnE(const TopoDS_Vertex & theV, + const TopoDS_Edge& theE, + const TopoDS_Edge& theE2, + const TopoDS_Shape& theF1, + const TopoDS_Shape& theF2, + const Handle(BRepAlgo_AsDes)& theAsDes, + TopoDS_Vertex & theFoundV) +{ + Standard_Real MinDist2 = ::RealLast(); + gp_Pnt P; + + // check all vertices on theE + const TopTools_ListOfShape& aVList = theAsDes->Descendant( theE ); + TopTools_ListIteratorOfListOfShape anIt( aVList ); + if (anIt.More()) + P = BRep_Tool::Pnt( theV ); + for ( ; anIt.More(); anIt.Next() ) + { + // check by distance + TopoDS_Vertex & V = TopoDS::Vertex( anIt.Value() ); + Standard_Real dist2 = P.SquareDistance( BRep_Tool::Pnt( V )); + if (dist2 < MinDist2) + MinDist2 = dist2; + else + continue; + + // V is a candidate if among edges passing through V there is one + // which is an intersection of theF1 and theF2 + TopTools_ListIteratorOfListOfShape anEIt( theAsDes->Ascendant( V )); + Standard_Boolean isOk = Standard_False; + for ( ; !isOk && anEIt.More(); anEIt.Next() ) + { + const TopoDS_Shape & E2 = anEIt.Value(); + if ( theE2.IsSame( E2 )) + continue; + const TopTools_ListOfShape & aFList = theAsDes->Ascendant( E2 ); + if (aFList.IsEmpty()) + continue; + if ( theF1.IsSame( aFList.First() )) + isOk = theF2.IsSame( aFList.Last() ); + else + isOk = theF2.IsSame( aFList.First() ) && theF1.IsSame( aFList.Last() ); + } + if (isOk) + theFoundV = V; + } + + if (theFoundV.IsNull()) + return Standard_False; + + // check that MinDist2 is not too large + Standard_Real f, l; + TopLoc_Location L; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theE, L, f, l ); + gp_Pnt P1 = aCurve->Value( f ); + gp_Pnt P2 = aCurve->Value( 0.3 * f + 0.7 * l ); + //gp_Pnt P2 = aCurve->Value( 0.5 * ( f + l )); + if (MinDist2 > P1.SquareDistance( P2 )) + return Standard_False; + +#ifdef DEB + MESSAGE("findVOnE: found MinDist = " << sqrt (MinDist2)); +#endif + + return Standard_True; +} + +//======================================================================= +//function : AddVonE +//purpose : Put V in AsDes as intersection of E1 and E2. +// Check that vertex equal to V already exists on one +// of edges, in such a case, V is not added but +// existing vertex is updated to be on E1 and E2 and +// is returned insead of V. +//======================================================================= + +TopoDS_Vertex Partition_Inter2d::AddVonE(const TopoDS_Vertex& theV, + const TopoDS_Edge& E1, + const TopoDS_Edge& E2, + const Handle(BRepAlgo_AsDes)& AsDes, + const TopoDS_Face& theF) + +{ + //------------------------------------------------------------- + // test if the points of intersection already exist. If not, + // add as descendants of the edges. + // nb: theses points are only vertices of intersection. + //------------------------------------------------------------- + const TopTools_ListOfShape& VOnE1 = AsDes->Descendant(E1); + const TopTools_ListOfShape& VOnE2 = AsDes->Descendant(E2); + gp_Pnt P1,P2; + TopoDS_Vertex V1,V2; + TopTools_ListIteratorOfListOfShape it; + BRep_Builder B; + TopAbs_Orientation O1,O2; + Standard_Real U1,U2; + Standard_Real Tol,Tol1,Tol2; + Standard_Boolean OnE1,OnE2; + + TopoDS_Vertex V = theV; + + U1 = BRep_Tool::Parameter(V,E1); + U2 = BRep_Tool::Parameter(V,E2); + O1 = V.Orientation(); + O2 = O1; + P1 = BRep_Tool::Pnt(V); + Tol = BRep_Tool::Tolerance( V ); + OnE1 = OnE2 = Standard_False; + + //----------------------------------------------------------------- + // Search if the point of intersection is a vertex of E1. + //----------------------------------------------------------------- + for (it.Initialize(VOnE1); it.More(); it.Next()) { + const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); + if (V.IsSame( CV )) { + V1 = V; + OnE1 = Standard_True; + break; + } + P2 = BRep_Tool::Pnt( CV ); + Tol1 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); + if (P1.SquareDistance(P2) <= Tol1*Tol1) { + V = CV; + V1 = V; + OnE1 = Standard_True; + break; + } + } + if (OnE1) { + //----------------------------------------------------------------- + // Search if the vertex found is still on E2. + //----------------------------------------------------------------- + for (it.Initialize(VOnE2); it.More(); it.Next()) { + if (V.IsSame( it.Value() )) { + OnE2 = Standard_True; + V2 = V; + break; + } + } + } + if (!OnE2) { + for (it.Initialize(VOnE2); it.More(); it.Next()) { + //----------------------------------------------------------------- + // Search if the point of intersection is a vertex of E2. + //----------------------------------------------------------------- + const TopoDS_Vertex& CV = TopoDS::Vertex( it.Value() ); + P2 = BRep_Tool::Pnt( CV ); + Tol2 = 1.1*(Tol + BRep_Tool::Tolerance( CV )); + if (P1.SquareDistance(P2) <= Tol2*Tol2) { + V = CV; + V2 = V; + OnE2 = Standard_True; + break; + } + } + } + + + if (!OnE1 && !OnE2 && !theF.IsNull()) + { + // if 3 faces intersects each others, 3 new edges on them must pass + // through one vertex but real intersection points of each + // pair of edges are sometimes more far than a tolerance. + // Try to analitically find vertices that E1 and E2 must pass trough + + TopoDS_Shape F1 = getOtherShape( theF, AsDes->Ascendant( E1 )); + TopoDS_Shape F2 = getOtherShape( theF, AsDes->Ascendant( E2 )); + if (!F1.IsNull() && !F2.IsNull() && !F1.IsSame( F2 )) + { + OnE1 = findVOnE ( theV, E1, E2, F1, F2, AsDes, V1 ); + OnE2 = findVOnE ( theV, E2, E1, F1, F2, AsDes, V2 ); + if (OnE2) V = V2; + if (OnE1) V = V1; + } + } + + if (OnE1 && OnE2) { + if (!V1.IsSame(V2)) { + // replace V1 with V2 on all edges V1 is on + Standard_Real UV1; + TopoDS_Edge EWE1; + TopoDS_Vertex VI; + const TopTools_ListOfShape& EdgeWithV1 = AsDes->Ascendant(V1); + + for (it.Initialize(EdgeWithV1); it.More(); it.Next()) { + EWE1 = TopoDS::Edge(it.Value()); + VI = V1; + VI.Orientation(TopAbs_INTERNAL); + UV1 = BRep_Tool::Parameter(VI,EWE1); + VI = V2; + VI.Orientation(TopAbs_INTERNAL); + B.UpdateVertex( VI, UV1, EWE1, GetTolerance( VI, UV1, EWE1, AsDes)); + } + AsDes->Replace(V1,V2); + V = V2; + } + } + + // add existing vertices instead of new ones + if (!OnE1) { + if (OnE2) { + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex (V, U1, E1, GetTolerance( V, U1, E1, AsDes)); + } + V.Orientation(O1); + AsDes->Add(E1,V); + } + if (!OnE2) { + if (OnE1) { + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex (V, U2, E2, GetTolerance( V, U2, E2, AsDes )); + } + V.Orientation(O2); + AsDes->Add(E2,V); + } + + return V; +} + +//======================================================================= +//function : FindEndVertex +//purpose : Returns a vertex from having parameter on +// closest to or . is True if +// found vertex is closer to . returns parameter +// difference. +//======================================================================= + +TopoDS_Vertex Partition_Inter2d::FindEndVertex(const TopTools_ListOfShape& LV, + const Standard_Real f, + const Standard_Real l, + const TopoDS_Edge& E, + Standard_Boolean& isFirst, + Standard_Real& minDU) +{ + TopoDS_Vertex endV; + Standard_Real U, endU, min; + minDU = 1.e10; + + TopTools_ListIteratorOfListOfShape it; + it.Initialize(LV); + for (; it.More(); it.Next()) { + const TopoDS_Vertex& v = TopoDS::Vertex(it.Value()); + U = BRep_Tool::Parameter(v, E); + min = Min( Abs(U-f), Abs(U-l) ); + if (min < minDU) { + endV = v; + endU = U; + minDU = min; + } + } + if (Abs(endU-f) < Abs(endU-l)) + isFirst = Standard_True; + else + isFirst = Standard_False; + + return endV; +} + +//======================================================================= +//function : treatClosed +//purpose : add second vertex to closed edge. Vertex is one of +//======================================================================= + +static void treatClosed (const TopoDS_Edge& E1, + const Standard_Real f, + const Standard_Real l, + TopTools_ListOfShape& LV1, + TopTools_ListOfShape& /*LV2*/) +{ + Standard_Boolean isFirst=0; + Standard_Real minDU = 1.e10; + TopoDS_Vertex endV; + endV = Partition_Inter2d::FindEndVertex(LV1, f,l, E1, isFirst,minDU); + + if (minDU > Precision::PConfusion()) + return; // not end point + + Standard_Real newU; + if (isFirst) + newU = f + (l - f); + else + newU = l - (l - f); + + // update end parameter + BRep_Builder B; + endV.Orientation(TopAbs_INTERNAL); + B.UpdateVertex(endV,newU,E1,BRep_Tool::Tolerance(endV)); +} + +//======================================================================= +//function : EdgesPartition +//purpose : +//======================================================================= + +static void EdgesPartition(const TopoDS_Face& F, + const TopoDS_Edge& E1, + const TopoDS_Edge& E2, + const Handle(BRepAlgo_AsDes)& AsDes, + const TopTools_MapOfShape& NewEdges, + const Standard_Boolean WithOri) +{ + + Standard_Real f[3],l[3]; + Standard_Real MilTol2; + Standard_Real Tol = Max (BRep_Tool::Tolerance(E1), + BRep_Tool::Tolerance(E2)); + MilTol2 = Tol * Tol * 10; + + BRep_Tool::Range(E1, f[1], l[1]); + BRep_Tool::Range(E2, f[2], l[2]); + + BRepAdaptor_Curve CE1(E1,F); + BRepAdaptor_Curve CE2(E2,F); + + TopoDS_Edge EI[3]; EI[1] = E1; EI[2] = E2; + TopTools_ListOfShape LV1; // new vertices at intersections on E1 + TopTools_ListOfShape LV2; // ... on E2 + BRep_Builder B; + + // if E1 and E2 are results of intersection of F and two connex faces then + // no need to intersect edges, they can contact by vertices only + // (encounted an exception in TopOpeBRep_EdgesIntersector in such a case) + Standard_Boolean intersect = Standard_True; + TopTools_IndexedMapOfShape ME; + TopExp::MapShapes(F, TopAbs_EDGE, ME); + if (!ME.Contains(E1) && ! ME.Contains(E2)) { // if E1 and E2 are new on F + TopoDS_Shape F1, F2; + const TopTools_ListOfShape& LF1 = AsDes->Ascendant( E1 ); + F1 = F.IsSame( LF1.First() ) ? LF1.Last() : LF1.First(); + const TopTools_ListOfShape& LF2 = AsDes->Ascendant( E2 ); + F2 = F.IsSame( LF2.First() ) ? LF2.Last() : LF2.First(); + if (!F.IsSame(F2) && !F.IsSame(F1) ) { + TopExp_Explorer exp(F2, TopAbs_EDGE); + TopExp::MapShapes(F1, TopAbs_EDGE, ME); + for (; exp.More(); exp.Next()) { + if (ME.Contains( exp.Current())) { + intersect = Standard_False; + break; + } + } + } + } + + if (intersect) { + //------------------------------------------------------ + // compute the points of Intersection in 2D + //----------------------------------------------------- + // i.e. fill LV1 and LV2 + TopOpeBRep_EdgesIntersector EInter; + EInter.SetFaces(F,F); + Standard_Real TolDub = 1.e-7; + EInter.ForceTolerances(TolDub,TolDub); + Standard_Boolean reducesegments = Standard_False; + EInter.Perform (E1,E2,reducesegments); + + Standard_Boolean rejectreducedsegmentpoints = Standard_False; + EInter.InitPoint(rejectreducedsegmentpoints); + for ( ; EInter.MorePoint(); EInter.NextPoint() ) + { + const TopOpeBRep_Point2d& P2D = EInter.Point(); + const gp_Pnt& P = P2D.Value(); + TopoDS_Vertex V = BRepLib_MakeVertex(P); + + //------------------------- + // control the point found. + //------------------------- + gp_Pnt P1 = CE1.Value(P2D.Parameter(1)); + gp_Pnt P2 = CE2.Value(P2D.Parameter(2)); + Standard_Real sqd1 = P1.SquareDistance(P); + Standard_Real sqd2 = P2.SquareDistance(P); + if (sqd1 > MilTol2 || sqd2 > MilTol2 ) + continue; + + // add a new vertex to the both edges + Standard_Real toler = Max( Tol, sqrt( Max( sqd1, sqd2 ))); + Standard_Integer i; + for (i = 1; i <= 2; i++) { + Standard_Real U = P2D.Parameter(i); + V.Orientation(TopAbs_INTERNAL); + B.UpdateVertex( V,U,EI[i], toler); + TopAbs_Orientation OO = TopAbs_REVERSED; + if (WithOri) { + if (P2D.IsVertex(i)) + OO = P2D.Vertex(i).Orientation(); + else if (P2D.Transition(i).Before() == TopAbs_OUT) { + OO = TopAbs_FORWARD; + } + V.Orientation(OO); + if (i == 1) LV1.Append(V); + else LV2.Append(V); + } + } + } + } // if (intersect) + + //---------------------------------- + // Test the extremities of the edges. + //---------------------------------- + // add to LV* vertices for vertex-vertex closeness + Standard_Real U1,U2; + Standard_Real TolConf2, TolConf; + TopoDS_Vertex V1[2],V2[2]; + TopExp::Vertices(E1,V1[0],V1[1]); + TopExp::Vertices(E2,V2[0],V2[1]); + + Standard_Integer i,j,k; + for (j = 0; j < 2; j++) { + if (V1[j].IsNull()) continue; + for ( k = 0; k < 2; k++) { + if (V2[k].IsNull()) continue; + gp_Pnt P1 = BRep_Tool::Pnt(V1[j]); + gp_Pnt P2 = BRep_Tool::Pnt(V2[k]); + TolConf = BRep_Tool::Tolerance(V1[j]) + BRep_Tool::Tolerance(V2[k]); + TolConf = Max (Tol, TolConf); + TolConf2 = TolConf * TolConf; + if (!intersect) + TolConf2 *= 100; + Standard_Real SqDist = P1.SquareDistance(P2); + + if (SqDist <= TolConf2) { + TopoDS_Vertex V = BRepLib_MakeVertex(P1); + V.Orientation(TopAbs_INTERNAL); + U1 = (j == 0) ? f[1] : l[1]; + U2 = (k == 0) ? f[2] : l[2]; + B.UpdateVertex(V,U1,E1,TolConf); + B.UpdateVertex(V,U2,E2,TolConf); + LV1.Prepend(V.Oriented(V1[j].Orientation())); + LV2.Prepend(V.Oriented(V2[k].Orientation())); + } + } + } + + Standard_Boolean AffichPurge = Standard_False; + + if ( LV1.IsEmpty()) return; + + //---------------------------------- + // Purge of all the vertices. + //---------------------------------- + // remove one of close vertices + TopTools_ListIteratorOfListOfShape it1LV1,it1LV2,it2LV1; + gp_Pnt P1,P2; + Standard_Boolean Purge = Standard_True; + + while (Purge) { + i = 1; + Purge = Standard_False; + for (it1LV1.Initialize(LV1),it1LV2.Initialize(LV2); + it1LV1.More(); + it1LV1.Next(),it1LV2.Next()) { + j = 1; + it2LV1.Initialize(LV1); + while (j < i) { + const TopoDS_Vertex& VE1 = TopoDS::Vertex(it1LV1.Value()); + const TopoDS_Vertex& VE2 = TopoDS::Vertex(it2LV1.Value()); + Standard_Real Tol1 = BRep_Tool::Tolerance( VE1 ); + Standard_Real Tol2 = BRep_Tool::Tolerance( VE2 ); + P1 = BRep_Tool::Pnt( VE1 ); + P2 = BRep_Tool::Pnt( VE2 ); + if (P1.IsEqual(P2, Tol1 + Tol2)) { + LV1.Remove(it1LV1); + LV2.Remove(it1LV2); + Purge = Standard_True; + break; + } + j++; + it2LV1.Next(); + } + if (Purge) break; + i++; + } + } + + // care of new closed edges, they always intersect with seam at end + if (V1[0].IsSame( V1[1] ) && NewEdges.Contains(E1) ) + treatClosed (E1, f[1], l[1], LV1, LV2); + if (V2[0].IsSame( V2[1] ) && NewEdges.Contains(E2) ) + treatClosed (E2, f[2], l[2], LV2, LV1); + + //---------------- + // Stocking vertex + //---------------- + + for ( it1LV1.Initialize( LV1 ); it1LV1.More(); it1LV1.Next()) + Partition_Inter2d::AddVonE (TopoDS::Vertex( it1LV1.Value()), + E1, E2, AsDes, F); +} + +//======================================================================= +//function : CompletPart2d +//purpose : Computes the intersections between the edges stored +// is AsDes as descendants of . Intersections is computed +// between two edges if one of them is bound in NewEdges. +//======================================================================= + +void Partition_Inter2d::CompletPart2d (const Handle(BRepAlgo_AsDes)& AsDes, + const TopoDS_Face& F, + const TopTools_MapOfShape& NewEdges) +{ + +#ifdef DEB + NbF2d++; + NbE2d = 0; +#endif + + //Do not intersect the edges of a face + TopTools_IndexedMapOfShape EdgesOfFace; + TopExp::MapShapes( F, TopAbs_EDGE , EdgesOfFace); + + //------------------------------------------------------------------- + // compute the intersection2D on the faces touched by the intersection3D + //------------------------------------------------------------------- + TopTools_ListIteratorOfListOfShape it1LE ; + TopTools_ListIteratorOfListOfShape it2LE ; + + //----------------------------------------------- + // Intersection edge-edge. + //----------------------------------------------- + const TopTools_ListOfShape& LE = AsDes->Descendant(F); + TopoDS_Vertex V1,V2; + Standard_Integer j, i = 1; + + TopoDS_Face FF = F; + FF.Orientation(TopAbs_FORWARD); + + for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) { + const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value()); + j = 1; + it2LE.Initialize(LE); + + while (j < i && it2LE.More()) { + const TopoDS_Edge& E2 = TopoDS::Edge(it2LE.Value()); + //---------------------------------------------------------- + // Intersections of the new edges obtained by intersection + // between them and with the restrictions edges + //---------------------------------------------------------- + if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) && + (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) { + EdgesPartition(FF,E1,E2,AsDes,NewEdges,Standard_True); + } + it2LE.Next(); + j++; + } + i++; + } +} + +//======================================================================= +//function : GetTolerance +//purpose : Returns tolerance theV must have atfer its +// addition to theE with theU parameter. theAsDes is +// used to find pcurves of theE +//======================================================================= + +Standard_Real Partition_Inter2d::GetTolerance + (const TopoDS_Vertex & theV, + const Standard_Real theU, + const TopoDS_Edge & theE, + const Handle(BRepAlgo_AsDes)& theAsDes) +{ + Standard_Real aTol = BRep_Tool::Tolerance( theV ); + gp_Pnt aPnt = BRep_Tool::Pnt( theV ); + + // check point on 3D curve + Standard_Real f,l; + Handle(Geom_Curve) C = BRep_Tool::Curve( theE, f, l ); + if (!C.IsNull()) + aTol = Max ( aTol, aPnt.Distance( C->Value( theU ))); + + // check points on pcurves + const TopTools_ListOfShape& aFList = theAsDes->Ascendant( theE ); + TopTools_ListIteratorOfListOfShape aFIt( aFList ); + for ( ; aFIt.More(); aFIt.Next() ) + { + const TopoDS_Face& F = TopoDS::Face( aFIt.Value() ); + Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( theE, F, f, l ); + if (!pcurve.IsNull()) + { + gp_Pnt2d aPnt2d = pcurve->Value( theU ); + TopLoc_Location L; + Handle(Geom_Surface) S = BRep_Tool::Surface( F, L ); + gp_Pnt aPntOnS = S->Value( aPnt2d.X(), aPnt2d.Y() ); + if (!L.IsIdentity()) + aPntOnS.Transform( L.Transformation() ); + aTol = Max ( aTol, aPnt.Distance( aPntOnS )); + } + } + + return aTol; +} + +#endif diff --git a/libsrc/occ/Partition_Inter2d.hxx b/libsrc/occ/Partition_Inter2d.hxx new file mode 100644 index 00000000..cfd4a9ac --- /dev/null +++ b/libsrc/occ/Partition_Inter2d.hxx @@ -0,0 +1,110 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter2d.hxx +// Module : GEOM + +#ifndef _Partition_Inter2d_HeaderFile +#define _Partition_Inter2d_HeaderFile + +#ifndef _Handle_BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _Standard_Real_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +class BRepAlgo_AsDes; +class TopoDS_Face; +class TopTools_MapOfShape; +class TopoDS_Vertex; +class TopTools_ListOfShape; +class TopoDS_Edge; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Inter2d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // + static void CompletPart2d(const Handle(BRepAlgo_AsDes)& AsDes,const TopoDS_Face& F,const TopTools_MapOfShape& NewEdges) ; + static TopoDS_Vertex FindEndVertex(const TopTools_ListOfShape& VertList,const Standard_Real f,const Standard_Real l,const TopoDS_Edge& E,Standard_Boolean& First,Standard_Real& DU) ; + static TopoDS_Vertex AddVonE(const TopoDS_Vertex& V,const TopoDS_Edge& E1,const TopoDS_Edge& E2,const Handle(BRepAlgo_AsDes)& AsDes,const TopoDS_Face& F) ; + static Standard_Real GetTolerance(const TopoDS_Vertex& theV,const Standard_Real theU,const TopoDS_Edge& theE,const Handle(BRepAlgo_AsDes)& theAsDes) ; + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/libsrc/occ/Partition_Inter2d.ixx b/libsrc/occ/Partition_Inter2d.ixx new file mode 100644 index 00000000..5dbe7193 --- /dev/null +++ b/libsrc/occ/Partition_Inter2d.ixx @@ -0,0 +1,32 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter2d.ixx +// Module : GEOM + +#include +#include "Partition_Inter2d.jxx" + + + + diff --git a/libsrc/occ/Partition_Inter2d.jxx b/libsrc/occ/Partition_Inter2d.jxx new file mode 100644 index 00000000..2d085275 --- /dev/null +++ b/libsrc/occ/Partition_Inter2d.jxx @@ -0,0 +1,50 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter2d.jxx +// Module : GEOM + +#include // netgen headers + + +#ifndef _BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Vertex_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _Partition_Inter2d_HeaderFile +#include "Partition_Inter2d.hxx" +#endif diff --git a/libsrc/occ/Partition_Inter3d.cxx b/libsrc/occ/Partition_Inter3d.cxx new file mode 100644 index 00000000..a47ff2df --- /dev/null +++ b/libsrc/occ/Partition_Inter3d.cxx @@ -0,0 +1,947 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter3d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Inter3d.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include + +#include "Partition_Inter2d.hxx" +#include "Partition_Inter3d.ixx" +#include "utilities.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DEB +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Inter3d +//purpose : +//======================================================================= + +Partition_Inter3d::Partition_Inter3d() +{ +} +//======================================================================= +//function : Partition_Inter3d +//purpose : +//======================================================================= + +Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes) + :myAsDes(AsDes) +{ + mySectionEdgesAD = new BRepAlgo_AsDes; +} + +//======================================================================= +//function : CompletPart3d +//purpose : FaceShapeMap is just to know the shape a face belongs to +//======================================================================= + +void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1, + const TopTools_DataMapOfShapeShape& FaceShapeMap) +{ + if (myAsDes.IsNull()) + myAsDes = new BRepAlgo_AsDes; + + TopTools_ListIteratorOfListOfShape it; + + //--------------------------------------------------------------- + // Construction of bounding boxes. + //--------------------------------------------------------------- + + BRep_Builder B; + TopoDS_Compound CompOS; + B.MakeCompound(CompOS); + for (it.Initialize(SetOfFaces1); it.More(); it.Next()) + B.Add(CompOS, it.Value()); + + TopOpeBRepTool_BoxSort BOS; + BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE); + + for (it.Initialize(SetOfFaces1); it.More(); it.Next()) { + TopoDS_Face F1 = TopoDS::Face(it.Value()); + + // avoid intersecting faces of one shape + TopoDS_Shape S1; + if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1); + + // to filter faces sharing an edge + TopTools_IndexedMapOfShape EM; + TopExp::MapShapes( F1, TopAbs_EDGE, EM); + + TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1); + for (; itLI.More(); itLI.Next()) { + TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI)); + if (F1.IsSame(F2) || IsDone(F1,F2)) + continue; + + TopoDS_Shape S2; + if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2); + if (!S1.IsNull() && S1.IsSame(S2)) + continue; // descendants of one shape + + TopExp_Explorer expE (F2, TopAbs_EDGE); + for ( ; expE.More(); expE.Next()) + if (EM.Contains( expE.Current() )) + break; + if (expE.More()) + { + // faces have a common edge, check if they are a tool and a face + // generated by the tool in another shape; in that case they are + // to be intersected + TopLoc_Location L1, L2; + Handle(Geom_Surface) S1 = BRep_Tool::Surface( F1, L1 ); + Handle(Geom_Surface) S2 = BRep_Tool::Surface( F2, L2 ); + if ( S1 != S2 || L1 != L2 ) + continue; + } + + F1.Orientation(TopAbs_FORWARD); + F2.Orientation(TopAbs_FORWARD); + FacesPartition(F1,F2); + } + + // mark as modified a face which has at least one new edge + if (!myAsDes->HasDescendant( F1 )) + continue; + TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 )); + for ( ; itE.More(); itE.Next()) { + if (myNewEdges.Contains( itE.Value())) { + myTouched.Add( F1 ); + break; + } + } + } +} + +//======================================================================= +//function : PutInBounds +//purpose : +//======================================================================= + +static void PutInBounds (const TopoDS_Face& F, + const TopoDS_Edge& E, + Handle(Geom2d_Curve)& C2d) +{ + Standard_Real umin,umax,vmin,vmax; + Standard_Real f,l; + BRep_Tool::Range(E,f,l); + + TopLoc_Location L; // Recup S avec la location pour eviter la copie. + Handle (Geom_Surface) S = BRep_Tool::Surface(F,L); + + if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { + S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface(); + } + if (!S->IsUPeriodic() && !S->IsVPeriodic()) + return; + + BRepTools::UVBounds(F,umin,umax,vmin,vmax); + + gp_Pnt2d Pf = C2d->Value(f); + gp_Pnt2d Pl = C2d->Value(l); + const Standard_Real Um = 0.34*f + 0.66*l; + gp_Pnt2d Pm = C2d->Value( Um ); + + // sometimes on shpere, pcurve is out of domain by V though S is + // UPeriodic, sometimes it is in domain but nontheless it has + // wrong position. + // Check pcurve position by 3D point + if (S->IsKind(STANDARD_TYPE( Geom_SphericalSurface ))) + { + // get point on the surface + gp_Pnt Ps = S->Value( Pm.X(), Pm.Y() ); + // get point on the edge + Handle(Geom_Curve) C = BRep_Tool::Curve( E, f, l ); + gp_Pnt Pc = C->Value( Um ); + // compare points + Standard_Real TolE = BRep_Tool::Tolerance( E ); + if ( Pc.SquareDistance( Ps ) * 0.95 < TolE * TolE ) + return; // OK + + // find good UV for Pc: project Pc on S + GeomAdaptor_Surface SA (S); + Extrema_ExtPS anExtPS (Pc, SA, + SA.UResolution( TolE ), SA.VResolution( TolE )); + if (anExtPS.IsDone()) + { + Standard_Integer i, nbExt = anExtPS.NbExt(); + Extrema_POnSurf aPOnSurf; + for (i = 1; i <= nbExt; ++i ) + if (anExtPS.Value( i ) <= TolE) // V6.3 + // if (anExtPS.SquareDistance( i ) <= TolE) // V6.5 + { + aPOnSurf = anExtPS.Point( i ); + break; + } + if (i <= nbExt) { + // a point found + Standard_Real u, v; + aPOnSurf.Parameter( u, v ); + gp_Pnt2d aGoodPm ( u, v ); + C2d->Translate( Pm , aGoodPm ); + } + } + } + + //--------------- + // Recadre en U. + //--------------- + if (S->IsUPeriodic()) { + Standard_Real period = S->UPeriod(); + Standard_Real eps = period*1.e-6; + Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X()); + Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X()); + Standard_Real du = 0.; + if (minC< umin - eps) { + du = (int((umin - minC)/period) + 1)*period; + } + if (minC > umax + eps) { + du = -(int((minC - umax)/period) + 1)*period; + } + if (du != 0) { + gp_Vec2d T1(du,0.); + C2d->Translate(T1); + minC += du; maxC += du; + } + // Ajuste au mieux la courbe dans le domaine. + if (maxC > umax +100*eps) { + Standard_Real d1 = maxC - umax; + Standard_Real d2 = umin - minC + period; + if (d2 < d1) du =-period; + if ( du != 0.) { + gp_Vec2d T2(du,0.); + C2d->Translate(T2); + } + } + } + //------------------ + // Recadre en V. + //------------------ + if (S->IsVPeriodic()) { + Standard_Real period = S->VPeriod(); + Standard_Real eps = period*1.e-6; + Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y()); + Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y()); + Standard_Real dv = 0.; + if (minC< vmin - eps) { + dv = (int((vmin - minC)/period) + 1)*period; + } + if (minC > vmax + eps) { + dv = -(int((minC - vmax)/period) + 1)*period; + } + if (dv != 0) { + gp_Vec2d T1(0.,dv); + C2d->Translate(T1); + minC += dv; maxC += dv; + } + // Ajuste au mieux la courbe dans le domaine. + if (maxC > vmax +100*eps) { + Standard_Real d1 = maxC - vmax; + Standard_Real d2 = vmin - minC + period; + if (d2 < d1) dv =-period; + if ( dv != 0.) { + gp_Vec2d T2(0.,dv); + C2d->Translate(T2); + } + } + } +} + +//======================================================================= +//function : Inter3D +//purpose : +//======================================================================= + +void Partition_Inter3d::Inter3D(const TopoDS_Face& F1, + const TopoDS_Face& F2, + TopTools_ListOfShape& L) +{ + BRep_Builder B; + + // fill the data Structure + Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure(); + TopOpeBRep_DSFiller DSFiller; + DSFiller.Insert(F1,F2,DatStr); + + // define the GeomTool used by the DSFiller : + // compute BSpline of degree 1 on intersection curves. + Standard_Real tol3dAPPROX = 1e-7; + Standard_Real tol2dAPPROX = 1e-7; + TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX); + GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX); + TopOpeBRepDS_BuildTool BT(GT2); + + // Perform Section + TopOpeBRepBuild_Builder TopB(BT); + TopB.Perform(DatStr); + + // =============== + // Store new edges + // =============== + + L.Clear(); + TopOpeBRepDS_CurveExplorer cex(DatStr->DS()); + for (; cex.More(); cex.Next()) { + const TopOpeBRepDS_Curve& CDS = cex.Curve(); + Standard_Integer ic = cex.Index(); + Handle(Geom2d_Curve) pc1 = CDS.Curve1(); + Handle(Geom2d_Curve) pc2 = CDS.Curve2(); + + TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic); + while (itLE.More()) { + TopoDS_Edge E = TopoDS::Edge(itLE.Value()); + + PutInBounds (F1,E,pc1); + PutInBounds (F2,E,pc2); + + B.UpdateEdge (E,pc1,F1,0.); + B.UpdateEdge (E,pc2,F2,0.); + + L.Append (E); + + itLE.Next(); + if (itLE.More()) { + pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy()); + pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy()); + } + } + } + + // ======================== + // store same domain faces + // ======================== + + + if ( DatStr->HasSameDomain( F1 )) + { + TopTools_ListOfShape emptyList; + if (!mySameDomainFM.IsBound(F1)) + mySameDomainFM.Bind(F1,emptyList); + if (!mySameDomainFM.IsBound(F2)) + mySameDomainFM.Bind(F2,emptyList); + mySameDomainFM(F1).Append(F2); + mySameDomainFM(F2).Append(F1); + } + + // ==================== + // Store section edges + // ==================== + + const TopOpeBRepDS_DataStructure& DS = DatStr->DS(); + Standard_Integer j,i,nse = DS.NbSectionEdges(); + if (nse == 0) return; + + + TopoDS_Vertex V, sdeV1, sdeV2; + TopTools_MapOfShape MV; + TopTools_ListOfShape LSE; // list of section edges + TopoDS_Face dummyF; + + for (i = 1; i <= nse; i++) + { + const TopoDS_Edge & se = DS.SectionEdge(i); + if (! TopB.IsSplit(se,TopAbs_ON)) + continue; + LSE.Append( se ); + + // add vertices where section edges interferes with other + // edges as its descendant in myAsDes + + TopoDS_Edge sde, oe; // same domain, other edge + if (DatStr->HasSameDomain(se)) { + sde = TopoDS::Edge( DatStr->SameDomain(se).Value() ); + TopExp::Vertices( sde, sdeV1, sdeV2); + } + TColStd_MapOfInteger MIV; // indices of added edges + TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se )); + itP.SupportKind( TopOpeBRepDS_EDGE ); + // loop on intersections of se + for (; itP.More(); itP.Next()) { + oe = TopoDS::Edge( DS.Shape( itP.Support())); + if (itP.IsVertex()) { + // there is a vertex at intersection + if ( !MIV.Add( itP.Current() )) + continue; + V = TopoDS::Vertex( DS.Shape( itP.Current())); + if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) ) + oe = sde; + V = ReplaceSameDomainV( V , oe ); + V.Orientation( TopAbs_INTERNAL); + B.UpdateVertex( V, itP.Parameter(), se, 0.); // AddVonE() sets real U + } + else { + // create a new vertex at the intersection point + const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current()); + V = BRepLib_MakeVertex( DSP.Point() ); + V.Orientation( TopAbs_INTERNAL); + B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance()); + // make V be on the other edge + TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe )); + for (; itOP.More(); itOP.Next()) { + const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current()); + if ( DSP.IsEqual (ODSP)) { + B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance()); + break; + } + } + } + // add V on the both intersecting edges + TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes,dummyF); + if (!addedV.IsSame( V )) + mySameDomainVM.Bind (V, addedV); // equal vertex is already there + + MV.Add( addedV ); // to ease storage of vertices of ON splits + } + } + + // add section edge to the face it intersects and find + // splits ON that do not have same domain pair + + TopB.SplitSectionEdges(); // let TopB find ON splits + + TopTools_MapOfShape SPM; // map of ON splits + TopTools_IndexedMapOfShape ME[2]; + TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]); + TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]); + + TopTools_ListIteratorOfListOfShape itSP, itLSE (LSE); + while ( itLSE.More() ) { + + TopoDS_Edge se = TopoDS::Edge( itLSE.Value() ); + + // move itLSE to the next se + Standard_Integer ancRank = DS.AncestorRank(se); + if (ME[ancRank-1].Contains( se )) + { + LSE.Remove( itLSE ); // se is an edge of face it intersects + continue; + } + else + { + itLSE.Next(); + } + + const TopoDS_Face& F = (ancRank == 1) ? F2 : F1; + + // add se to face but dont add twice + TopTools_ListIteratorOfListOfShape itE( myAsDes->Descendant( F )); + if (myAsDes->HasDescendant( F )) { + for ( ; itE.More(); itE.Next()) + if (se.IsSame( itE.Value() )) + break; + } + if (!itE.More()) + { + myAsDes->Add( F, se ); + + // check se pcurve on F + Standard_Real tol, f,l, umin=1e100, umax=-1e100; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l); + if (pc.IsNull()) { + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) { + const TopoDS_Edge& E = TopoDS::Edge ( itSP.Value()); + BRep_Tool::Range(E, f, l); + umin = Min( umin, f); + umax = Max( umax, l); + } + Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l); + if (umin < umax) // sometimes umin == umax for closed edge + C3d = new Geom_TrimmedCurve( C3d, umin, umax); + pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol); + if (pc.IsNull()) { + MESSAGE (" CANT BUILD PCURVE "); + } + B.UpdateEdge( se, pc, F, tol); + } + } + + // to detect splits that do not have same domain pair + // ie which split a face into parts and not pass by its boundary + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) { + const TopoDS_Shape& SP = itSP.Value(); + if (!SPM.Add( SP )) + SPM.Remove( SP ); + } + } + + // store vertices of ON splits and bind section edges to faces + + for (itLSE.Initialize (LSE); itLSE.More(); itLSE.Next()) + { + const TopoDS_Shape& se = itLSE.Value(); + + Standard_Integer ancRank = DS.AncestorRank(se); + TopoDS_Face F = (ancRank == 1) ? F2 : F1; + + // add vertices of ON splits which have no same domain pair + Standard_Boolean added = Standard_False; + itSP.Initialize( TopB.Splits(se,TopAbs_ON) ); + for ( ; itSP.More(); itSP.Next()) + { + if (!SPM.Contains( itSP.Value() )) + continue; + + const TopoDS_Edge& S = TopoDS::Edge ( itSP.Value()); + + added = Standard_True; + mySectionEdgesAD->Add( F, se ); + + TopoDS_Vertex VS[2]; + TopExp::Vertices (S, VS[0], VS[1]); + for (j=0; j<2; ++j) + { + if (mySameDomainVM.IsBound( VS[j] )) + VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] )); + if ( !MV.Contains( VS[j] )) { + // find equal vertex on se - point interference + gp_Pnt P1 = BRep_Tool::Pnt( VS[j] ); + TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) ); + for (; itV.More(); itV.Next()) { + V = TopoDS::Vertex( itV.Value() ); + if ( V.IsSame( VS[j] )) + break; + gp_Pnt P2 = BRep_Tool::Pnt( V ); + if (P1.IsEqual( P2, Precision::Confusion())) { + mySameDomainVM.Bind (VS[j], V); + VS[j] = V; + break; + } + } + if (!itV.More()) // no interferences with edges + myAsDes->Add( se, VS[j]); + } + + // add ends of ON splits to F in order to detect later + // if a split is on face in IsSplitOn() + mySectionEdgesAD->Add( F, VS[j]); + } + // in the descendants of F, first go ends of an ON split and + // then a split itself + mySectionEdgesAD->Add( F, S ); + } + if (!added) + mySectionEdgesAD->Add( F, se ); + + myNewEdges.Add( se ); + } +} + +//======================================================================= +//function : FacesPartition +//purpose : +//======================================================================= + +void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1, + const TopoDS_Face& F2) + //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/) +{ + TopTools_ListOfShape LInt; + + Inter3D (F1,F2,LInt); + + StorePart3d (F1,F2,LInt); +} + +//======================================================================= +//function : SetDone +//purpose : +//======================================================================= + +void Partition_Inter3d::SetDone(const TopoDS_Face& F1, + const TopoDS_Face& F2) +{ + if (!myDone.IsBound(F1)) { + TopTools_ListOfShape emptyList; + myDone.Bind(F1,emptyList); + } + myDone(F1).Append(F2); + if (!myDone.IsBound(F2)) { + TopTools_ListOfShape emptyList; + myDone.Bind(F2,emptyList); + } + myDone(F2).Append(F1); +} + +//======================================================================= +//function : IsDone +//purpose : +//======================================================================= + +Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1, + const TopoDS_Face& F2) + + const +{ + if (myDone.IsBound(F1)) { + TopTools_ListIteratorOfListOfShape it (myDone(F1)); + for (; it.More(); it.Next()) { + if (it.Value().IsSame(F2)) return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : StorePart3d +//purpose : +//======================================================================= + +void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1, + const TopoDS_Face& F2, + const TopTools_ListOfShape& LInt) +{ + if (!LInt.IsEmpty()) { + myAsDes->Add( F1,LInt); + myAsDes->Add( F2,LInt); + + TopTools_ListIteratorOfListOfShape it(LInt); + for (; it.More(); it.Next()) { + + TopoDS_Edge E = TopoDS::Edge(it.Value()); + + BRep_Builder B; + B.SameParameter(E,Standard_False); + BRepLib::SameParameter(E,1.0e-7); + + myNewEdges.Add(E); + } + } + SetDone(F1,F2); +} + +//======================================================================= +//function : TouchedFaces +//purpose : +//======================================================================= + +TopTools_MapOfShape& Partition_Inter3d::TouchedFaces() +{ + return myTouched; +} + +//======================================================================= +//function : AsDes +//purpose : +//======================================================================= + +Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const +{ + return myAsDes; +} + +//======================================================================= +//function : NewEdges +//purpose : +//======================================================================= + +TopTools_MapOfShape& Partition_Inter3d::NewEdges() +{ + return myNewEdges; +} + +//======================================================================= +//function : Affiche +//purpose : +//======================================================================= + +void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const +{ +#ifdef DEB + char PSection[1024]; + char *section=PSection; + Standard_Integer i = 0; + Standard_Real j=1; + TopTools_ListOfShape aList; + TopTools_ListIteratorOfListOfShape it; + for (it.Initialize(SetOfFaces); it.More(); it.Next()) { + const TopoDS_Shape& OS = it.Value(); + aList=myAsDes->Descendant(OS); + MESSAGE ( " the number of items stored in the list " << j << " : " << aList.Extent() ) + j++; + TopTools_ListIteratorOfListOfShape itaList; + for (itaList.Initialize(aList); itaList.More(); itaList.Next()) { + const TopoDS_Shape& SS = itaList.Value(); + i++; + sprintf(PSection,"section_%d",i); + DBRep::Set(section,SS); + } + } +#endif +} + +//======================================================================= +//function : SameDomain +//purpose : +//======================================================================= + +const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const +{ + if (mySameDomainFM.IsBound( F )) + return mySameDomainFM (F); + + static TopTools_ListOfShape emptyList; + return emptyList; +} + +//======================================================================= +//function : HasSameDomainF +//purpose : Return true if F has same domain faces +//======================================================================= + +Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const +{ + return mySameDomainFM.IsBound( F ); +} + +//======================================================================= +//function : IsSameDomain +//purpose : Return true if F1 and F2 are same domain faces +//======================================================================= + +Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1, + const TopoDS_Shape& F2) const +{ + if (mySameDomainFM.IsBound( F1 )) { + TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 )); + for (; it.More(); it.Next()) + if (F2.IsSame( it.Value())) + return Standard_True; + } + return F1.IsSame( F2 ); +} + +//======================================================================= +//function : ReplaceSameDomainV +//purpose : return same domain vertex of V if it was replaced +// and make this vertex to be on E too, else return V +//======================================================================= + +TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V, + const TopoDS_Edge& E) const +{ + TopoDS_Vertex SDV = V; + if (mySameDomainVM.IsBound( V )) { + + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1); + + SDV = TopoDS::Vertex( mySameDomainVM(V) ); + Standard_Real tol = BRep_Tool::Tolerance( V ); + BRep_Builder B; + SDV.Orientation( V.Orientation()); + + if (isClosed) { + Standard_Real f, l; + BRep_Tool::Range (E, f, l); + Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f ); + B.UpdateVertex(SDV, (isFirst ? f : l), E, tol); + SDV.Reverse(); + B.UpdateVertex(SDV, (isFirst ? l : f), E, tol); + } + else + B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol); + + } + return SDV; +} + +//======================================================================= +//function : SectionEdgesAD +//purpose : +//======================================================================= + +Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const +{ + return mySectionEdgesAD; +} + +//======================================================================= +//function : IsSectionEdge +//purpose : return True if E is an edge of a face and it +// intersects an other face +//======================================================================= + +Standard_Boolean + Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const +{ + return mySectionEdgesAD->HasAscendant(E); +} + +//======================================================================= +//function : HasSectionEdge +//purpose : return True if an edge of F intersects an other +// face or F is intersected by edge of an other face +//======================================================================= + +Standard_Boolean + Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const +{ + return mySectionEdgesAD->HasDescendant(F); +} + +//======================================================================= +//function : IsSplitOn +//purpose : return True if NewE is split of OldE on F +//======================================================================= + +Standard_Boolean + Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE, + const TopoDS_Edge& OldE, + const TopoDS_Face& F) const +{ + if (! mySectionEdgesAD->HasDescendant(F)) + return Standard_False; + + TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) ); + for ( ; itE.More(); itE.Next()) { + if ( itE.Value().ShapeType() != TopAbs_EDGE || + ! OldE.IsSame ( itE.Value() )) + continue; + // an edge encountered, its vertices and a split come next + itE.Next(); + if (!itE.More()) break; + const TopoDS_Shape& V3 = itE.Value(); + if (V3.ShapeType() != TopAbs_VERTEX) continue; + itE.Next(); + if (!itE.More()) break; + const TopoDS_Shape& V4 = itE.Value(); + if (V4.ShapeType() != TopAbs_VERTEX) continue; + + TopoDS_Vertex V1, V2; + TopExp::Vertices( OldE, V1, V2); + + if ( V1.IsSame(V2) && + (V1.IsSame(V3) || V1.IsSame(V4)) ) { + // closed old edge; use the split for the test + itE.Next(); + if (!itE.More()) break; + const TopoDS_Edge& split = TopoDS::Edge( itE.Value() ); + // check distance at middle point of NewE + Standard_Real f1,l1, f2,l2; + Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1); + if (!PC1.IsNull()) { + Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2); + gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) ); + Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1); + if (proj.NbPoints() && + proj.LowerDistance() <= Precision::Confusion()) + return Standard_True; + } + else { + Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1); + Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE ,f2,l2); + gp_Pnt P = C2->Value( 0.5*(f2+l2) ); + GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1); + if (proj.NbPoints() && + proj.LowerDistance() <= Precision::Confusion()) + return Standard_True; + } + } + else { + Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE); + Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE); + + Standard_Real f,l, u; + BRep_Tool::Range( NewE, f,l); + u = 0.5*(f+l); + f = Min(u3,u4); + l = Max(u3,u4); + + if (u <= l && u >= f) + return Standard_True; + } + } + return Standard_False; +} + +//======================================================================= +//function : SectionEdgeFaces +//purpose : return faces cut by section edge +//======================================================================= + +const TopTools_ListOfShape& + Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const +{ + return mySectionEdgesAD->Ascendant( SecE ); +} + +#endif diff --git a/libsrc/occ/Partition_Inter3d.hxx b/libsrc/occ/Partition_Inter3d.hxx new file mode 100644 index 00000000..d8be2c59 --- /dev/null +++ b/libsrc/occ/Partition_Inter3d.hxx @@ -0,0 +1,143 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter3d.hxx +// Module : GEOM + +#ifndef _Partition_Inter3d_HeaderFile +#define _Partition_Inter3d_HeaderFile + +#ifndef _Handle_BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +class BRepAlgo_AsDes; +class TopTools_ListOfShape; +class TopTools_DataMapOfShapeShape; +class TopoDS_Face; +class TopTools_MapOfShape; +class TopoDS_Shape; +class TopoDS_Vertex; +class TopoDS_Edge; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Inter3d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // + Partition_Inter3d(); + Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes); + void CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,const TopTools_DataMapOfShapeShape& FaceShapeMap) ; + void FacesPartition(const TopoDS_Face& F1,const TopoDS_Face& F2) ; + Standard_Boolean IsDone(const TopoDS_Face& F1,const TopoDS_Face& F2) const; + TopTools_MapOfShape& TouchedFaces() ; + Handle_BRepAlgo_AsDes AsDes() const; + TopTools_MapOfShape& NewEdges() ; + Standard_Boolean HasSameDomainF(const TopoDS_Shape& F) const; + Standard_Boolean IsSameDomainF(const TopoDS_Shape& F1,const TopoDS_Shape& F2) const; + const TopTools_ListOfShape& SameDomain(const TopoDS_Face& F) const; + TopoDS_Vertex ReplaceSameDomainV(const TopoDS_Vertex& V,const TopoDS_Edge& E) const; + Handle_BRepAlgo_AsDes SectionEdgesAD() const; + Standard_Boolean IsSectionEdge(const TopoDS_Edge& E) const; + Standard_Boolean HasSectionEdge(const TopoDS_Face& F) const; + Standard_Boolean IsSplitOn(const TopoDS_Edge& NewE,const TopoDS_Edge& OldE,const TopoDS_Face& F) const; + const TopTools_ListOfShape& SectionEdgeFaces(const TopoDS_Edge& SecE) const; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + void Inter3D(const TopoDS_Face& F1,const TopoDS_Face& F2,TopTools_ListOfShape& LInt) ; + void StorePart3d(const TopoDS_Face& F1,const TopoDS_Face& F2,const TopTools_ListOfShape& LInt1) ; + void SetDone(const TopoDS_Face& F1,const TopoDS_Face& F2) ; + void Affiche(const TopTools_ListOfShape& SetOfFaces) const; + + + // Fields PRIVATE + // + Handle_BRepAlgo_AsDes myAsDes; + TopTools_DataMapOfShapeListOfShape myDone; + TopTools_MapOfShape myTouched; + TopTools_MapOfShape myNewEdges; + Handle_BRepAlgo_AsDes mySectionEdgesAD; + TopTools_DataMapOfShapeListOfShape mySameDomainFM; + TopTools_DataMapOfShapeShape mySameDomainVM; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/libsrc/occ/Partition_Inter3d.ixx b/libsrc/occ/Partition_Inter3d.ixx new file mode 100644 index 00000000..0775cc99 --- /dev/null +++ b/libsrc/occ/Partition_Inter3d.ixx @@ -0,0 +1,31 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter3d.ixx +// Module : GEOM + +#include "Partition_Inter3d.jxx" + + + + diff --git a/libsrc/occ/Partition_Inter3d.jxx b/libsrc/occ/Partition_Inter3d.jxx new file mode 100644 index 00000000..5804ba81 --- /dev/null +++ b/libsrc/occ/Partition_Inter3d.jxx @@ -0,0 +1,53 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Inter3d.jxx +// Module : GEOM + +#ifndef _BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Shape_HeaderFile +#include +#endif +#ifndef _TopoDS_Vertex_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _Partition_Inter3d_HeaderFile +#include "Partition_Inter3d.hxx" +#endif diff --git a/libsrc/occ/Partition_Loop.cxx b/libsrc/occ/Partition_Loop.cxx new file mode 100644 index 00000000..49b72f5a --- /dev/null +++ b/libsrc/occ/Partition_Loop.cxx @@ -0,0 +1,473 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Loop.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Loop.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include +#include + +#include "Partition_Loop.ixx" + +#include "utilities.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static char* name = new char[100]; +static int nbe = 0; + +//======================================================================= +//function : Partition_Loop +//purpose : +//======================================================================= +Partition_Loop::Partition_Loop() +{ +} + +//======================================================================= +//function : Init +//purpose : +//======================================================================= +void Partition_Loop::Init(const TopoDS_Face& F) +{ + myConstEdges.Clear(); + myNewWires .Clear(); + myNewFaces .Clear(); + myFace = F; +} + +//======================================================================= +//function : AddConstEdge +//purpose : +//======================================================================= +void Partition_Loop::AddConstEdge (const TopoDS_Edge& E) +{ + myConstEdges.Append(E); +} + + +//======================================================================= +//function : FindDelta +//purpose : +//======================================================================= +static Standard_Real FindDelta(TopTools_ListOfShape& LE, + const TopoDS_Face& F) +{ + Standard_Real dist, f, l; + Standard_Real d = Precision::Infinite(); + TopTools_ListIteratorOfListOfShape itl; + + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,f,l); + gp_Pnt2d p = C->Value(f); + gp_Pnt2d pp = C->Value(l); + Standard_Real d1 = p.Distance(pp); + if (d1 connected by the vertex in the list . +// Is erased of the list. If is too in the list +// with the same orientation, it's erased of the list +//======================================================================= +static Standard_Boolean SelectEdge(const TopoDS_Face& F, + const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + TopTools_ListOfShape& LE) +{ + TopTools_ListIteratorOfListOfShape itl; + NE.Nullify(); + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + LE.Remove(itl); + break; + } + } + + if (LE.Extent() > 1) { + //-------------------------------------------------------------- + // Several possible edges. + // - Test the edges differents of CE + //-------------------------------------------------------------- + Standard_Real cf, cl, f, l; + TopoDS_Face FForward = F; + Handle(Geom2d_Curve) Cc, C; + FForward.Orientation(TopAbs_FORWARD); + + Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl); + Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV); + Standard_Real uc,u; + if (CE.Orientation () == TopAbs_FORWARD) uc = cl; + else uc = cf; + + gp_Pnt2d P2,PV = Cc->Value(uc); + + Standard_Real delta = FindDelta(LE,FForward); + + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (!E.IsSame(CE)) { + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + if (E.Orientation () == TopAbs_FORWARD) u = f; + else u = l; + P2 = C->Value(u); + dist = PV.Distance(P2); + if (dist <= distmin){ + distmin = dist; + } + + } + } + + Standard_Real anglemax = - M_PI; + TopoDS_Edge SelectedEdge; + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (!E.IsSame(CE)) { + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + if (E.Orientation () == TopAbs_FORWARD) u = f; + else u = l; + P2 = C->Value(u); + dist = PV.Distance(P2); + if (dist <= distmin + (1./3)*delta){ + gp_Pnt2d PC, P; + gp_Vec2d CTg1, CTg2, Tg1, Tg2; + Cc->D2(uc, PC, CTg1, CTg2); + C->D2(u, P, Tg1, Tg2); + + Standard_Real angle; + + if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) { + angle = CTg1.Angle(Tg1.Reversed()); + } + else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) { + angle = (CTg1.Reversed()).Angle(Tg1); + } + else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) { + angle = CTg1.Angle(Tg1); + } + else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) { + angle = (CTg1.Reversed()).Angle(Tg1.Reversed()); + } + if (angle >= anglemax) { + anglemax = angle ; + SelectedEdge = E; + } + } + } + } + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (E.IsEqual(SelectedEdge)) { + NE = TopoDS::Edge(E); + LE.Remove(itl); + break; + } + } + } + else if (LE.Extent() == 1) { + NE = TopoDS::Edge(LE.First()); + LE.RemoveFirst(); + } + else { + return Standard_False; + } + return Standard_True; +} + +//======================================================================= +//function : SamePnt2d +//purpose : +//======================================================================= +static Standard_Boolean SamePnt2d(TopoDS_Vertex V, + TopoDS_Edge& E1, + TopoDS_Edge& E2, + TopoDS_Face& F) +{ + Standard_Real f1,f2,l1,l2; + gp_Pnt2d P1,P2; + TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD); + TopoDS_Face FF = TopoDS::Face(aLocalF); + Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1); + Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2); + if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1); + else P1 = C1->Value(l1); + + if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2); + else P2 = C2->Value(f2); + Standard_Real Tol = 100*BRep_Tool::Tolerance(V); + Standard_Real Dist = P1.Distance(P2); + return Dist < Tol; +} + +//======================================================================= +//function : PurgeNewEdges +//purpose : +//======================================================================= +static void PurgeNewEdges(TopTools_ListOfShape& ConstEdges, + const TopTools_MapOfOrientedShape& UsedEdges) +{ + TopTools_ListIteratorOfListOfShape it(ConstEdges); + while ( it.More()) { + const TopoDS_Shape& NE = it.Value(); + if (!UsedEdges.Contains(NE)) { + ConstEdges.Remove(it); + } + else { + it.Next(); + } + } +} + +//======================================================================= +//function : StoreInMVE +//purpose : +//======================================================================= +static void StoreInMVE (const TopoDS_Face& F, + TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE ) + +{ + TopoDS_Vertex V1, V2; + TopTools_ListOfShape Empty; + + TopExp::Vertices(E,V1,V2); + if (!MVE.IsBound(V1)) { + MVE.Bind(V1,Empty); + } + MVE(V1).Append(E); + + if (!MVE.IsBound(V2)) { + MVE.Bind(V2,Empty); + } + MVE(V2).Append(E); +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void Partition_Loop::Perform() +{ + + TopTools_DataMapOfShapeListOfShape MVE; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit, Mapit1; + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + + //----------------------------------- + // Construction map vertex => edges + //----------------------------------- + for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { + TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + StoreInMVE(myFace,E,MVE); + } + + //---------------------------------------------- + // Construction of all the wires and of all the new faces. + //---------------------------------------------- + TopTools_MapOfOrientedShape UsedEdges; + + while (!MVE.IsEmpty()) { + TopoDS_Vertex VF,CV; + TopoDS_Edge CE,NE,EF; + TopoDS_Wire NW; + BRep_Builder B; + Standard_Boolean End= Standard_False; + + B.MakeWire(NW); + //-------------------------------- + // EF first edge. + //-------------------------------- + Mapit.Initialize(MVE); + EF = CE = TopoDS::Edge(Mapit.Value().First()); + + TopExp::Vertices(CE,V1,V2); + //-------------------------------- + // VF first vertex + //-------------------------------- + if (CE.Orientation() == TopAbs_FORWARD) { + CV = VF = V1; + } + else { + CV = VF = V2; + } + if (!MVE.IsBound(CV)) continue; + for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + MVE(CV).Remove(itl); + break; + } + } + + int i = 0; + while (!End) { + //------------------------------- + // Construction of a wire. + //------------------------------- + TopExp::Vertices(CE,V1,V2); + if (!CV.IsSame(V1)) CV = V1; else CV = V2; + B.Add (NW,CE); + UsedEdges.Add(CE); + + //-------------- + // stop test + //-------------- + if (!MVE.IsBound(CV) || MVE(CV).IsEmpty() || CV.IsSame(VF) ) { + if (CV.IsSame(VF)) { + if (MVE(CV).Extent() == 1 ) MVE.UnBind(CV); + else { + for ( itl.Initialize(MVE(CV)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(CE)) { + MVE(CV).Remove(itl); + break; + } + } + } + } + End=Standard_True; + } + + //-------------- + // select edge + //-------------- + else { + Standard_Boolean find = SelectEdge(myFace,CE,CV,NE,MVE(CV)); + if (find) { + CE=NE; + if (MVE(CV).IsEmpty()) MVE.UnBind(CV); + if (CE.IsNull() ) { + MESSAGE ( " CE is NULL !!! " ) + End=Standard_True; + } + } + else { + MESSAGE ( " edge doesn't exist " ) + End=Standard_True; + } + } + } + + //----------------------------- + // Test if the wire is closed + //----------------------------- + if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) { + } + else{ + MESSAGE ( "wire not closed" ) + } + myNewWires.Append (NW); + } + + PurgeNewEdges(myConstEdges,UsedEdges); + +} + + +//======================================================================= +//function : NewWires +//purpose : +//======================================================================= +const TopTools_ListOfShape& Partition_Loop::NewWires() const +{ + return myNewWires; +} + +//======================================================================= +//function : NewFaces +//purpose : +//======================================================================= +const TopTools_ListOfShape& Partition_Loop::NewFaces() const +{ + return myNewFaces; +} + +//======================================================================= +//function : WiresToFaces +//purpose : +//======================================================================= +void Partition_Loop::WiresToFaces() +{ + if (!myNewWires.IsEmpty()) { + BRepAlgo_FaceRestrictor FR; + + TopAbs_Orientation OriF = myFace.Orientation(); + TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD); + + FR.Init (TopoDS::Face(aLocalS),Standard_False); + TopTools_ListIteratorOfListOfShape it(myNewWires); + for (; it.More(); it.Next()) { + FR.Add(TopoDS::Wire(it.Value())); + } + + FR.Perform(); + + if (FR.IsDone()) { + for (; FR.More(); FR.Next()) { + myNewFaces.Append(FR.Current().Oriented(OriF)); + } + } + } +} + + +#endif diff --git a/libsrc/occ/Partition_Loop.hxx b/libsrc/occ/Partition_Loop.hxx new file mode 100644 index 00000000..56e05e26 --- /dev/null +++ b/libsrc/occ/Partition_Loop.hxx @@ -0,0 +1,118 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Loop.hxx +// Module : GEOM + +#ifndef _Partition_Loop_HeaderFile +#define _Partition_Loop_HeaderFile + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeListOfShape_HeaderFile +#include +#endif +class TopoDS_Face; +class TopoDS_Edge; +class TopTools_ListOfShape; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Loop { + +public: + + inline void* operator new(size_t,void* anAddress) + { + return anAddress; + } + inline void* operator new(size_t size) + { + return Standard::Allocate(size); + } + inline void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // inline void operator delete(void *anAddress, size_t size) + // { + // if (anAddress) Standard::Free((Standard_Address&)anAddress,size); + // } + // Methods PUBLIC + // + Partition_Loop(); + void Init(const TopoDS_Face& F) ; + void AddConstEdge(const TopoDS_Edge& E) ; + void Perform() ; + const TopTools_ListOfShape& NewWires() const; + void WiresToFaces() ; + const TopTools_ListOfShape& NewFaces() const; + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // + TopoDS_Face myFace; + TopTools_ListOfShape myConstEdges; + TopTools_ListOfShape myNewWires; + TopTools_ListOfShape myNewFaces; + + +}; + + + + + +// other inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/libsrc/occ/Partition_Loop.ixx b/libsrc/occ/Partition_Loop.ixx new file mode 100644 index 00000000..1c40e725 --- /dev/null +++ b/libsrc/occ/Partition_Loop.ixx @@ -0,0 +1,31 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Loop.ixx +// Module : GEOM + +#include "Partition_Loop.jxx" + + + + diff --git a/libsrc/occ/Partition_Loop.jxx b/libsrc/occ/Partition_Loop.jxx new file mode 100644 index 00000000..dd86f05c --- /dev/null +++ b/libsrc/occ/Partition_Loop.jxx @@ -0,0 +1,41 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Loop.jxx +// Module : GEOM + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _Partition_Loop_HeaderFile +#include "Partition_Loop.hxx" +#endif diff --git a/libsrc/occ/Partition_Loop2d.cxx b/libsrc/occ/Partition_Loop2d.cxx new file mode 100644 index 00000000..d980a5cb --- /dev/null +++ b/libsrc/occ/Partition_Loop2d.cxx @@ -0,0 +1,1145 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R& D +// +// +// +// File : Partition_Loop2d.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Loop2d.cxx,v 1.6 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include +#include "Partition_Loop2d.ixx" + +#include "utilities.h" +#include + +#include +#include +#include +#include +// #include // V6.3 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // V6.5 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Loop2d +//purpose : +//======================================================================= + +Partition_Loop2d::Partition_Loop2d() +{ +} + +//======================================================================= +//function : Init +//purpose : Init with the set of edges must have +// pcurves on . +//======================================================================= + +void Partition_Loop2d::Init(const TopoDS_Face& F) +{ + myConstEdges.Clear(); + myNewWires .Clear(); + myNewFaces .Clear(); + myFace = F; + myFaceOri = myFace.Orientation(); + myFace.Orientation( TopAbs_FORWARD ); +} + +//======================================================================= +//function : AddConstEdge +//purpose : Add as unique edge in the result. +//======================================================================= + +void Partition_Loop2d::AddConstEdge (const TopoDS_Edge& E) +{ +#ifdef DEB + Standard_Real f,l; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + if (pc.IsNull()) { + INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE"); + } else +#endif + { + myConstEdges.Append(E); + } +} + +void Partition_Loop2d::AddSectionEdge (const TopoDS_Edge& E) +{ +#ifdef DEB + Standard_Real f,l; + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + if (pc.IsNull()) + pc = BRep_Tool::CurveOnSurface( E, myFace, f,l); + gp_Vec2d Tg1; + gp_Pnt2d PC; + pc->D1(0.5*(f+l), PC, Tg1); + if (Tg1.Magnitude() <= gp::Resolution()) { + MESSAGE (""); + } + if (pc.IsNull()) { + INFOS( "AddConstEdge(): EDGE W/O PCURVE on FACE"); + } else +#endif + { + myConstEdges.Append(E); + myConstEdges.Append(E.Reversed()); + mySectionEdges.Add( E ); + } +} + +//======================================================================= +//function : preciseU +//purpose : find u such that the 3D point on theE is just out of tolerance +// of theV +//======================================================================= + +static Standard_Real preciseU (const BRepAdaptor_Surface& theSurf, + const TopoDS_Edge& theE, + const TopoDS_Vertex& theV, + const Handle(Geom2d_Curve)& theC, + const Standard_Boolean theFirstEnd) +{ + Standard_Boolean isForward = ( theE.Orientation () == TopAbs_FORWARD ); + if (theFirstEnd) isForward = !isForward; + + // find the first point in 2d and 3d + Standard_Real f,l; + BRep_Tool::Range( theE, f, l ); + Standard_Real u0 = isForward ? l : f; + gp_Pnt2d aP2d0 = theC->Value( u0 ); + gp_Pnt aPnt0 = theSurf.Value( aP2d0.X(), aP2d0.Y() ); + + // shift in 2d and 3d + Standard_Real du = ( l - f ) / 100, du3d = 0; + if (isForward) + du = -du; + + // target parameter + Standard_Real u; + + while (du3d < ::RealSmall()) + { + // u for test + u = u0 + du; + du *= 10; // for the next iteration: increase du untill du3d is large enough + + // find out how u is far from u0 in 3D + gp_Pnt2d aP2d = theC->Value( u ); + gp_Pnt aPnt = theSurf.Value( aP2d.X(), aP2d.Y() ); + du3d = aPnt0.Distance( aPnt ); + } + + // find u such that the 3D point is just out of tolerance of theV + Standard_Real tolV = BRep_Tool::Tolerance( theV ) + Precision::Confusion(); + u = u0 + du * tolV / du3d; + + // check that u is within the range + if ( isForward ? (u < f) : (u > l) ) + u = u0 + du; + + return u; +} + +//======================================================================= +//function : SelectEdge +//purpose : Find in the list the edge connected with by +// the vertex . +// is removed from the list. If is in +// with the same orientation, it's removed from the list +//======================================================================= + +static Standard_Boolean SelectEdge(const BRepAdaptor_Surface& Surf, + const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + const TopTools_ListOfShape& LE) +{ + NE.Nullify(); + + if (LE.Extent() > 1) { + //-------------------------------------------------------------- + // Several possible edges. + // - Test the edges differents of CE + //-------------------------------------------------------------- + TopoDS_Face FForward = Surf.Face(); + TopoDS_Edge aPrevNE; + + gp_Vec2d CTg1, Tg1, CTg2, Tg2; + gp_Pnt2d PC, P; + + Standard_Real f, l; + Handle(Geom2d_Curve) Cc, C; + Cc = BRep_Tool::CurveOnSurface(CE,FForward,f,l); + + Standard_Boolean isForward = ( CE.Orientation () == TopAbs_FORWARD ); + Standard_Real uc, u, du = Precision::PConfusion(); + uc = isForward ? ( l - du ) : ( f + du ); + Cc->D1(uc, PC, CTg1); + if (!isForward) CTg1.Reverse(); + + Standard_Real anglemin = 3 * PI, tolAng = 1.e-8; + + // select an edge whose first derivative is most left of CTg1 + // ie an angle between Tg1 and CTg1 is least + TopTools_ListIteratorOfListOfShape itl; + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if (E.IsSame(CE)) + continue; + if (! CV.IsSame( TopExp::FirstVertex( E, Standard_True ))) + continue; + + isForward = ( E.Orientation () == TopAbs_FORWARD ); + + // get E curve + C = BRep_Tool::CurveOnSurface(E,FForward,f,l); + // get the first derivative Tg1 + u = isForward ? ( f + du ) : ( l - du ); + C->D1(u, P, Tg1); + if (!isForward) Tg1.Reverse(); + + // -PI < angle < PI + Standard_Real angle = Tg1.Angle(CTg1); + + if (PI - Abs(angle) <= tolAng) + { + // an angle is too close to PI; assure that an angle sign really + // reflects an edge position: +PI - an edge is worst, + // -PI - an edge is best. + u = preciseU( Surf, CE, CV, Cc, Standard_False); + gp_Vec2d CTg; + Cc->D1(u, PC, CTg); + if (CE.Orientation() == TopAbs_REVERSED) CTg.Reverse(); + + u = preciseU( Surf, E, CV, C, Standard_True); + C->D1(u, P, Tg1); + if (!isForward) Tg1.Reverse(); + + angle = Tg1.Angle(CTg); + } + + Standard_Boolean isClose = ( Abs( angle - anglemin ) <= tolAng ); + if (angle <= anglemin) { + if (isClose) + aPrevNE = NE; + else + aPrevNE.Nullify(); + anglemin = angle ; + NE = E; + } + else + if (isClose) + aPrevNE = E; + + } + if (!aPrevNE.IsNull()) { + // select one of close edges, the most left one. + Cc = BRep_Tool::CurveOnSurface( NE, FForward, f, l ); + uc = preciseU( Surf, NE, CV, Cc, Standard_True); + Cc->D1(uc, PC, CTg1); + if (NE.Orientation() != TopAbs_FORWARD) CTg1.Reverse(); + + u = preciseU( Surf, aPrevNE, CV, C, Standard_True); + C->D1(u, P, Tg1); + if (aPrevNE.Orientation() != TopAbs_FORWARD) Tg1.Reverse(); + + if ( Tg1.Angle(CTg1) < 0) + NE = aPrevNE; + } + } + else if (LE.Extent() == 1) { + NE = TopoDS::Edge(LE.First()); + } + else { + return Standard_False; + } + return !NE.IsNull(); +} + +//======================================================================= +//function : SamePnt2d +//purpose : +//======================================================================= + +static Standard_Boolean SamePnt2d(const TopoDS_Vertex& V1, + const TopoDS_Edge& E1, + const TopoDS_Vertex& V2, + const TopoDS_Edge& E2, + const TopoDS_Face& F) +{ + Standard_Real f1,f2,l1,l2; + Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,F,f1,l1); + Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,F,f2,l2); + + gp_Pnt2d P1 = C1->Value( BRep_Tool::Parameter(V1,E1)); + gp_Pnt2d P2 = C2->Value( BRep_Tool::Parameter(V2,E2)); + + Standard_Real Tol = 100 * BRep_Tool::Tolerance(V1); + Standard_Real Dist = P1.Distance(P2); + return Dist < Tol; +} + + +//======================================================================= +//function : StoreInMVE +//purpose : +//======================================================================= + +static void StoreInMVE (const TopoDS_Face& /*F*/, + TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE ) + +{ + TopoDS_Vertex V1, V2; + TopTools_ListOfShape Empty; + + TopExp::Vertices(E,V1,V2); + if (!MVE.IsBound(V1)) { + MVE.Bind(V1,Empty); + } + MVE(V1).Append(E); + + if (!MVE.IsBound(V2)) { + MVE.Bind(V2,Empty); + } + MVE(V2).Append(E); +} + +//======================================================================= +//function : RemoveFromMVE +//purpose : +//======================================================================= + +static void RemoveFromMVE(const TopoDS_Edge& E, + TopTools_DataMapOfShapeListOfShape& MVE) +{ + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + TopExp::Vertices (E,V1,V2); + if (MVE.IsBound(V1)) + for ( itl.Initialize(MVE(V1)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(E)) { + MVE(V1).Remove(itl); + break; + } + } + if (MVE.IsBound(V2)) + for ( itl.Initialize(MVE(V2)); itl.More(); itl.Next()) { + if (itl.Value().IsEqual(E)) { + MVE(V2).Remove(itl); + break; + } + } +} +//======================================================================= +//function : addConnected +//purpose : add to all edges reachable from +//======================================================================= + +static void addConnected(const TopoDS_Shape& E, + TopTools_MapOfShape& EM, + TopTools_MapOfShape& VM, + const TopTools_DataMapOfShapeListOfShape& MVE) +{ + // Loop on vertices of E + TopoDS_Iterator itV ( E ); + for ( ; itV.More(); itV.Next()) { + + if ( ! VM.Add ( itV.Value() )) continue; + + // Loop on edges sharing V + TopTools_ListIteratorOfListOfShape itE( MVE( itV.Value() ) ); + for (; itE.More(); itE.Next()) { + if ( EM.Add( itE.Value() )) + addConnected ( itE.Value(), EM, VM, MVE ); + } + } +} +//======================================================================= +//function : canPassToOld +//purpose : +//======================================================================= + +// static Standard_Boolean canPassToOld (const TopoDS_Shape& V, +// TopTools_MapOfShape& UsedShapesMap, +// const TopTools_DataMapOfShapeListOfShape& MVE, +// const TopTools_MapOfShape& SectionEdgesMap) +// { +// TopTools_ListIteratorOfListOfShape itE( MVE(V) ); +// // Loop on edges sharing V +// for (; itE.More(); itE.Next()) { +// if ( !UsedShapesMap.Add( itE.Value() )) +// continue; // already checked + +// if ( !SectionEdgesMap.Contains( itE.Value() )) +// return Standard_True; // WE PASSED + +// TopoDS_Iterator itV( itE.Value() ); +// // Loop on vertices of an edge +// for (; itV.More(); itV.Next()) { +// if ( !UsedShapesMap.Add( itV.Value() )) +// continue; // already checked +// else +// return canPassToOld( itV.Value(), UsedShapesMap, MVE, SectionEdgesMap); +// } +// } +// return Standard_False; +// } + +//======================================================================= +//function : MakeDegenAndSelect +//purpose : Find parameter of intersection of with and +// select an edge with its parameter closest to found one. +// Return new degenerated edge trimming by found parameters +//======================================================================= + +static TopoDS_Edge MakeDegenAndSelect(const TopoDS_Edge& CE, + const TopoDS_Vertex& CV, + TopoDS_Edge& NE, + TopTools_SequenceOfShape& EdgesSeq, + TColStd_SequenceOfReal& USeq, + const TopoDS_Edge& DE) +{ + if (EdgesSeq.Length() < 3) { + if (CE == EdgesSeq.First()) + NE = TopoDS::Edge( EdgesSeq.Last() ); + else + NE = TopoDS::Edge( EdgesSeq.First() ); + return DE; + } + + // find parameter on DE where it intersects CE + + Standard_Real U1; + Standard_Integer i, nb = EdgesSeq.Length(); + for (i=1; i<= nb; ++i) { + if (CE == EdgesSeq(i)) { + U1 = USeq(i); + break; + } + } + + // select NE with param closest to U1 thus finding U2 for a new degen edge + + Standard_Real U2, dU, dUmin = 1.e100; + Standard_Boolean isReversed = ( DE.Orientation() == TopAbs_REVERSED ); + for (i=1; i<= nb; ++i) { + dU = USeq(i) - U1; + if (isReversed ? (dU > 0) : (dU < 0)) + continue; + dU = Abs( dU ); + if ( dU > dUmin || IsEqual( dU, 0.)) + continue; + const TopoDS_Edge& E = TopoDS::Edge ( EdgesSeq(i) ); + if ( ! CV.IsSame( TopExp::FirstVertex( E , Standard_True ))) + continue; + NE = E; + dUmin = dU + Epsilon(dU); + U2 = USeq(i); + } + + // make a new degenerated edge + TopoDS_Edge NewDegen = TopoDS::Edge ( DE.EmptyCopied() ); + + Standard_Real Tol = BRep_Tool::Tolerance( CV ); + TopoDS_Vertex V = CV; + + BRep_Builder B; + V.Orientation( NewDegen.Orientation() ); + B.UpdateVertex( V, U1, NewDegen, Tol); + B.Add ( NewDegen , V ); + + V.Reverse(); + B.UpdateVertex( V, U2, NewDegen, Tol); + B.Add ( NewDegen , V ); + + return NewDegen; +} + +//======================================================================= +//function : prepareDegen +//purpose : Intersect with edges bound to its vertex in +// and store intersection parameter on in +// as well as the edges them-self in . +// Bind to vertex of in +//======================================================================= + +static void prepareDegen (const TopoDS_Edge& DegEdge, + const TopoDS_Face& F, + const TopTools_DataMapOfShapeListOfShape& MVE, + TopTools_SequenceOfShape& EdgesSeq, + TColStd_SequenceOfReal& USeq, + TopTools_DataMapOfShapeInteger& MVDEI, + const Standard_Integer DegEdgeIndex) +{ + const TopoDS_Vertex& V = TopExp::FirstVertex ( DegEdge ); + MVDEI.Bind ( V, DegEdgeIndex ); + + const TopTools_ListOfShape& EdgesList = MVE ( V ); + // if only 2 edges come to degenerated one, no pb in selection and + // no need to intersect them, just simulate asked data + Standard_Boolean doIntersect = ( EdgesList.Extent() > 2 ); + + BRepAdaptor_Curve2d DC, C; + Geom2dInt_GInter InterCC; + Standard_Real Tol = Precision::PConfusion(); + if ( doIntersect ) + DC.Initialize( DegEdge, F ); + + // avoid intersecting twice the same edge + // BRepOffset_DataMapOfShapeReal EUMap ( EdgesList.Extent() ); // V6.3 + TopTools_DataMapOfShapeReal EUMap ( EdgesList.Extent() ); // V6.5 + + Standard_Real U, f, l; + BRep_Tool::Range (DegEdge, f, l); + + TopTools_ListIteratorOfListOfShape itE (EdgesList); + for (; itE.More(); itE.Next()) { + + const TopoDS_Edge& E = TopoDS::Edge ( itE.Value() ); + + if ( !doIntersect) { + U = 0.; // it won't be used + } + else if ( BRep_Tool::IsClosed( E, F )) { + // seam edge: select U among f and l + Standard_Boolean first = Standard_True; + if ( V.IsSame ( TopExp::FirstVertex( E, Standard_True ) )) + first = Standard_False; + if ( DegEdge.Orientation() == TopAbs_REVERSED ) + first = !first; + U = first ? f : l; + } + else if ( EUMap.IsBound( E ) ) { + // same edge already bound + U = EUMap( E ); + } + else { + // intersect 2d curves + C.Initialize( E, F ); + InterCC.Perform ( DC, C , Tol, Tol ); + if (! InterCC.IsDone() || InterCC.NbPoints() == 0) { + MESSAGE ( "NO 2d INTERSECTION ON DEGENERATED EDGE" ); + continue; + } + // hope there is only one point of intersection + U = InterCC.Point( 1 ).ParamOnFirst(); + } + USeq.Append ( U ); + EdgesSeq.Append ( E ); + } +} +//======================================================================= +//function : Perform +//purpose : Make loops. +//======================================================================= + +void Partition_Loop2d::Perform() +{ + + Standard_Integer NbConstEdges = myConstEdges.Extent(); + TopTools_DataMapOfShapeListOfShape MVE(NbConstEdges) , MVE2(NbConstEdges); + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit; + TopTools_ListIteratorOfListOfShape itl; + TopoDS_Vertex V1,V2; + BRepAdaptor_Surface Surface ( myFace, Standard_False ); + + // degenerated edges and parameters of their 2d intersection with other edges + TopoDS_Edge DE [2]; + TopTools_SequenceOfShape SEID [2]; // seq of edges intersecting degenerated + TColStd_SequenceOfReal SeqU [2]; // n-th U corresponds to n-th edge in SEID + TopTools_DataMapOfShapeInteger MVDEI(2); // map vertex - degenerated edge index + Standard_Integer iDeg = 0; // index of degenerated edge [0,1] + + //--------------------------------------------------------- + // Construction map vertex => edges, find degenerated edges + //--------------------------------------------------------- + for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { + TopoDS_Edge& E = TopoDS::Edge(itl.Value()); + if ( BRep_Tool::Degenerated( E )) { + if (DE[0].IsNull()) DE[0] = E; + else DE[1] = E; + } + else + StoreInMVE(myFace,E,MVE); + } + + // fill data for degenerated edges + if ( ! DE[0].IsNull() ) + prepareDegen ( DE[0], myFace, MVE, SEID[0], SeqU[0], MVDEI, 0); + if ( ! DE[1].IsNull() ) + prepareDegen ( DE[1], myFace, MVE, SEID[1], SeqU[1], MVDEI, 1); + + + // to detect internal wires + Standard_Boolean isInternCW = 0; + MVE2 = MVE; + + + //------------------------------ + // Construction of all the wires + //------------------------------ + // first, we collect wire edges in WEL list looking for same edges that + // will be then removed possibly exploding a wire into parts; + // second, build wire(s) + + while (!MVE.IsEmpty()) { + + TopoDS_Vertex VF,CV; + TopoDS_Edge CE,NE,EF; + TopoDS_Wire NW; + BRep_Builder B; + Standard_Boolean End = Standard_False; + TopTools_ListOfShape WEL; + + Mapit.Initialize(MVE); + if (Mapit.Value().IsEmpty()) { + MVE.UnBind(Mapit.Key()); + continue; + } + + // EF first edge. + EF = CE = TopoDS::Edge(Mapit.Value().First()); + // VF first vertex + VF = TopExp::FirstVertex( CE, Standard_True); + + isInternCW = Standard_True; + + TopTools_MapOfShape addedEM (NbConstEdges); // map of edges added to WEL + TopTools_MapOfShape doubleEM (NbConstEdges); // edges encountered twice in WEL + + //------------------------------- + // Construction of a wire. + //------------------------------- + while (!End) { + + // only a seam is allowed twice in a wire, the others should be removed + if (addedEM.Add ( CE ) || BRep_Tool::IsClosed( CE, myFace ) ) + WEL.Append( CE ); + else { + doubleEM.Add( CE ); + RemoveFromMVE (CE,MVE2); + TopoDS_Edge CERev = CE; + CERev.Reverse(); + RemoveFromMVE (CERev,MVE2); + } + + RemoveFromMVE (CE,MVE); + + CV = TopExp::LastVertex( CE, Standard_True); + + if (isInternCW && !mySectionEdges.Contains(CE)) + // wire is internal if all edges are section ones + isInternCW = Standard_False; + + if (MVDEI.IsBound( CV )) { // CE comes to the degeneration + iDeg = MVDEI( CV ); + TopoDS_Edge NewDegen; + NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]); + WEL.Append( NewDegen ); + CE = NE; + End = CV.IsSame( VF ); + continue; + } + + //-------------- + // stop test + //-------------- + if (MVE(CV).IsEmpty()) { + End=Standard_True; + MVE.UnBind(CV); + } + else if (CV.IsSame(VF) && SamePnt2d(CV,CE, VF,EF, myFace) ) { + End = Standard_True; + } + else { + //---------------------------- + // select new current edge + //---------------------------- + if (! SelectEdge (Surface,CE,CV,NE,MVE(CV))) { + MESSAGE ( " NOT CLOSED WIRE " ); + End=Standard_True; + } + else + CE = NE; + } + } // while ( !End ) + + + // WEL is built, built wire(s) + + + itl.Initialize( WEL ); + if ( doubleEM.IsEmpty()) { // no double edges + B.MakeWire( NW ); + for (; itl.More(); itl.Next()) + B.Add ( NW, itl.Value()); + if (isInternCW) myInternalWL.Append(NW); + else myNewWires.Append (NW); + } + + else { + // remove double and degenerated edges from WEL + while (itl.More()) { + const TopoDS_Edge& E = TopoDS::Edge ( itl.Value() ); + if ( doubleEM.Contains( E ) || BRep_Tool::Degenerated( E )) + WEL.Remove( itl ); + else + itl.Next(); + } + if ( WEL.IsEmpty()) + continue; + // remove double edges from SEID and SeqU + Standard_Integer i,j; + for (j=0; j<2; ++j) { + for (i=1; i<=SEID[j].Length(); ++i) { + if (doubleEM.Contains( SEID[j].Value(i))) { + SEID[j].Remove( i ); + SeqU[j].Remove( i-- ); + } + } + } + // removal of doulbe edges can explode a wire into parts, + // make new wires of them. + // A Loop like previous one but without 2d check + while ( !WEL.IsEmpty() ) { + CE = TopoDS::Edge( WEL.First() ); + WEL.RemoveFirst(); + B.MakeWire( NW ); + VF = TopExp::FirstVertex ( CE, Standard_True); + + End = Standard_False; + while ( !End) { + B.Add( NW, CE ); + CV = TopExp::LastVertex ( CE, Standard_True); + + if (MVDEI.IsBound( CV )) { // CE comes to the degeneration + iDeg = MVDEI( CV ); + TopoDS_Edge NewDegen; + NewDegen = MakeDegenAndSelect( CE, CV, NE, SEID[iDeg], SeqU[iDeg], DE[iDeg]); + B.Add( NW, NewDegen ); + End = CV.IsSame( VF ); + CE = NE; + if (!NE.IsNull()) { // remove NE from WEL + for (itl.Initialize( WEL ); itl.More(); itl.Next()) + if ( NE == itl.Value()) { + WEL.Remove( itl ); + break; + } + } + } // end degeneration + + else { + if (CV.IsSame( VF )) { + End = Standard_True; + continue; + } + // edges in WEL most often are well ordered + // so try to iterate until the End + Standard_Boolean add = Standard_False; + itl.Initialize(WEL); + while ( itl.More() && !End) { + NE = TopoDS::Edge( itl.Value() ); + if ( CV.IsSame( TopExp::FirstVertex( NE, Standard_True ))) { + WEL.Remove( itl ); + if (add) + B.Add( NW, CE ); + CE = NE; + add = Standard_True; + CV = TopExp::LastVertex( CE, Standard_True); + if (MVDEI.IsBound( CV ) || CV.IsSame( VF )) + break; + } + else + itl.Next(); + } + if (!add) + End = Standard_True; + } + } // !End + + myInternalWL.Append( NW ); + } + } // end building new wire(s) from WEL + + } // end Loop on MVE + + // all wires are built + + + // ============================================================ + // select really internal wires i.e. those from which we can`t + // pass to an old (not section) edge + // ============================================================ + + Standard_Integer nbIW = myInternalWL.Extent(); + if (nbIW == 0) + return; + + if ( myNewWires.Extent() != 1 && nbIW > 1) { + TopTools_MapOfShape outerEM (NbConstEdges); // edges connected to non-section ones + TopTools_MapOfShape visitedVM (NbConstEdges); + for ( itl.Initialize( myConstEdges ); itl.More(); itl.Next()) { + if ( ! mySectionEdges.Contains( itl.Value() )) + addConnected (itl.Value(), outerEM, visitedVM, MVE2); + } + // if an edge of a wire is in , the wire is not internal + TopExp_Explorer expIWE; + TopTools_ListIteratorOfListOfShape itIW ( myInternalWL ); + while (itIW.More()) { + expIWE.Init ( itIW.Value() , TopAbs_EDGE ); + if ( outerEM.Contains( expIWE.Current() )) { + myNewWires.Append ( itIW.Value() ); + myInternalWL.Remove( itIW ); // == itIW.Next() + } + else + itIW.Next(); + } + } +} +//======================================================================= +//function : isHole +//purpose : +//======================================================================= + +static Standard_Boolean isHole (const TopoDS_Wire& W, + const TopoDS_Face& F) +{ + BRep_Builder B; + TopoDS_Shape newFace = F.EmptyCopied(); + B.Add(newFace,W.Oriented(TopAbs_FORWARD)); + BRepTopAdaptor_FClass2d classif (TopoDS::Face(newFace), + Precision::PConfusion()); + return (classif.PerformInfinitePoint() == TopAbs_IN); +} + +//======================================================================= +//function : IsInside +//purpose : check if W1 is inside W2. Suppose W2 is not a hole !!!! +//======================================================================= + +static Standard_Boolean isInside(const TopoDS_Face& F, + const TopoDS_Wire& W1, + const TopoDS_Wire& W2) +{ + // make a face with wire W2 + BRep_Builder B; + TopoDS_Shape aLocalShape = F.EmptyCopied(); + TopoDS_Face newFace = TopoDS::Face(aLocalShape); + B.Add(newFace,W2); + + // get any 2d point of W1 + TopExp_Explorer exp(W1,TopAbs_EDGE); + if (BRep_Tool::Degenerated( TopoDS::Edge( exp.Current() ))) + exp.Next(); + const TopoDS_Edge& e = TopoDS::Edge(exp.Current()); + Standard_Real f,l; + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(e,F,f,l); + gp_Pnt2d pt2d(C2d->Value( 0.5 * ( f + l ))); + + BRepTopAdaptor_FClass2d classif(newFace,Precision::PConfusion()); + return (classif.Perform(pt2d) == TopAbs_IN); +} + +//======================================================================= +//function : NewWires +//purpose : Returns the list of wires performed. +// can be an empty list. +//======================================================================= + +const TopTools_ListOfShape& Partition_Loop2d::NewWires() const +{ + return myNewWires; +} + +//======================================================================= +//function : NewFaces +//purpose : Returns the list of faces. +//Warning : The method as to be called before. +// can be an empty list. +//======================================================================= + +const TopTools_ListOfShape& Partition_Loop2d::NewFaces() const +{ + return myNewFaces; +} + +//======================================================================= +//function : findEqual +//purpose : move wires form to pairs of wires build of the same edges +//======================================================================= + +static void findEqual (TopTools_ListOfShape& WL, + TopTools_DataMapOfShapeShape& EqWM, + const TopoDS_Face& F) +{ + TopTools_ListIteratorOfListOfShape it1, it2; + Standard_Integer i,j; + TColStd_MapOfInteger IndMap; + for (it1.Initialize(WL), i=1; it1.More(); it1.Next(), i++) { + + if (IndMap.Contains(i)) continue; + const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value()); + + for (it2.Initialize(WL), j=1; it2.More(); it2.Next(), j++) { + + if (j <= i || IndMap.Contains(j)) continue; + + TopTools_IndexedMapOfShape EdgesMap; + TopExp::MapShapes (Wire1, TopAbs_EDGE, EdgesMap); + + const TopoDS_Shape& Wire2 = it2.Value(); + TopoDS_Iterator itE ( Wire2); + for (; itE.More(); itE.Next()) { + if ( !EdgesMap.Contains( itE.Value()) ) + break; + } + if (!itE.More()) { // all edges are same + if (isHole( Wire1, F)) { + EqWM.Bind ( Wire1, Wire2 ); + } + else { + EqWM.Bind ( Wire2, Wire1 ); + } + IndMap.Add(i); + IndMap.Add(j); + break; + } + } + } + // clear WL + it1.Initialize(WL); + i=1; + while (it1.More()) { + if (IndMap.Contains(i)) + WL.Remove(it1); // next node becomes current and with Next() we would miss it + else + it1.Next(); + i++; + } +} + +//======================================================================= +//function : classify +//purpose : bind to a wire a list of internal wires +//======================================================================= + +static void classify(const TopTools_DataMapOfShapeShape& EqWM, + BRepAlgo_AsDes& OuterInner, + const TopoDS_Face& F) +{ + TopTools_DataMapIteratorOfDataMapOfShapeShape it1, it2; + + for (it1.Initialize(EqWM); it1.More(); it1.Next()) { + // find next after it1.Value() + for (it2.Initialize(EqWM); it2.More(); it2.Next()) + if (it1.Value().IsSame( it2.Value() )) + { + it2.Next(); + break; + } + for ( ; it2.More(); it2.Next()) { + const TopoDS_Wire& Wire1 = TopoDS::Wire( it1.Value() ); + const TopoDS_Wire& Wire2 = TopoDS::Wire( it2.Value() ); + if (isInside(F, Wire1, Wire2)) + OuterInner.Add (Wire2, Wire1); + else if (isInside(F, Wire2, Wire1)) + OuterInner.Add (Wire1, Wire2); + } + } +} +//======================================================================= +//function : WiresToFaces +//purpose : Build faces from the wires result. +// serves to find original edge by new +// one.
contains edges resulting from face +// intersections +//======================================================================= + +void Partition_Loop2d::WiresToFaces(const BRepAlgo_Image& ) +{ + Standard_Integer nbW = myNewWires.Extent() + myInternalWL.Extent(); + if (nbW==0) + return; + + BRepAlgo_FaceRestrictor FR; + FR.Init (myFace,Standard_False); + + // FaceRestrictor is instable in rather simple cases + // (ex. a single face of bellecoque.brep splited by 10 planes: + // sometimes 1-2 faces are missing ). + // So we use it as less as possible: no holes -> make faces by hands + + + // are there holes in myFace ? + Standard_Boolean hasOldHoles = Standard_False; + TopoDS_Iterator itOldW (myFace); + if ( itOldW.More()) { + const TopoDS_Wire& FirstOldWire = TopoDS::Wire( itOldW.Value() ); + itOldW.Next(); + hasOldHoles = itOldW.More() || isHole( FirstOldWire, myFace); + } + if (myInternalWL.IsEmpty() && !hasOldHoles) { + // each wire bounds one face + BRep_Builder B; + TopTools_ListIteratorOfListOfShape itNW (myNewWires); + for (; itNW.More(); itNW.Next()) { + TopoDS_Face NF = TopoDS::Face ( myFace.EmptyCopied() ); + B.Add ( NF, itNW.Value() ); + NF.Orientation( myFaceOri); + myNewFaces.Append ( NF ); + } + return; + } + + // FaceRestrictor can't classify wires build on all the same edges + // and gives incorrect result in such cases (ex. a plane cut into 2 parts by cylinder) + // We must make faces of equal wires separately. One of equal wires makes a + // hole in a face and should come together with outer wires of face. + // The other of a wires pair bounds a face that may have holes in turn. + + // Find equal wires among internal wires + TopTools_DataMapOfShapeShape EqWM; // key is a hole part of a pair of equal wires + findEqual (myInternalWL, EqWM, myFace); + + if (!EqWM.IsEmpty()) { // there are equal wires + + if (hasOldHoles) + myInternalWL.Append( myNewWires ); // an old wire can be inside an equal wire + + // classify equal wire pairs + BRepAlgo_AsDes OuterInner; + classify (EqWM,OuterInner,myFace); + + // make face of most internal of equal wires and its inner wires + while ( !EqWM.IsEmpty()) { + + TopTools_ListOfShape prevHolesL; // list of hole-part of previous most internal equal wires + + // find most internal wires among pairs (key - hole, value - outer part) + TopTools_DataMapIteratorOfDataMapOfShapeShape it(EqWM); + Standard_Integer nbEqW = EqWM.Extent(); // protection against infinite loop + for ( ; it.More(); it.Next()) { + + TopoDS_Wire outerW = TopoDS::Wire ( it.Value() ); + if ( OuterInner.HasDescendant( outerW ) && // has internal + ! OuterInner.Descendant( outerW ).IsEmpty() ) + continue; + + FR.Add( outerW ); + + // add internal wires that are inside of outerW + TopTools_ListIteratorOfListOfShape itIW (myInternalWL); + while ( itIW.More()) { + TopoDS_Wire IW = TopoDS::Wire ( itIW.Value() ); + if ( isInside (myFace, IW, outerW)) { + FR.Add (IW); + myInternalWL.Remove( itIW ); // == itIW.Next() !!! + } + else + itIW.Next(); + } + + // the hole-part of current pair of equal wires will be in the next new face + prevHolesL.Append ( it.Key() ); + + } // Loop on map of equal pairs searching for innermost wires + + // make faces + FR.Perform(); + if (FR.IsDone()) { + for (; FR.More(); FR.Next()) + myNewFaces.Append(FR.Current()); + } + + FR.Clear(); + + // add hole-parts to FaceRestrictor, + // remove them from the EqWM, + // remove found wires as internal of resting classified wires + Standard_Boolean clearOuterInner = ( prevHolesL.Extent() < EqWM.Extent() ); + TopTools_ListIteratorOfListOfShape itPrev (prevHolesL); + for (; itPrev.More(); itPrev.Next()) { + TopoDS_Wire& Hole = TopoDS::Wire ( itPrev.Value() ); + FR.Add ( Hole ); + if (clearOuterInner) { + const TopoDS_Wire& outerW = TopoDS::Wire ( EqWM.Find( Hole ) ); + // Loop on wires including outerW + TopTools_ListIteratorOfListOfShape itO( OuterInner.Ascendant( outerW )); + for (; itO.More(); itO.Next()) { + TopTools_ListOfShape& innerL = OuterInner.ChangeDescendant( itO.Value() ); + TopTools_ListIteratorOfListOfShape itI (innerL); + // Loop on internal wires of current including wire + for (; itI.More(); itI.Next()) + if ( outerW.IsSame( itI.Value() )) { + innerL.Remove( itI ); break; + } + } + } + EqWM.UnBind ( Hole ); + } + + if (nbEqW == EqWM.Extent()) + { + // error: pb with wires classification +#ifdef DEB + MESSAGE("Partition_Loop2d::WiresToFaces(), pb with wires classification"); +#endif + break; + } + + } // while (!EqWM.IsEmpty) + + } // if !EqWM.IsEmpty() + + myNewWires.Append ( myInternalWL ); + + TopTools_ListIteratorOfListOfShape itW (myNewWires); + for (; itW.More(); itW.Next()) { + TopoDS_Wire& W = TopoDS::Wire ( itW.Value() ); + FR.Add(W); + } + FR.Perform(); + for (; FR.IsDone() && FR.More(); FR.Next()) + myNewFaces.Append(FR.Current()); + + + TopTools_ListIteratorOfListOfShape itNF (myNewFaces); + for (; itNF.More(); itNF.Next()) + itNF.Value().Orientation( myFaceOri ); +} + +#endif diff --git a/libsrc/occ/Partition_Loop2d.hxx b/libsrc/occ/Partition_Loop2d.hxx new file mode 100644 index 00000000..bdf1c253 --- /dev/null +++ b/libsrc/occ/Partition_Loop2d.hxx @@ -0,0 +1,106 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop2d.hxx +// Module : GEOM + +#ifndef _Partition_Loop2d_HeaderFile +#define _Partition_Loop2d_HeaderFile + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopAbs_Orientation_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +class TopoDS_Face; +class TopoDS_Edge; +class TopTools_ListOfShape; +class BRepAlgo_Image; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Loop2d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // + Partition_Loop2d(); + void Init(const TopoDS_Face& F) ; + void AddConstEdge(const TopoDS_Edge& E) ; + void AddSectionEdge(const TopoDS_Edge& E) ; + void Perform() ; + const TopTools_ListOfShape& NewWires() const; + void WiresToFaces(const BRepAlgo_Image& EdgeImage) ; + const TopTools_ListOfShape& NewFaces() const; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // + TopoDS_Face myFace; + TopAbs_Orientation myFaceOri; + TopTools_ListOfShape myConstEdges; + TopTools_ListOfShape myNewWires; + TopTools_ListOfShape myNewFaces; + TopTools_ListOfShape myInternalWL; + TopTools_MapOfShape mySectionEdges; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/libsrc/occ/Partition_Loop2d.ixx b/libsrc/occ/Partition_Loop2d.ixx new file mode 100644 index 00000000..2d35fd5c --- /dev/null +++ b/libsrc/occ/Partition_Loop2d.ixx @@ -0,0 +1,14 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop2d.ixx +// Module : GEOM + +#include "Partition_Loop2d.jxx" + + + + diff --git a/libsrc/occ/Partition_Loop2d.jxx b/libsrc/occ/Partition_Loop2d.jxx new file mode 100644 index 00000000..555c16c8 --- /dev/null +++ b/libsrc/occ/Partition_Loop2d.jxx @@ -0,0 +1,24 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop2d.jxx +// Module : GEOM + +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _BRepAlgo_Image_HeaderFile +#include +#endif +#ifndef _Partition_Loop2d_HeaderFile +#include "Partition_Loop2d.hxx" +#endif diff --git a/libsrc/occ/Partition_Loop3d.cxx b/libsrc/occ/Partition_Loop3d.cxx new file mode 100644 index 00000000..3e9acc3c --- /dev/null +++ b/libsrc/occ/Partition_Loop3d.cxx @@ -0,0 +1,356 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.cxx +// Module : GEOM + +//using namespace std; +#include +#include "Partition_Loop3d.ixx" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : Partition_Loop3d +//purpose : +//======================================================================= + +Partition_Loop3d::Partition_Loop3d() +{ +} + +//======================================================================= +//function : AddConstFaces +//purpose : Add faces of as unique faces in the result. +//======================================================================= + +void Partition_Loop3d::AddConstFaces(const TopoDS_Shape& S) +{ + TopExp_Explorer FaceExp(S, TopAbs_FACE); + for (; FaceExp.More(); FaceExp.Next()) + myFaces.Append( FaceExp.Current() ); + + TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, myEFMap); +} + +//======================================================================= +//function : AddSectionFaces +//purpose : Add faces of as double faces in the result. +//======================================================================= + +void Partition_Loop3d::AddSectionFaces(const TopoDS_Shape& S) +{ + AddConstFaces( S ); + AddConstFaces( S.Reversed() ); +} + +//======================================================================= +//function : MakeShells +//purpose : Make and return shells. +// can contain faces that must not be +// added to result shells. +//======================================================================= + +const TopTools_ListOfShape& + Partition_Loop3d::MakeShells (const TopTools_MapOfOrientedShape& AvoidFacesMap) +{ + myNewShells.Clear(); + + BRep_Builder Builder; + TopTools_MapOfShape CheckedEdgesMap; + TopTools_MapOfOrientedShape AddedFacesMap; + + TopTools_ListIteratorOfListOfShape itF (myFaces); + for (; itF.More(); itF.Next()) + { + const TopoDS_Shape& FF = itF.Value(); + if (AvoidFacesMap.Contains( FF ) || + ! AddedFacesMap.Add( FF ) ) + continue; + + // make a new shell + TopoDS_Shell Shell; + Builder.MakeShell(Shell); + Builder.Add(Shell,FF); + + // clear the maps from shapes added to previous Shell + TopTools_MapIteratorOfMapOfShape itEM (CheckedEdgesMap); + for (; itEM.More(); itEM.Next()) { + TopTools_ListOfShape& FL = myEFMap.ChangeFromKey( itEM.Key()); + TopTools_ListIteratorOfListOfShape it (FL); + while ( it.More()) { + if (AddedFacesMap.Contains( it.Value())) + FL.Remove( it ); + else + it.Next(); + } + } + CheckedEdgesMap.Clear(); + + + // loop on faces added to Shell; add their neighbor faces to Shell and so on + TopoDS_Iterator itAddedF (Shell); + for (; itAddedF.More(); itAddedF.Next()) + { + const TopoDS_Face& F = TopoDS::Face (itAddedF.Value()); + + // loop on edges of F; find a good neighbor face of F by E + TopExp_Explorer EdgeExp(F, TopAbs_EDGE); + for (; EdgeExp.More(); EdgeExp.Next()) + { + const TopoDS_Edge& E = TopoDS::Edge( EdgeExp.Current()); + if (! CheckedEdgesMap.Add( E )) + continue; + + // candidate faces list + const TopTools_ListOfShape& FL = myEFMap.ChangeFromKey(E); + if (FL.IsEmpty()) + continue; + // select one of neighbors + TopoDS_Face SelF; + if (FL.Extent() == 2) { + if (! F.IsSame( FL.First() )) + SelF = TopoDS::Face( FL.First() ); + else if (!F.IsSame( FL.Last() )) + SelF = TopoDS::Face( FL.Last() ); + } + else { + // check if a face already added to Shell shares E + TopTools_ListIteratorOfListOfShape it (FL); + Standard_Boolean found = Standard_False; + for (; !found && it.More(); it.Next()) + if (F != it.Value()) + found = AddedFacesMap.Contains( it.Value() ); + if (found) + continue; + // select basing on geometrical check + Standard_Boolean GoodOri, inside; + Standard_Real dot, MaxDot = -100; + TopTools_ListOfShape TangFL; // tangent faces + for ( it.Initialize( FL ) ; it.More(); it.Next()) { + const TopoDS_Face& NeighborF = TopoDS::Face( it.Value()); + if (NeighborF.IsSame( F )) + continue; + inside = Partition_Loop3d::IsInside( E, F, NeighborF, 1, dot, GoodOri); + if (!GoodOri) + continue; + if (!inside) + dot = -dot - 3; + if (dot < MaxDot) + continue; + if ( IsEqual( dot, MaxDot)) + TangFL.Append(SelF); + else + TangFL.Clear(); + MaxDot = dot; + SelF = NeighborF; + } + if (!TangFL.IsEmpty()) { + for (it.Initialize( TangFL ); it.More(); it.Next()) { + const TopoDS_Face& NeighborF = TopoDS::Face( it.Value()); + if (Partition_Loop3d:: IsInside( E, SelF , NeighborF, 0, dot, GoodOri)) + SelF = NeighborF; + } + } + } + if (!SelF.IsNull() && + AddedFacesMap.Add( SelF ) && + !AvoidFacesMap.Contains( SelF )) + Builder.Add( Shell, SelF); + + } // loop on edges of F + + } // loop on the faces added to Shell + + // Shell is complete + myNewShells.Append( Shell ); + + } // loop on myFaces + + + // prepare to the next call + myFaces.Clear(); + myEFMap.Clear(); + + return myNewShells; +} + + + +//======================================================================= +//function : Normal +//purpose : +//======================================================================= + +gp_Vec Partition_Loop3d::Normal(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + gp_Vec Norm, V1, V2; + Standard_Real First, Last; + gp_Pnt Ps; + + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last); + Handle(Geom_Surface) Sf = BRep_Tool::Surface(F); + + gp_Pnt2d p = C2d->Value( 0.5*(First+Last) ); + Sf->D1(p.X(), p.Y(), Ps, V1, V2); + Norm = V1.Crossed(V2); + + if (F.Orientation() == TopAbs_REVERSED ) + Norm.Reverse(); + + return Norm; +} + +//======================================================================= +//function : NextNormal +//purpose : find normal to F at point a little inside F near the middle of E +//warning : E must be properly oriented in F. +//======================================================================= + +static gp_Vec NextNormal(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + Standard_Real First, Last; + + Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E, F, First, Last); + Handle(Geom_Surface) Sf = BRep_Tool::Surface(F); + + gp_Pnt2d p; + gp_Vec2d v; + C2d->D1( 0.5*(First+Last), p, v); + if (E.Orientation() != F.Orientation()) + v.Reverse(); + gp_Dir2d dir( -v.Y(), v.X() ); // dir inside F + + Standard_Real duv = 1e-6; // this is not Ok and may give incorrect result if + // resolutionUV of compared faces is very different. To have a good result, + //it is necessary to get normal to faces at points equidistant from E in 3D + + p.SetX( p.X() + dir.X()*duv ); + p.SetY( p.Y() + dir.Y()*duv ); + + gp_Pnt Ps; + gp_Vec Norm, V1, V2, VV1, VV2; + Sf->D1( p.X(), p.Y(), Ps, V1, V2); + Norm = V1.Crossed(V2); + + if (F.Orientation() == TopAbs_REVERSED ) + Norm.Reverse(); + + return Norm; +} + + +//======================================================================= +//function : FindEinF +//purpose : find E in F +//======================================================================= + +static TopoDS_Edge FindEinF(const TopoDS_Edge& E, + const TopoDS_Face& F) +{ + TopExp_Explorer expl (F, TopAbs_EDGE); + for (; expl.More(); expl.Next()) + if( E.IsSame( expl.Current() )) + return TopoDS::Edge(expl.Current()); + TopoDS_Edge nullE; + return nullE; +} + +//======================================================================= +//function : IsInside +//purpose : check if is inside by edge . +// if , compute : scalar production of +// normalized vectors pointing inside faces, and +// check if faces are oriented well for sewing +//======================================================================= + +Standard_Boolean Partition_Loop3d::IsInside(const TopoDS_Edge& E, + const TopoDS_Face& F1, + const TopoDS_Face& F2, + const Standard_Boolean CountDot, + Standard_Real& Dot, + Standard_Boolean& GoodOri) +{ + Standard_Real f, l; + gp_Pnt P; + gp_Vec Vc1, Vc2, Vin1, Vin2, Nf1, Nf2; + Handle(Geom_Curve) Curve = BRep_Tool::Curve(E,f,l); + Curve->D1( 0.5*(f + l), P, Vc2); + TopoDS_Edge E1, E2 = FindEinF (E, F2); + if (E2.Orientation() == TopAbs_REVERSED ) Vc2.Reverse(); + + Nf1 = Normal(E,F1); + Nf2 = Normal(E,F2); + + Standard_Real sin = + Nf1.CrossSquareMagnitude(Nf2) / Nf1.SquareMagnitude() / Nf2.SquareMagnitude(); + Standard_Boolean tangent = sin < 0.001; + + Standard_Boolean inside = 0; + if (tangent) { + E1 = FindEinF (E, F1); + gp_Vec NNf1 = NextNormal(E1,F1); + gp_Vec NNf2 = NextNormal(E2,F2); + Vin2 = NNf2.Crossed(Vc2); + inside = Vin2 * NNf1 < 0; + } + else { + Vin2 = Nf2.Crossed(Vc2); + inside = Vin2 * Nf1 < 0; + } + + if (!CountDot) return inside; + + if (tangent) + Vin2 = Nf2.Crossed(Vc2); + else + E1 = FindEinF (E, F1); + + Vc1 = Vc2; + if (E1.Orientation() != E2.Orientation()) + Vc1.Reverse(); + Vin1 = Nf1.Crossed(Vc1); + + if (tangent) { + Standard_Real N1N2 = Nf1 * Nf2; + GoodOri = (Vin2 * Vin1 < 0) ? N1N2 > 0 : N1N2 < 0; + } + else { + Standard_Real V1N2 = Vin1 * Nf2; + GoodOri = ( inside ? V1N2 <= 0 : V1N2 >= 0); + } + + Vin1.Normalize(); + Vin2.Normalize(); + + Dot = Vin2 * Vin1; + + return inside; +} + + +#endif diff --git a/libsrc/occ/Partition_Loop3d.hxx b/libsrc/occ/Partition_Loop3d.hxx new file mode 100644 index 00000000..52abd115 --- /dev/null +++ b/libsrc/occ/Partition_Loop3d.hxx @@ -0,0 +1,102 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.hxx +// Module : GEOM + +#ifndef _Partition_Loop3d_HeaderFile +#define _Partition_Loop3d_HeaderFile + +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_IndexedDataMapOfShapeListOfShape_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +#ifndef _Standard_Real_HeaderFile +#include +#endif +class TopoDS_Shape; +class TopTools_ListOfShape; +class TopTools_MapOfOrientedShape; +class TopoDS_Edge; +class TopoDS_Face; +class gp_Vec; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Loop3d { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // + Partition_Loop3d(); + void AddConstFaces(const TopoDS_Shape& S) ; + void AddSectionFaces(const TopoDS_Shape& S) ; + const TopTools_ListOfShape& MakeShells(const TopTools_MapOfOrientedShape& AvoidFacesMap) ; + static Standard_Boolean IsInside(const TopoDS_Edge& E,const TopoDS_Face& F1,const TopoDS_Face& F2,const Standard_Boolean CountDot,Standard_Real& Dot,Standard_Boolean& GoodOri) ; + static gp_Vec Normal(const TopoDS_Edge& E,const TopoDS_Face& F) ; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + + + // Fields PRIVATE + // + TopTools_ListOfShape myNewShells; + TopTools_ListOfShape myFaces; + TopTools_IndexedDataMapOfShapeListOfShape myEFMap; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/libsrc/occ/Partition_Loop3d.ixx b/libsrc/occ/Partition_Loop3d.ixx new file mode 100644 index 00000000..a661b324 --- /dev/null +++ b/libsrc/occ/Partition_Loop3d.ixx @@ -0,0 +1,14 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.ixx +// Module : GEOM + +#include "Partition_Loop3d.jxx" + + + + diff --git a/libsrc/occ/Partition_Loop3d.jxx b/libsrc/occ/Partition_Loop3d.jxx new file mode 100644 index 00000000..9b654f41 --- /dev/null +++ b/libsrc/occ/Partition_Loop3d.jxx @@ -0,0 +1,30 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Loop3d.jxx +// Module : GEOM + +#ifndef _TopoDS_Shape_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfOrientedShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _TopoDS_Face_HeaderFile +#include +#endif +#ifndef _gp_Vec_HeaderFile +#include +#endif +#ifndef _Partition_Loop3d_HeaderFile +#include "Partition_Loop3d.hxx" +#endif diff --git a/libsrc/occ/Partition_Spliter.cxx b/libsrc/occ/Partition_Spliter.cxx new file mode 100644 index 00000000..97bd8e33 --- /dev/null +++ b/libsrc/occ/Partition_Spliter.cxx @@ -0,0 +1,2168 @@ +#ifdef OCCGEOMETRY + +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Spliter.cxx +// Author : Benedicte MARTIN +// Module : GEOM +// $Header: /cvs/netgen/netgen/libsrc/occ/Partition_Spliter.cxx,v 1.7 2008/03/31 14:20:28 wabro Exp $ + +//using namespace std; +#include +#include "Partition_Inter2d.hxx" +#include "Partition_Inter3d.hxx" +#include "Partition_Loop2d.hxx" +#include "Partition_Loop3d.hxx" +#include "Partition_Spliter.ixx" + +#include "utilities.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef DEB +//# define PART_PERF +#endif + +#ifdef PART_PERF +# include +#endif + +//======================================================================= +//function : isClosed +//purpose : check id a shape is closed, ie is a solid or a closed shell +//======================================================================= + +static Standard_Boolean isClosed(const TopoDS_Shape& theShape) +{ + Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID); + + if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) { + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF); + for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i) + isClosed = ( MEF(i).Extent() != 1 ); + } + + return isClosed; +} + +//======================================================================= +//function : Partition_Spliter +//purpose : constructor +//======================================================================= + +Partition_Spliter::Partition_Spliter() +{ + myAsDes = new BRepAlgo_AsDes; + Clear(); +} + +//======================================================================= +//function : AddTool +//purpose : add cutting tool that will _NOT_ be in result +//======================================================================= + +void Partition_Spliter::AddTool(const TopoDS_Shape& S) +{ + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + TopoDS_Iterator it (S); + for (; it.More(); it.Next()) + { + AddTool( it.Value()); + myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape + } + return; + } + + for (TopExp_Explorer exp(S,TopAbs_FACE); exp.More(); exp.Next()) + { + myMapTools.Add(exp.Current()); + myFaceShapeMap.Bind( exp.Current(), S ); + } + if (isClosed( S )) + myClosedShapes.Add( S ); +} + +//======================================================================= +//function : AddShape +//purpose : add object Shape to be splited +//======================================================================= + +void Partition_Spliter::AddShape(const TopoDS_Shape& S) +{ + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + TopoDS_Iterator it (S); + for (; it.More(); it.Next()) + { + AddShape( it.Value()); + myFaceShapeMap.Bind( it.Value(), S ); // to know compound by shape + } + return; + } + + TopExp_Explorer exp(S,TopAbs_FACE); + if (!exp.More()) { // do not split edges and vertices + //myBuilder.Add( myShape, S ); + return; + } + + Standard_Integer nbFacesBefore = myMapFaces.Extent(); // not to add twice the same S + for (; exp.More(); exp.Next()) { + const TopoDS_Shape & aFace = exp.Current(); + if ( ! myFaceShapeMap.IsBound( aFace )) // keep shape of tool face added as object + myFaceShapeMap.Bind( aFace, S ); + if (myMapFaces.Add( aFace )) + myImagesFaces.SetRoot( aFace ); + } + + if (nbFacesBefore == myMapFaces.Extent()) + return; + + // solids must be processed before all + if (S.ShapeType() == TopAbs_SOLID) + myListShapes.Prepend(S); + else + myListShapes.Append(S); + + if (isClosed( S )) + myClosedShapes.Add( S ); + +} + +//======================================================================= +//function : Shape +//purpose : return resulting compound +//======================================================================= + +TopoDS_Shape Partition_Spliter::Shape() const +{ + return myShape; +} + +//======================================================================= +//function : Clear +//purpose : clear fields +//======================================================================= + +void Partition_Spliter::Clear() +{ + myDoneStep = TopAbs_SHAPE; + + myListShapes.Clear(); + myMapFaces.Clear(); + myMapTools.Clear(); + myEqualEdges.Clear(); + myNewSection.Clear(); + myClosedShapes.Clear(); + mySharedFaces.Clear(); + myWrappingSolid.Clear(); + myFaceShapeMap.Clear(); + + myInternalFaces.Clear(); + myIntNotClFaces.Clear(); + + myAsDes->Clear(); + myImagesFaces.Clear(); + myImagesEdges.Clear(); + myImageShape.Clear(); + + // myInter3d = Partition_Inter3d(myAsDes); + Partition_Inter3d hinter3d (myAsDes); + myInter3d = hinter3d; + + myAddedFacesMap.Clear(); + +} + +//======================================================================= +//function : Compute +//purpose : produce a result +//======================================================================= + +void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit) +{ + if ((Limit != TopAbs_SHAPE && myDoneStep == Limit) || + (Limit == TopAbs_SHAPE && myDoneStep == TopAbs_SOLID)) + return; + + myBuilder.MakeCompound( myShape ); + + TopTools_MapIteratorOfMapOfShape it; + TopTools_ListIteratorOfListOfShape itl; + TopExp_Explorer exp; + +#ifdef PART_PERF + OSD_Chronometer aCron; +#endif + + if (myDoneStep > TopAbs_VERTEX) { + + TopTools_ListOfShape aListFaces; + aListFaces = myImagesFaces.Roots(); + for (it.Initialize(myMapTools); it.More(); it.Next()) + aListFaces.Append(it.Key()); + +#ifdef PART_PERF + aCron.Start(); +#endif + + //----------------------------------------------- + // Intersection between faces + //----------------------------------------------- + // result is in myAsDes as a map Face - list of new edges; + // special care is done for section edges, same domain faces and vertices: + // data about them is inside myInter3d + myInter3d.CompletPart3d(aListFaces, myFaceShapeMap); + +#ifdef PART_PERF + MESSAGE("+++ CompletPart3d()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + //----------------------------------------------- + // Intersection of edges + //----------------------------------------------- + + // add tool faces which must be reconstructed to myMapFaces too + FindToolsToReconstruct(); + +#ifdef PART_PERF + MESSAGE("+++ FindToolsToReconstruct()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + + // add existing vertices to edges of object faces in myAsDes + TopTools_MapOfShape DoneEM; + for ( it.Initialize(myMapFaces); it.More(); it.Next()) { + const TopoDS_Shape& F = it.Key(); + TopoDS_Face FForward = TopoDS::Face(F.Oriented(TopAbs_FORWARD)); + for (exp.Init(FForward,TopAbs_EDGE); exp.More(); exp.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( exp.Current() ); + myAsDes->Add(FForward,E); + if (DoneEM.Add(E)) { + TopoDS_Iterator itV(E); + for (; itV.More(); itV.Next()) { + const TopoDS_Vertex& V = TopoDS::Vertex( itV.Value()); + myAsDes->Add(E, myInter3d.ReplaceSameDomainV( V, E )); + } + } + } + } + + // intersect edges that are descendants of a face in myAsDes + TopTools_MapOfShape& Modif = myInter3d.TouchedFaces(); + for ( it.Initialize(Modif); it.More(); it.Next()) { + const TopoDS_Face& F = TopoDS::Face(it.Key()); + Partition_Inter2d::CompletPart2d (myAsDes, F, myInter3d.NewEdges()); + } + // now myAsDes contains also new vertices made at edge intersection as + // descendant of edges both new and old + + myDoneStep = TopAbs_VERTEX; + +#ifdef PART_PERF + MESSAGE("+++ CompletPart2d()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + } // if (myDoneStep > TopAbs_VERTEX) + + if (Limit == TopAbs_VERTEX) { + // add new vertices to myShape + for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) { + if (! myAsDes->HasDescendant( it.Key() )) + continue; + itl.Initialize( myAsDes->Descendant( it.Key() )); + for (; itl.More(); itl.Next()) + myBuilder.Add ( myShape, itl.Value() ); + } + return; + } + + + if (myDoneStep > TopAbs_EDGE) { + + //----------------------------------------------- + //----------------------------------------------- + // ------- Reconstruction of all the edges.------ + //----------------------------------------------- + //----------------------------------------------- + + // ============== + // cut new edges + // ============== + TopTools_ListOfShape LSE; // all edge splits + for ( it.Initialize(myInter3d.NewEdges()); it.More(); it.Next()) { + + TopoDS_Vertex V1,V2; + TopoDS_Edge EE = TopoDS::Edge(it.Key()); + + TopTools_ListOfShape aListV, aListF; + aListV = myAsDes->Descendant(EE); // intersection vertices + aListF = myAsDes->Ascendant(EE); // intersected faces + + if (aListV.IsEmpty()) + continue; // new edge does not intersect any other edge + + // Add end vertices to new edges only if + // one face is Tool and the other is Shape + Standard_Boolean isTool1 = ! myMapFaces.Contains( aListF.First() ); + Standard_Boolean isTool2 = ! myMapFaces.Contains( aListF.Last() ); + if (isTool1 || isTool2) + { + TopExp::Vertices(EE,V1,V2); + Standard_Real Tol = Max (BRep_Tool::Tolerance( V1 ), + BRep_Tool::Tolerance( V2 )); + + gp_Pnt P1 = BRep_Tool::Pnt(V1); + gp_Pnt P2 = BRep_Tool::Pnt(V2); + Standard_Boolean AddV1 = Standard_True; + Standard_Boolean AddV2 = Standard_True; + + // add only if there is no intersection at end vertex + for (itl.Initialize(aListV); itl.More(); itl.Next()) { + const TopoDS_Vertex& Ve = TopoDS::Vertex(itl.Value()) ; + Standard_Real Tol2 = Max ( Tol, BRep_Tool::Tolerance( Ve )); + Tol2 *= Tol2; + gp_Pnt P = BRep_Tool::Pnt(Ve); + if (AddV1 && P.SquareDistance(P1) <= Tol2) + AddV1 = Standard_False; + + if (AddV2 && P.SquareDistance(P2) <= Tol2) + AddV2 = Standard_False; + } + + if (AddV1) { + aListV.Append(V1); + myAsDes->Add(EE,V1); + } + + if (AddV2) { + aListV.Append(V2); + myAsDes->Add(EE,V2); + } + } + + // cut new edges + Standard_Integer NbV=aListV.Extent() ; + if (NbV>1 || (NbV==1 && V1.IsSame(V2)) ) { + TopTools_ListOfShape LNE; + MakeEdges (EE,aListV, LNE); + myImagesEdges.Bind(EE,LNE); + LSE.Append( LNE ); + } + } + + // ============== + // cut old edges + // ============== + for ( it.Initialize(myMapFaces); it.More(); it.Next()) { + for (exp.Init( it.Key(), TopAbs_EDGE); exp.More(); exp.Next()) { + const TopoDS_Edge& EE = TopoDS::Edge( exp.Current() ); + if ( myImagesEdges.HasImage( EE )) + continue; + TopTools_ListOfShape LNE; + const TopTools_ListOfShape& aListVV = myAsDes->Descendant(EE); + MakeEdges (EE, aListVV, LNE); + myImagesEdges.Bind(EE,LNE); + LSE.Append( LNE ); + } + } +#ifdef PART_PERF + MESSAGE("+++ Cut Edges"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + + // process same domain section edges + MergeEqualEdges( LSE ); + + myDoneStep = TopAbs_EDGE; + +#ifdef PART_PERF + MESSAGE("+++ MergeEqualEdges()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + } // if (myDoneStep > TopAbs_EDGE) + + if (Limit == TopAbs_EDGE) { + // add splits of old edges + TopTools_ListIteratorOfListOfShape itNE; + for (itl.Initialize( myListShapes );itl.More();itl.Next()) { + if (myMapTools.Contains( itl.Value() )) + continue; // skip tool faces + for ( exp.Init( itl.Value(), TopAbs_EDGE ); exp.More(); exp.Next()) { + itNE.Initialize( myImagesEdges.Image( exp.Current() )); + for ( ; itNE.More(); itNE.Next()) + myBuilder.Add ( myShape, itNE.Value() ); + } + } + // add splits of new edges + for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) { + itNE.Initialize( myImagesEdges.Image( it.Key() )); + for (; itNE.More(); itNE.Next()) + myBuilder.Add ( myShape, itNE.Value() ); + } + return; + } + + + //----------------------------------------------- + // split faces + //----------------------------------------------- + + if (myDoneStep > TopAbs_FACE) { + + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + TopoDS_Shape FacesComp = MakeFaces ( itl.Value()); + // there is a cunning here: myImagesFaces keeps faces made by Loop2d + // but some of them may be replaced with splits of same domain face + // and myImageShape keeps ultimate result + myImageShape.Bind( itl.Value(), FacesComp ); + } + + myDoneStep = TopAbs_FACE; +#ifdef PART_PERF + MESSAGE("+++ MakeFaces()"); + aCron.Show( cout ); + aCron.Reset(); + aCron.Start(); +#endif + } + + if (Limit == TopAbs_WIRE || + Limit == TopAbs_FACE) { + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + if ( myMapTools.Contains( itl.Value() )) + continue; // no result needed for a tool face + const TopoDS_Shape& FacesComp = myImageShape.Image( itl.Value() ).First(); + for ( exp.Init( FacesComp, Limit); exp.More(); exp.Next()) + myBuilder.Add ( myShape, exp.Current()); + } + return; + } + + + //----------------------------------------------- + // split and add solids and shells + //----------------------------------------------- + + Standard_Boolean makeSolids = (Limit == TopAbs_SHAPE || + Limit < TopAbs_SHELL); + for (itl.Initialize(myListShapes);itl.More();itl.Next()) + { + const TopoDS_Shape & S = itl.Value(); + if (S.ShapeType() > TopAbs_SHELL) + continue; + + TopTools_ListOfShape NSL; // new shape list + MakeShells (S , NSL); + if (makeSolids && S.ShapeType() == TopAbs_SOLID ) + MakeSolids( S, NSL ); + + // store new shells or solids + TopTools_ListIteratorOfListOfShape itNSL (NSL); + for ( ; itNSL.More(); itNSL.Next()) + myBuilder.Add (myShape, itNSL.Value()); + } +#ifdef PART_PERF + MESSAGE("+++ MakeShells()"); + aCron.Show( cout ); +#endif + + //----------------------------------------------- + // add split faces + //----------------------------------------------- + + for (itl.Initialize(myListShapes);itl.More();itl.Next()) + { + const TopoDS_Shape & S = itl.Value(); + if (S.ShapeType() != TopAbs_FACE || + myMapTools.Contains( S )) + continue; + TopoDS_Iterator itS( myImageShape.Image(S).First() ); + for (; itS.More(); itS.Next()) + if (! myAddedFacesMap.Contains( itS.Value() )) + myBuilder.Add (myShape, itS.Value()); + } + + myDoneStep = makeSolids ? TopAbs_SOLID : TopAbs_SHELL; + +} + +//======================================================================= +//function : MakeSolids +//purpose : make solids out of Shells +//======================================================================= + +void Partition_Spliter::MakeSolids(const TopoDS_Shape & theSolid, + TopTools_ListOfShape & theShellList) +{ + // for a solid wrapping other shells or solids without intersection, + // it is necessary to find shells making holes in it + + TopTools_ListOfShape aNewSolids; // result + TopTools_ListOfShape aHoleShells; + TopoDS_Shape anInfinitePointShape; + + Standard_Boolean isWrapping = myWrappingSolid.Contains( theSolid ); + if (!isWrapping && !theShellList.IsEmpty()) + { + // check if theSolid initially has internal shells + TopoDS_Iterator aShellExp (theSolid); + aShellExp.Next(); + isWrapping = aShellExp.More(); + } + + TopTools_ListIteratorOfListOfShape aShellIt(theShellList); + for ( ; aShellIt.More(); aShellIt.Next()) + { + const TopoDS_Shape & aShell = aShellIt.Value(); + + // check if a shell is a hole + if (isWrapping && IsInside (anInfinitePointShape, aShell)) + aHoleShells.Append( aShell ); + else + { + // make a solid from a shell + TopoDS_Solid Solid; + myBuilder.MakeSolid( Solid ); + myBuilder.Add (Solid, aShell); + + aNewSolids.Append (Solid); + } + } + + // find an outer shell most close to each hole shell + TopTools_DataMapOfShapeShape aInOutMap; + for (aShellIt.Initialize( aHoleShells ); aShellIt.More(); aShellIt.Next()) + { + const TopoDS_Shape & aHole = aShellIt.Value(); + TopTools_ListIteratorOfListOfShape aSolisIt (aNewSolids); + for ( ; aSolisIt.More(); aSolisIt.Next()) + { + const TopoDS_Shape & aSolid = aSolisIt.Value(); + if (! IsInside( aHole, aSolid )) + continue; + + if ( aInOutMap.IsBound (aHole)) + { + const TopoDS_Shape & aSolid2 = aInOutMap( aHole ); + if ( IsInside( aSolid, aSolid2 )) + { + aInOutMap.UnBind( aHole ); + aInOutMap.Bind ( aHole, aSolid ); + } + } + else + aInOutMap.Bind ( aHole, aSolid ); + } + + // add aHole to a solid + if (aInOutMap.IsBound( aHole )) + myBuilder.Add ( aInOutMap( aHole ), aHole ); + } + + theShellList.Clear(); + theShellList.Append( aNewSolids ); +} + +//======================================================================= +//function : FindFacesInside +//purpose : return compound of faces of other shapes that are +// inside . +// is an object shape. +// makes avoid faces that do not form a +// closed shell +// makes return already added faces +//======================================================================= + +TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& theShape, + const Standard_Boolean CheckClosed, + const Standard_Boolean All) +{ + // ================================================ + // check if internal faces have been already found + // ================================================ + TopExp_Explorer expl; + if (myInternalFaces.IsBound( theShape )) + { + TopoDS_Shape aIntFComp = myInternalFaces.Find ( theShape ); + TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find ( theShape ); + + expl.Init( aIntRemFComp, TopAbs_FACE); + if (CheckClosed || !expl.More()) + return aIntFComp; + + TopoDS_Compound C; + myBuilder.MakeCompound( C ); + // add removed faces + for (; expl.More(); expl.Next()) + myBuilder.Add( C, expl.Current() ); + // add good internal faces + for (expl.Init( aIntFComp, TopAbs_FACE); expl.More(); expl.Next()) + myBuilder.Add( C, expl.Current() ); + return C; + } + + // =================================== + // get data for internal faces search + // =================================== + + // compound of split faces of theShape + const TopoDS_Shape& CSF = myImageShape.Image(theShape).First(); + + TopTools_MapOfShape MSE, MFP; + TopTools_DataMapOfShapeListOfShape DMSEFP; + TopTools_MapIteratorOfMapOfShape itm; + TopTools_ListOfShape EmptyL; + + // MSE filling: map of new section edges of CSF + for (expl.Init(CSF,TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape & resE = expl.Current() ; + if (myNewSection.Contains( resE )) // only new edges + MSE.Add(resE); + } + + // DMEF: map edge of CSF - faces of CSF + TopTools_IndexedDataMapOfShapeListOfShape DMEF; + TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF); + + // Fill + // 1. MFP - a map of faces to process: map of resulting faces except + // those of theShape; we`ll add to C those of them which are inside CSF + // 2. DMSEFP - edge of MSE => faces of MFP + TopTools_ListIteratorOfListOfShape itl; + for (itl.Initialize(myListShapes);itl.More();itl.Next()) { + const TopoDS_Shape& aShape = itl.Value(); + if ( theShape.IsSame( aShape )) continue; + // fill maps + // iterate on split faces of aShape + TopoDS_Iterator itF ( myImageShape.Image(aShape).First() ); + for ( ; itF.More(); itF.Next()) { + const TopoDS_Shape& sf = itF.Value(); + MFP.Add(sf); + // iterate on edges of split faces of aShape, + // add to DMSEFP edges that are new + for (expl.Init( sf, TopAbs_EDGE ); expl.More(); expl.Next()) { + TopoDS_Shape se = expl.Current(); + if ( MSE.Contains(se)) {// section edge + if (!DMSEFP.IsBound(se)) + DMSEFP.Bind(se,EmptyL); + DMSEFP(se).Append(sf); + } + } + } + } + + // add tool faces having section edges on faces of theShape to MFP and DMSEFP; + // such tool faces need not to be reconstructed and so they are not in myListShapes + for (itm.Initialize(myMapTools); itm.More(); itm.Next()) + { + const TopoDS_Shape & aToolFace = itm.Key(); + if (myMapFaces.Contains( aToolFace )) + continue; + MFP.Add(aToolFace); + for (expl.Init( aToolFace, TopAbs_EDGE ); expl.More(); expl.Next()) { + TopoDS_Shape se = expl.Current(); + if ( MSE.Contains( se )) {// section edge + if (!DMSEFP.IsBound( se )) + DMSEFP.Bind( se, EmptyL ); + DMSEFP( se ).Append( aToolFace ); + } + } + } + + + // =========================== + // find faces inside theShape + // =========================== + + Standard_Boolean skipAlreadyAdded = Standard_False; + Standard_Boolean GoodOri, inside; + Standard_Real dot; + TopTools_ListOfShape KeepFaces; + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit; + + // iterate on section edges, check faces of other shapes + // sharing section edges and put internal faces to KeepFaces + for (Mapit.Initialize(DMSEFP); Mapit.More() ; Mapit.Next() ) { + // a new edge of theShape + const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key()); + // an original edge of which E is a split + const TopoDS_Edge& OrigE = TopoDS::Edge ( myImagesEdges.Root( E )); + // does OrigE itself splits a face + Standard_Boolean isSectionE = myInter3d.IsSectionEdge ( OrigE ); + + // split faces of other shapes sharing E + TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E); + itl.Initialize( LSF ); + while (itl.More()) { + // a split faces of other shape + TopoDS_Face aFace1 = TopoDS::Face(itl.Value()); + // remove aFace1 form DMSEFP and MFP + LSF.Remove( itl ); // == itl.Next(); + if (!MFP.Remove( aFace1 )) + continue; // was not is MFP ( i.e already checked) + // check if aFace1 was already added to 2 shells + if (!All && + myAddedFacesMap.Contains( aFace1 ) && + myAddedFacesMap.Contains( aFace1.Reversed() )) { + skipAlreadyAdded = Standard_True; + continue; + } + + // find another face which originates from the same face as aFace1: + // usually aFace2 is internal if aFace1 is not and vice versa + + TopoDS_Shape anOrigFace = aFace1; + if (myImagesFaces.IsImage(aFace1)) + anOrigFace = myImagesFaces.Root(aFace1); + TopoDS_Shape aFace2; + if ( !isSectionE ) { + while (itl.More()) { + aFace2 = itl.Value(); + if (!MFP.Contains( aFace2 )) { + LSF.Remove( itl ); + continue; + } + if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 ))) + break; + itl.Next(); + } + if (itl.More()) { // aFace2 found, remove it from maps + LSF.Remove( itl ); + MFP.Remove(aFace2); + } + else + aFace2.Nullify(); + itl.Initialize( LSF ); + } + + // check that anOrigFace is not same domain with CSF faces it intersects + + const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E + const TopoDS_Shape& origF1 = myImagesFaces.Root(FL.First()); + const TopoDS_Shape& origF2 = myImagesFaces.Root(FL.Last()); + Standard_Boolean sameDom1 = anOrigFace.IsSame( origF1 ); + Standard_Boolean sameDom2 = anOrigFace.IsSame( origF2 ); + if (!(sameDom1 || sameDom2) && myInter3d.HasSameDomainF( anOrigFace )) { + sameDom1 = myInter3d.IsSameDomainF( anOrigFace, origF1); + if (origF1 == origF2) + sameDom2 = sameDom1; + else + myInter3d.IsSameDomainF( anOrigFace, origF2); + } + if (sameDom1 && sameDom2) + continue; + if ((sameDom1 || sameDom2)) { + inside = Partition_Loop3d::IsInside (E, + TopoDS::Face(FL.First()), + TopoDS::Face(FL.Last()), + 1, dot, GoodOri); + if (inside || (dot + Precision::Angular() >= 1.0)) + continue; // E is convex between origF1 and origF2 or they are tangent + } + + + // keep one of found faces + + //face of CSF sharing E + const TopoDS_Shape& aShapeFace = sameDom1 ? FL.Last() : FL.First(); + // analyse aFace1 state + inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace), aFace1, + 1, dot, GoodOri); + if (inside && isSectionE) + { + // aFace1 must be tested with both adjacent faces of CSF + const TopoDS_Shape& aShapeFace2 = sameDom1 ? FL.First() : FL.Last(); + if (aShapeFace2 != aShapeFace) + inside = Partition_Loop3d::IsInside (E, TopoDS::Face(aShapeFace2), aFace1, + 1, dot, GoodOri); + } + + // store internal face + if (inside) + KeepFaces.Append(aFace1); + + else if (!aFace2.IsNull()) + { + if (dot + Precision::Angular() >= 1.0) + { + // aFace2 state is not clear, it will be analysed alone, + // put it back to the maps + MFP.Add( aFace2 ); + LSF.Append( aFace2 ); + } + else + KeepFaces.Append(aFace2); + } + } + } + + // =================================================== + // add not distributed faces connected with KeepFaces + // =================================================== + + // ultimate list of internal faces + TopTools_ListOfShape KeptFaces; + + // add to MFP not split tool faces as well, they may be connected with + // tool faces interfering with theShape + for ( itm.Initialize(myMapTools); itm.More(); itm.Next() ) { + const TopoDS_Shape& aToolFace = itm.Key(); + if (!myImageShape.HasImage(aToolFace)) + MFP.Add (aToolFace); + } + + if (MFP.IsEmpty()) + KeptFaces.Append (KeepFaces); + + while (!KeepFaces.IsEmpty()) + { + // KeepEdges : map of edges of faces kept last time + TopTools_IndexedMapOfShape KeepEdges; + for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) { + TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges); + KeptFaces.Append( itl.Value() ); + } + + KeepFaces.Clear(); + + // keep faces connected with already kept faces by KeepEdges + for ( itm.Initialize(MFP); itm.More(); itm.Next() ) { + const TopoDS_Shape& FP = itm.Key(); + for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape& se = expl.Current(); + if (!MSE.Contains(se) && KeepEdges.Contains(se) ) { + KeepFaces.Append(FP); + MFP.Remove(FP); + break; + } + } + } + } + + // =============================================================== + // here MFP contains faces outer of theShape and those of shapes + // which do not interfere with theShape at all and between which + // there may be those wrapped by theShape and whose faces may be + // needed to be returned as well + // =============================================================== + + Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID); + if (All || isSolid) // All is for sub-result removal + { + // loop on not used faces; checked faces will be removed from MFP + // during the loop + for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) { + const TopoDS_Shape & aFace = itm.Key(); + + // a shape which aFace originates from + TopoDS_Shape anOrigShape = GetOriginalShape( aFace ); + + // find out if all split faces of anOrigShape are not in MFP + // and by the way remove them from MFP + Standard_Boolean isAllOut = Standard_True; + TopoDS_Shape aSplitFaces = anOrigShape; + if (myImageShape.HasImage(anOrigShape)) + aSplitFaces = myImageShape.Image(anOrigShape).First(); + + TopTools_ListOfShape aSplitFaceL; // faces candidate to be kept + for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next()) + { + const TopoDS_Shape & aSpFace = expl.Current(); + // a tool face which became object has image but the whole tool shape has not + if (myImageShape.HasImage( aSpFace )) + { + TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE ); + for ( ; exF.More(); exF.Next() ) + { + aSplitFaceL.Append( exF.Current() ); + if ( ! MFP.Remove( exF.Current() ) && isAllOut ) + // a shared face might be removed from MFP during a prev loop + isAllOut = mySharedFaces.Contains( exF.Current() ); + } + } + else + { + aSplitFaceL.Append( aSpFace ); + if ( ! MFP.Remove( aSpFace ) && isAllOut) + // a shared face might be removed from MFP during a prev loop + isAllOut = mySharedFaces.Contains( aSpFace ); + } + } + itm.Initialize( MFP ); // iterate remaining faces + if ( !isAllOut ) + continue; + + // classify anOrigShape against theShape + if (IsInside (anOrigShape, theShape)) + { + if (isSolid && myClosedShapes.Contains( anOrigShape )) + // to make a special care at solid reconstruction + myWrappingSolid.Add ( theShape ); + + // keep faces of an internal shape anOrigShape + KeptFaces.Append( aSplitFaceL ); + } + } + } + + // ==================================================== + // check if kept faces form a shell without free edges + // ==================================================== + + DMEF.Clear(); // edge - kept faces + MFP.Clear(); // reuse it for wrong faces + if (CheckClosed) { + for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) + TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF); + + Standard_Integer i, nb = DMEF.Extent(); + Standard_Boolean isClosed = Standard_False; + while (!isClosed) { + isClosed = Standard_True; + for (i=1; isClosed && i<=nb; ++i) { + const TopoDS_Shape& E = DMEF.FindKey( i ); + if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) && + ! MSE.Contains( E )) + isClosed = ( DMEF(i).Extent() != 1 ); + } + if (!isClosed) { + const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face + MFP.Add( F ); + // remove bad face from DMEF + for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) { + const TopoDS_Shape& E = expl.Current(); + TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E ); + for (itl.Initialize( FL ); itl.More(); itl.Next() ) { + if ( F.IsSame( itl.Value() )) { + FL.Remove( itl ); + break; + } + } + } + } + } + } + + // ============== + // make a result + // ============== + + TopoDS_Compound C; + // compound of removed internal faces + TopoDS_Compound CNotCl; + + myBuilder.MakeCompound(C); + myBuilder.MakeCompound(CNotCl); + + // add to compounds + for (itl.Initialize(KeptFaces); itl.More(); itl.Next() ) + { + TopoDS_Shape & aIntFace = itl.Value(); + if (! MFP.Contains( aIntFace )) + myBuilder.Add( C, aIntFace); + else + myBuilder.Add( CNotCl, aIntFace); + } + + if (!skipAlreadyAdded && CheckClosed) + { + myInternalFaces.Bind( theShape, C ); + myIntNotClFaces.Bind( theShape, CNotCl ); + } + + return C; +} + +//======================================================================= +//function : MakeShell +//purpose : split S into compound of shells +//======================================================================= + +void Partition_Spliter::MakeShells(const TopoDS_Shape& S, + TopTools_ListOfShape& NS) +{ + Partition_Loop3d ShellMaker; + // get compound of split faces of S + const TopoDS_Shape& FacesComp = myImageShape.Image(S).First(); + ShellMaker.AddConstFaces( FacesComp ); + // add split faces inside S + if (myClosedShapes.Contains( S )) { + TopoDS_Shape InternalFacesComp = FindFacesInside(S, Standard_True); + ShellMaker.AddSectionFaces( InternalFacesComp ); + } + + NS = ShellMaker.MakeShells( myAddedFacesMap ); + + // Add faces added to new shell to myAddedFacesMap: + // avoid rebuilding twice commont part of 2 solids. + TopTools_ListIteratorOfListOfShape itS(NS); + while ( itS.More()) { + TopExp_Explorer expF (itS.Value(), TopAbs_FACE); + for (; expF.More(); expF.Next()) + myAddedFacesMap.Add (expF.Current()); + + itS.Next(); + } +} + +//======================================================================= +//function : findEqual +//purpose : compare edges of EL1 against edges of EL2, +// Result is in EMM binding EL1 edges to list of equal edges. +// Edges are considered equall only if they have same vertices. +// ==True makes consider same edges as equal +// Put in all equal edges +//======================================================================= + +static void findEqual (const TopTools_ListOfShape& EL1, + const TopTools_ListOfShape& EL2, + const Standard_Boolean addSame, + TopTools_DataMapOfShapeListOfShape& EEM, + TopTools_MapOfShape& AllEqMap) +{ + // map vertices to edges for EL2 + TopTools_DataMapOfShapeListOfShape VEM; + TopTools_ListIteratorOfListOfShape itE1, itE2(EL2); + TopoDS_Iterator itV; + TopTools_ListOfShape emptyL; + for (; itE2.More(); itE2.Next()) { + for (itV.Initialize( itE2.Value() ); itV.More(); itV.Next()) { + const TopoDS_Shape& V = itV.Value(); + if (! VEM.IsBound( V ) ) + VEM.Bind( V, emptyL); + VEM( V ).Append( itE2.Value()); + } + } + + gp_Vec D1, D2; + gp_Pnt P; + Standard_Real f,l,u,tol; + Handle(Geom_Curve) C1, C2; + Extrema_ExtPC Extrema; + TopoDS_Vertex V1, V2, V3, V4; + + AllEqMap.Clear(); + + for (itE1.Initialize(EL1); itE1.More(); itE1.Next()) { + const TopoDS_Edge& E1 = TopoDS::Edge( itE1.Value()); + if (BRep_Tool::Degenerated( E1 ) || AllEqMap.Contains (E1)) + continue; + TopExp::Vertices( E1, V1, V2 ); + + if (VEM.IsBound(V1)) + itE2.Initialize( VEM(V1) ); + for (; itE2.More(); itE2.Next()) { + const TopoDS_Edge& E2 = TopoDS::Edge( itE2.Value()); + if (BRep_Tool::Degenerated( E2 ) || AllEqMap.Contains (E2)) + continue; + + if (E1.IsSame(E2)) { + if (!addSame) + continue; + } + else { + TopExp::Vertices( E2, V3, V4); + if (!V2.IsSame(V4) && !V2.IsSame(V3)) + continue; + // E1 and E2 have same vertices + // check D1 at end points. + C2 = BRep_Tool::Curve( E2, f,l); + C1 = BRep_Tool::Curve( E1, f,l); + u = BRep_Tool::Parameter(V1,E1); + C1->D1(u, P, D1); + u = BRep_Tool::Parameter(V1.IsSame(V3) ? V3 : V4, E2); + C2->D1(u, P, D2); + D1.Normalize(); D2.Normalize(); + if (Abs(D1*D2) + Precision::Angular() < 1.0) + continue; + if (! V1.IsSame(V2)) { + u = BRep_Tool::Parameter(V2,E1); + C1->D1(u, P, D1); + u = BRep_Tool::Parameter(V2.IsSame(V3) ? V3 : V4, E2); + C2->D1(u, P, D2); + D1.Normalize(); D2.Normalize(); + if (Abs(D1*D2) + Precision::Angular() < 1.0) + continue; + } + // check distance at a couple of internal points + tol = Max(BRep_Tool::Tolerance(E1), + BRep_Tool::Tolerance(E2)); + GeomAdaptor_Curve AC1(C1); + Extrema.Initialize(AC1,f,l); + Standard_Boolean ok = Standard_True, hasMin = Standard_False; + BRep_Tool::Range( E2, f, l); + Standard_Integer i=1, nbi=3; + for (; iValue( f+(l-f)*i/nbi )); + Standard_Integer j=1, nbj=Extrema.NbExt(); + for (; j<=nbj && ok; ++j) { + if (Extrema.IsMin(j)) { + hasMin = Standard_True; + ok = Extrema.Value(j) <= tol; // V6.3 + // ok = Extrema.SquareDistance(j) <= tol; // V6.5 + } + } + } + if ( !hasMin || !ok) + continue; + } + // bind E2 to E1 in EEM + if (!EEM.IsBound(E1)) { + EEM.Bind (E1, emptyL); + AllEqMap.Add (E1); + } + EEM(E1).Append(E2); + AllEqMap.Add (E2); + } + } +} + +//======================================================================= +//function : MakeFaces +//purpose : split faces of S, return compound of new faces +//======================================================================= + +TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S) +{ + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + TopTools_ListIteratorOfListOfShape itl, itNE; + + TopExp_Explorer exp(S,TopAbs_FACE); + for (; exp.More(); exp.Next()) { + + const TopoDS_Face& F = TopoDS::Face(exp.Current()); + + TopTools_ListOfShape LNF; + + if (myImagesFaces.HasImage( F )) { + myImagesFaces.LastImage( F, LNF ); + TopAbs_Orientation oriF = F.Orientation(); + for ( itl.Initialize( LNF ); itl.More(); itl.Next()) + itl.Value().Orientation( oriF ); + } + else { + + Partition_Loop2d loops; + loops.Init(F); + + TopTools_IndexedMapOfShape EM; + TopExp::MapShapes( F, TopAbs_EDGE, EM); + + TopTools_MapOfShape AddedEqualM, EqualSeamM; + Standard_Boolean needRebuild = Standard_False; + + // add splits to loops + + // LE: old edges + new not splitted edges + const TopTools_ListOfShape& LE = myAsDes->Descendant(F); + for (itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( itl.Value() ); + + Standard_Boolean isSectionE = myInter3d.IsSectionEdge(E); + Standard_Boolean isNewE = !EM.Contains( E ); + + // LSE: list of split edges + TopTools_ListOfShape LSE; + myImagesEdges.LastImage(E,LSE); // splits of E or E itself + + for (itNE.Initialize(LSE); itNE.More(); itNE.Next()) { + + TopoDS_Edge NE = TopoDS::Edge( itNE.Value() ); + Standard_Boolean isSameE = NE.IsSame ( E ); + + if ( isNewE || isSectionE || !isSameE) { + if (AddedEqualM.Contains( NE )) { + // a seam must be twice in a loop + if (!BRep_Tool::IsClosed( E, F ) || !EqualSeamM.Add( NE )) + continue; + } + + if (isNewE) { + if (isSectionE) { + if ( ! myInter3d.IsSplitOn( NE, E, F) ) + continue; + } + else { + TopoDS_Vertex V1,V2; + TopExp::Vertices(NE,V1,V2); + const TopTools_ListOfShape& EL1 = myAsDes->Ascendant(V1); + const TopTools_ListOfShape& EL2 = myAsDes->Ascendant(V2); + if ( EL1.Extent() < 2 && EL2.Extent() < 2 ) + continue; + } + } + else { + NE.Orientation( E.Orientation()); + if (!isSameE) { + // orient NE because it may be a split of other edge + Standard_Real f,l,u; + Handle(Geom_Curve) C3d = BRep_Tool::Curve( E,f,l ); + Handle(Geom_Curve) NC3d = BRep_Tool::Curve( NE,f,l); + if ( C3d != NC3d) { + gp_Vec D1, ND1; gp_Pnt P; + TopoDS_Vertex V = TopExp::FirstVertex(NE); + u = BRep_Tool::Parameter(V,NE); + NC3d->D1 (u, P, ND1); + u = BRep_Tool::Parameter(V,E); + C3d ->D1 (u, P, D1); + if (ND1.Dot(D1) < 0) + NE.Reverse(); + } + } + } + if (myEqualEdges.Contains( NE )) + AddedEqualM.Add( NE ); + + needRebuild = Standard_True; + } + + if (isNewE || isSectionE) + myNewSection.Add( NE ); + + if (isNewE) + loops.AddSectionEdge(NE); + else + loops.AddConstEdge(NE); + } + } + + //------------------- + // Build the faces. + //------------------- + + if (needRebuild) { + + loops.Perform(); + loops.WiresToFaces(myImagesEdges); + + LNF = loops.NewFaces(); + + myImagesFaces.Bind(F,LNF); + + // replace the result faces that have already been built + // during same domain faces reconstruction done earlier + if (myInter3d.HasSameDomainF( F )) + { + // build map edge to same domain faces: EFM + TopTools_IndexedDataMapOfShapeListOfShape EFM; + TopTools_MapOfShape SDFM; // avoid doubling + itl.Initialize( myInter3d.SameDomain( F )); + for (; itl.More(); itl.Next()) { + if ( !myImagesFaces.HasImage( itl.Value() )) + continue; + // loop on splits of a SD face + TopTools_ListIteratorOfListOfShape itNF; + itNF.Initialize (myImagesFaces.Image( itl.Value() )); + for ( ; itNF.More(); itNF.Next()) { + TopoDS_Shape SDF = itNF.Value(); + if (myImagesFaces.HasImage( SDF )) // already replaced + SDF = myImagesFaces.Image( SDF ).First(); + if (SDFM.Add (SDF)) + TopExp::MapShapesAndAncestors(SDF, TopAbs_EDGE, TopAbs_FACE, EFM); + } + } + // do replace faces in the LNF + TopTools_ListOfShape LOF; + if ( !EFM.IsEmpty() ) + itl.Initialize( LNF ); + while (itl.More()) { + const TopoDS_Shape& NF = itl.Value(); + TopExp_Explorer expE ( NF, TopAbs_EDGE ); + const TopoDS_Edge& E = TopoDS::Edge (expE.Current()); + if (EFM.Contains( E )) { + const TopTools_ListOfShape& SDFL = EFM.FindFromKey( E ); + TopoDS_Shape SDF = SDFL.First(); + Standard_Boolean GoodOri; + Standard_Real dot; + Partition_Loop3d::IsInside (E, TopoDS::Face(NF), TopoDS::Face(SDF), + 1, dot, GoodOri); + if (dot < 0) + { + // NF and SDF are on different side of E + if (SDFL.Extent() == 1) { + itl.Next(); + continue; + } + else + SDF = SDFL.Last(); // next face must be on the same side + } + gp_Vec V1 = Partition_Loop3d::Normal( E, TopoDS::Face( NF )); + gp_Vec V2 = Partition_Loop3d::Normal( E, TopoDS::Face( SDF )); + if (V1*V2 < 0) + SDF.Reverse(); + + if (!myImagesFaces.HasImage( NF )) + myImagesFaces.Bind( NF, SDF ); + + // mySharedFaces is used in FindFacesInside() + mySharedFaces.Add( SDF ); + + LOF.Prepend ( SDF ); + LNF.Remove (itl); + } + else + itl.Next(); + } + + LNF.Append (LOF); + } + } // if (needRebuild) + + else { + LNF.Append( F ); + myImagesFaces.Bind(F,LNF); + } + } // if (myImagesFaces.HasImage( F )) + + // fill the resulting compound + for (itl.Initialize(LNF); itl.More(); itl.Next()) + myBuilder.Add ( C, itl.Value()); + + } // loop on faces of S + + return C; +} + + +//======================================================================= +//function : Tri +//purpose : +//======================================================================= + +static void Tri(const TopoDS_Edge& E, + TopTools_SequenceOfShape& Seq, + const Partition_Inter3d & theInter3d) +{ + Standard_Boolean Invert = Standard_True; + Standard_Real U1,U2; + TopoDS_Vertex V1,V2; + + while (Invert) { + Invert = Standard_False; + for ( Standard_Integer i = 1; i < Seq.Length(); i++) { + + V1 = TopoDS::Vertex(Seq.Value(i)); + V2 = TopoDS::Vertex(Seq.Value(i+1)); + + V1.Orientation(TopAbs_INTERNAL); + V2.Orientation(TopAbs_INTERNAL); + + U1 = BRep_Tool::Parameter(V1,E); + U2 = BRep_Tool::Parameter(V2,E); + + if (IsEqual(U1,U2)) { + if (theInter3d.ReplaceSameDomainV( V1, E ).IsSame( V1 )) + Seq.Remove(i+1); // remove V2 + else + Seq.Remove(i); + i--; + continue; + } + if (U2 < U1) { + Seq.Exchange(i,i+1); + Invert = Standard_True; + } + } + } +} + +//======================================================================= +//function : MakeEdges +//purpose : cut E by vertices VOnE, return list of new edges NE +//======================================================================= + +void Partition_Spliter::MakeEdges (const TopoDS_Edge& E, + const TopTools_ListOfShape& VOnE, + TopTools_ListOfShape& NE ) const +{ + TopoDS_Edge WE = E; + WE.Orientation(TopAbs_FORWARD); + + Standard_Real U1,U2, f, l; + TopoDS_Vertex V1,V2,VF,VL; + + BRep_Tool::Range(WE,f,l); + TopExp::Vertices(WE,VF,VL); + + if (VOnE.Extent() < 3) { // do not rebuild not cut edge + if (( VF.IsSame( VOnE.First() ) && VL.IsSame( VOnE.Last() )) || + VL.IsSame( VOnE.First() ) && VF.IsSame( VOnE.Last() ) ) { + NE.Append( E ); + return; + } + } + + TopTools_SequenceOfShape SV; + TopTools_ListIteratorOfListOfShape itv(VOnE); + TopTools_MapOfOrientedShape VM( VOnE.Extent() ); + for (; itv.More(); itv.Next()) + if ( VM.Add( itv.Value() )) + SV.Append(itv.Value()); + + Tri( WE, SV, myInter3d ); + + if (SV.Length() < 3) { // do not rebuild not cut edge + if (( VF.IsSame( SV.First() ) && VL.IsSame( SV.Last() )) || + VL.IsSame( SV.First() ) && VF.IsSame( SV.Last() ) ) { + NE.Append( E ); + return; + } + } + + Standard_Integer iVer, NbVer = SV.Length(); + + + //---------------------------------------------------------------- + // Construction of the new edges . + //---------------------------------------------------------------- + + if (VF.IsSame(VL)) { // closed edge + if (NbVer==1) + SV.Append( SV.First() ); + else if (!SV.First().IsSame(SV.Last())) { + Standard_Boolean isFirst=0; + Standard_Real minDU = 1.e10; + TopoDS_Vertex endV = Partition_Inter2d::FindEndVertex(VOnE, f,l, E, isFirst,minDU); + if (endV.IsSame(SV.First())) + SV.Append(endV); + else if (endV.IsSame(SV.Last())) + SV.Prepend(endV); + else + MESSAGE ("END VERTEX IS IN SEQUNCE MIDDLE"); + } + NbVer = SV.Length(); + } + + for (iVer=1; iVer < NbVer; iVer++) { + V1 = TopoDS::Vertex(SV(iVer)); + V2 = TopoDS::Vertex(SV(iVer+1)); + + TopoDS_Shape NewEdge = WE.EmptyCopied(); + V1.Orientation(TopAbs_FORWARD); + myBuilder.Add (NewEdge,V1); + V2.Orientation(TopAbs_REVERSED); + myBuilder.Add (NewEdge,V2); + + if (iVer==1) + U1 = f; + else { + V1.Orientation(TopAbs_INTERNAL); + U1=BRep_Tool::Parameter(V1,WE); + } + if (iVer+1 == NbVer) + U2 = l; + else { + V2.Orientation(TopAbs_INTERNAL); + U2=BRep_Tool::Parameter(V2,WE); + } + if (Abs(U1-U2) <= Precision::PConfusion()) { + MESSAGE( "MakeEdges(), EQUAL PARAMETERS OF DIFFERENT VERTICES"); + continue; + } + TopoDS_Edge EE=TopoDS::Edge(NewEdge); + myBuilder.Range (EE,U1,U2); + + TopoDS_Edge NEdge = TopoDS::Edge(NewEdge); + myBuilder.SameParameter(NEdge,Standard_False); + + Standard_Real tol = 1.0e-2; + Standard_Boolean flag = BRep_Tool::SameParameter(NEdge); + if (!flag) { + BRepLib::SameParameter(NEdge,tol); + } + NE.Append(NEdge.Oriented(E.Orientation())); + } +} + +//======================================================================= +//function : MergeEqualEdges +//purpose : find equal edges, choose ones to keep and make +// them have pcurves on all faces they are shared by +//======================================================================= + +void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE) +{ + // find equal edges + // map: edge - equal edges + TopTools_DataMapOfShapeListOfShape EEM( LSE.Extent() ); + findEqual (LSE, LSE, 0, EEM, myEqualEdges); + + TopTools_ListOfShape EEL; // list of equal edges + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itM (EEM); + for ( ; itM.More(); itM.Next()) { + EEL = itM.Value(); + EEL.Append( itM.Key() ); + + // choose an edge to keep, section edges have priority + TopoDS_Edge EKeep; + TopTools_ListIteratorOfListOfShape itEE (EEL); + for (; itEE.More(); itEE.Next()) { + EKeep = TopoDS::Edge( itEE.Value() ); + const TopoDS_Edge& EKeepOrig = TopoDS::Edge( myImagesEdges.Root( EKeep )); + if (myInter3d.IsSectionEdge( EKeepOrig )) + break; + } + + // update edge images and build pcurves + Standard_Real f,l, tol; + for (itEE.Initialize (EEL); itEE.More(); itEE.Next()) { + const TopoDS_Edge& E = TopoDS::Edge( itEE.Value() ); + if ( E.IsSame( EKeep )) + continue; + + // 1. build pcurves of the kept edge on faces where replaced edges exist + const TopoDS_Edge& EReplOrig = TopoDS::Edge( myImagesEdges.Root( E )); + TopTools_ListOfShape FL; + FL = myAsDes->Ascendant( EReplOrig ); + Standard_Integer iFace, iFirstSectionFace = FL.Extent() + 1; + // add faces where the replaced edge is a section edge + if (myInter3d.IsSectionEdge( EReplOrig )) { + TopTools_ListIteratorOfListOfShape seIt; + seIt.Initialize( myInter3d.SectionEdgeFaces ( EReplOrig )); + for ( ; seIt.More(); seIt.Next()) + FL.Append( seIt.Value() ); + } + // loop on faces + TopTools_ListIteratorOfListOfShape itF (FL); + for ( iFace = 1 ; itF.More(); itF.Next(), ++iFace ) { + const TopoDS_Face& F = TopoDS::Face( itF.Value()); + + Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( EKeep, F, f,l); + if (pc.IsNull()) { + Handle(Geom_Curve) C3d = BRep_Tool::Curve( EKeep, f, l); + C3d = new Geom_TrimmedCurve( C3d, f,l); + pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol); + if (pc.IsNull()) { + MESSAGE (" CANT BUILD PCURVE "); + } + myBuilder.UpdateEdge( EKeep, pc, F, tol); + } + + if (iFace >= iFirstSectionFace || + !BRep_Tool::IsClosed( EReplOrig, F )) + continue; + + // build the second pcurve for a seam + TopoDS_Vertex V = TopExp::FirstVertex( EKeep ); + Standard_Real Ukeep = BRep_Tool::Parameter( V, EKeep ); + Standard_Real Urepl = BRep_Tool::Parameter( V, E ); + + TopoDS_Edge EReplRev = E; + EReplRev.Reverse(); + Handle(Geom2d_Curve) pcRepl1 = BRep_Tool::CurveOnSurface( E, F, f,l); + Handle(Geom2d_Curve) pcRepl2 = BRep_Tool::CurveOnSurface( EReplRev, F, f,l); + + gp_Pnt2d p1r, p2r, pk; + p1r = pcRepl1->Value( Urepl ); + p2r = pcRepl2->Value( Urepl ); + pk = pc->Value( Ukeep ); + + // suppose that pk is equal to either p1r or p2r + Standard_Boolean isUPeriod = + ( Abs( p1r.X() - p2r.X() ) > Abs( p1r.Y() - p2r.Y() )); + Standard_Boolean is1Equal; + if (isUPeriod) + is1Equal = ( Abs( p1r.X() - pk.X() ) < Abs( p2r.X() - pk.X() )); + else + is1Equal = ( Abs( p1r.Y() - pk.Y() ) < Abs( p2r.Y() - pk.Y() )); + + Handle(Geom2d_Curve) pc2 = Handle(Geom2d_Curve)::DownCast + ( pc->Translated( pk, is1Equal ? p2r : p1r ) ); + + if (E.Orientation() == TopAbs_REVERSED) + is1Equal = !is1Equal; + + if (is1Equal) + myBuilder.UpdateEdge( EKeep, pc, pc2, F, tol); + else + myBuilder.UpdateEdge( EKeep, pc2, pc, F, tol); + + } // loop on a Faces where a replaced edge exists + + + // 2. update edge images according to replacement + if (myImagesEdges.HasImage( E )) + myImagesEdges.Remove( E ); + myImagesEdges.Bind( E, EKeep ); + + } // loop on a list of equal edges EEL + } // loop on a map of equal edges EEM +} + +//======================================================================= +//function : KeepShapesInside +//purpose : remove shapes that are outside of S from resul +//======================================================================= + +void Partition_Spliter::KeepShapesInside (const TopoDS_Shape& S) +{ + TopoDS_Iterator it; + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + for (it.Initialize( S ); it.More(); it.Next()) + KeepShapesInside( it.Value()); + return; + } + + Standard_Boolean isTool = Standard_False; + if (!myImageShape.HasImage( S )) { + isTool = CheckTool( S ); + if (!isTool) return; + } + + // build map of internal faces + TopTools_IndexedMapOfShape MIF; + TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True); + TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF ); + + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + TopAbs_ShapeEnum anInternalShapeType = TopAbs_SHAPE; + if (!MIF.IsEmpty()) + { + // leave in the result only those shapes having a face in MIF + for (it.Initialize( myShape ); it.More(); it.Next()) { + const TopoDS_Shape & aResShape = it.Value(); + TopExp_Explorer expResF( aResShape, TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) { + if ( MIF.Contains( expResF.Current())) { + myBuilder.Add( C, aResShape ); + if (aResShape.ShapeType() < anInternalShapeType) + anInternalShapeType = aResShape.ShapeType(); + break; + } + } + } + } + + // may be S was not split by internal faces then it is missing + // in myShape, add it + if (!isTool && + (anInternalShapeType > TopAbs_SOLID || S.ShapeType() > TopAbs_SOLID)) + { + TopTools_IndexedMapOfShape MSF; // map of split faces of S + TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MSF); + + // find a shape having all faces in MSF + for (it.Initialize( myShape ); it.More(); it.Next()) { + TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) { + if (! MSF.Contains( expResF.Current())) + break; + } + if (! expResF.More()) { + myBuilder.Add( C, it.Value() ); + break; + } + } + } + + myShape = C; +} + +//======================================================================= +//function : RemoveShapesInside +//purpose : remove shapes that are inside S from resul +//======================================================================= + +void Partition_Spliter::RemoveShapesInside (const TopoDS_Shape& S) +{ + TopoDS_Iterator it; + if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid + for (it.Initialize( S ); it.More(); it.Next()) + RemoveShapesInside( it.Value()); + return; + } + Standard_Boolean isTool = Standard_False; + if (!myImageShape.HasImage( S )) { + isTool = CheckTool( S ); + if (!isTool) return; + } + + TopoDS_Shape IntFacesComp = FindFacesInside( S, Standard_False, Standard_True); + TopTools_IndexedMapOfShape MIF; // map of internal faces + TopExp::MapShapes( IntFacesComp, TopAbs_FACE, MIF); + + if (MIF.IsEmpty()) return; + + // add to MIF split faces of S + if (myImageShape.HasImage(S)) + TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF); + + // leave in the result only those shapes not having all face in MIF + + TopoDS_Compound C; + myBuilder.MakeCompound(C); + + // RMF : faces of removed shapes that encounter once + TopTools_MapOfShape RFM; + + for (it.Initialize( myShape ); it.More(); it.Next()) { + + TopExp_Explorer expResF( it.Value(), TopAbs_FACE ); + for (; expResF.More(); expResF.Next()) + if (!MIF.Contains( expResF.Current())) + break; + + if (expResF.More()) + // add shape to result + myBuilder.Add( C, it.Value() ); + else + // add faces of a removed shape to RFM + for (expResF.ReInit(); expResF.More(); expResF.Next()) { + const TopoDS_Shape& F = expResF.Current(); + if ( ! RFM.Remove ( F )) + RFM.Add( F ); + } + } + + if (!isTool) { + + // rebuild S, it must remain in the result + + Standard_Boolean isClosed = Standard_False; + switch (S.ShapeType()) { + case TopAbs_SOLID : + isClosed = Standard_True; break; + case TopAbs_SHELL: { + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF); + Standard_Integer i; + for (i=1; isClosed && i<=MEF.Extent(); ++i) + isClosed = ( MEF(i).Extent() != 1 ); + break; + } + default: + isClosed = Standard_False; + } + if (isClosed) { + + // add to a new shape external faces of removed shapes, ie those in RFM + + TopoDS_Shell Shell; + myBuilder.MakeShell( Shell ); + + // exclude redundant internal face with edges encounterd only once + TopTools_IndexedDataMapOfShapeListOfShape MEF; + TopTools_MapIteratorOfMapOfShape itF (RFM); + for ( ; itF.More(); itF.Next()) + TopExp::MapShapesAndAncestors(itF.Key(), TopAbs_EDGE, TopAbs_FACE, MEF); + + // add only faces forming a closed shell + for (itF.Reset() ; itF.More(); itF.Next()) + { + TopExp_Explorer expE (itF.Key(), TopAbs_EDGE); + for (; expE.More(); expE.Next()) + if (MEF.FindFromKey(expE.Current()).Extent() == 1) + break; + if (!expE.More()) + myBuilder.Add( Shell, itF.Key()); + } + + if (S.ShapeType() == TopAbs_SOLID) { + TopoDS_Solid Solid; + myBuilder.MakeSolid( Solid ); + myBuilder.Add (Solid, Shell); + myBuilder.Add (C, Solid); + } + else + myBuilder.Add (C, Shell); + } + else { + if (myImageShape.HasImage( S )) { + for (it.Initialize( myImageShape.Image(S).First()); it.More(); it.Next()) + myBuilder.Add (C, it.Value()); + } + } + } + + myShape = C; +} + +//======================================================================= +//function : CheckTool +//purpose : Return True if is a tool shape. Prepare tool +// faces of for the search of internal faces. +//======================================================================= + +Standard_Boolean Partition_Spliter::CheckTool(const TopoDS_Shape& S) +{ + // suppose S has not an image + + Standard_Boolean isTool = Standard_False; + TopoDS_Compound C; + myBuilder.MakeCompound( C ); + + TopExp_Explorer expF( S, TopAbs_FACE); + for (; expF.More(); expF.Next()) { + + const TopoDS_Face& F = TopoDS::Face( expF.Current() ); + if (myMapTools.Contains( F )) + isTool = Standard_True; + else + continue; + + if (myImagesFaces.HasImage( F )) { + // F has been reconstructed + TopAbs_Orientation Fori = F.Orientation(); + TopTools_ListOfShape LNF; + myImagesFaces.LastImage( F, LNF); + TopTools_ListIteratorOfListOfShape itF (LNF); + for ( ; itF.More(); itF.Next()) + myBuilder.Add( C, itF.Value().Oriented(Fori) ); + continue; + } + + Standard_Boolean hasSectionE = myInter3d.HasSectionEdge( F ); + Standard_Boolean hasNewE = myAsDes->HasDescendant( F ); + if (!hasSectionE && !hasNewE) + { + // F intersects nothing + myBuilder.Add( C, F ); + continue; + } + + // make an image for F + + TopoDS_Face NF = F; + NF.Orientation(TopAbs_FORWARD); + NF = TopoDS::Face( NF.EmptyCopied() ); // make a copy + TopoDS_Wire NW; + myBuilder.MakeWire( NW ); + + // add edges, as less as possible + TopTools_ListOfShape NEL; + TopTools_ListIteratorOfListOfShape itNE; + if (hasSectionE) { + // add section edges + TopExp_Explorer expE; + for ( ; expE.More(); expE.Next()) { + if (! myImagesEdges.HasImage( expE.Current() )) + continue; + myImagesEdges.LastImage( expE.Current(), NEL ); + for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) + myBuilder.Add ( NW, itNE.Value()); + } + } + if (hasNewE) { + // add new adges + NEL = myAsDes->Descendant( F ); + for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) { + TopTools_ListOfShape SEL; // splits + myImagesEdges.LastImage( itNE.Value(), SEL ); + TopTools_ListIteratorOfListOfShape itSE (SEL); + for ( ; itSE.More(); itSE.Next()) + myBuilder.Add ( NW, itSE.Value()); + } + } + myBuilder.Add( NF, NW ); + myBuilder.Add (C, NF); + + NF.Orientation( F.Orientation() ); // NF is most probably invalid + myImagesFaces.Bind (F, NF); + } + if (isTool) + myImageShape.Bind (S, C); + + return isTool; +} + +//======================================================================= +//function : IsInside +//purpose : Return True if the first vertex of S1 inside S2. +// If S1.IsNull(), check infinite point against S2. +//======================================================================= + +Standard_Boolean Partition_Spliter::IsInside (const TopoDS_Shape& theS1, + const TopoDS_Shape& theS2) +{ + BRepClass3d_SolidClassifier aClassifier( theS2 ); + + TopExp_Explorer expl( theS1, TopAbs_VERTEX ); + if (!expl.More()) + aClassifier.PerformInfinitePoint( ::RealSmall()); + else + { + const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() ); + aClassifier.Perform (BRep_Tool::Pnt( aVertex ), + BRep_Tool::Tolerance( aVertex )); + } + + return ( aClassifier.State() == TopAbs_IN ); +} + +//======================================================================= +//function : GetOriginalShape +//purpose : Return the shape aShape originates from. aShape +// should be a face or more complex result shape +//======================================================================= + +TopoDS_Shape Partition_Spliter::GetOriginalShape(const TopoDS_Shape& theShape) const +{ + TopoDS_Shape anOrigShape; + + TopExp_Explorer expl( theShape, TopAbs_FACE); + if (expl.More()) + { + + TopoDS_Shape aFace = expl.Current(); + if (myImagesFaces.IsImage( aFace )) + aFace = myImagesFaces.Root( aFace ); + anOrigShape = myFaceShapeMap.Find( aFace ); + } + return anOrigShape; +} + +//======================================================================= +//function : FindToolsToReconstruct +//purpose : find and store as objects tools which interfere +// with solids or are inside solids without +// an interference +//======================================================================= + +void Partition_Spliter::FindToolsToReconstruct() +{ + if (myMapTools.IsEmpty()) + return; + + Standard_Integer nbFoundTools = 0; + + // build edge - face map in order to detect interference with section edges + TopTools_IndexedDataMapOfShapeListOfShape EFM; + TopTools_MapIteratorOfMapOfShape aMapIt; + for (aMapIt.Initialize(myMapTools); aMapIt.More(); aMapIt.Next()) + TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM); + for (aMapIt.Initialize(myMapFaces); aMapIt.More(); aMapIt.Next()) + TopExp::MapShapesAndAncestors( aMapIt.Key(), TopAbs_EDGE, TopAbs_FACE, EFM); + + TopTools_MapOfShape aCurrentSolids, aCheckedShapes; + + // faces cut by new edges + TopTools_MapOfShape & aSectionFaces = myInter3d.TouchedFaces(); + + // keep solids interfering with each other in aCurrentSolids map + // and add tool faces intersecting solids as object shapes + + TopTools_ListIteratorOfListOfShape itS, itF, itCF, itE; + for (itS.Initialize( myListShapes ); itS.More(); itS.Next()) { + TopExp_Explorer expSo (itS.Value(), TopAbs_SOLID); + for (; expSo.More(); expSo.Next()) { + + // check if a solid has been already processed + const TopoDS_Shape & aSo = expSo.Current(); + if (!aCheckedShapes.Add( aSo )) + continue; + aCurrentSolids.Add( aSo ); + + // faces to check + TopTools_ListOfShape aFacesToCheck; + TopExp_Explorer exp( aSo, TopAbs_FACE ); + for ( ; exp.More(); exp.Next()) + aFacesToCheck.Append ( exp.Current()); + + // add other shapes interefering with a solid. + // iterate faces to check while appending new ones + for (itCF.Initialize (aFacesToCheck) ; itCF.More(); itCF.Next()) + { + const TopoDS_Shape& aCheckFace = itCF.Value(); +// if (!aCheckedShapes.Add( aCheckFace )) +// continue; + + // find faces interfering with aCheckFace + TopTools_ListOfShape anIntFaces; + + // ** 1. faces intersecting aCheckFace with creation of new edges on it + if ( myAsDes->HasDescendant( aCheckFace )) + { + // new edges on aCheckFace + const TopTools_ListOfShape& NEL = myAsDes->Descendant( aCheckFace ); + for (itE.Initialize( NEL); itE.More(); itE.Next()) + { + const TopoDS_Shape & aNewEdge = itE.Value(); + if (!aCheckedShapes.Add( aNewEdge )) + continue; + + // faces interfering by aNewEdge + itF.Initialize (myAsDes->Ascendant( aNewEdge )); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + + // ** 2. faces having section edge aNewEdge on aFacesToCheck + if (EFM.Contains( aNewEdge)) + { + itF.Initialize ( EFM.FindFromKey (itE.Value())); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + } + } + } + + // ** 3. faces cut by edges of aCheckFace + TopExp_Explorer expE (aCheckFace, TopAbs_EDGE); + for ( ; expE.More(); expE.Next()) + { + const TopoDS_Shape & aCheckEdge = expE.Current(); + if (aCheckedShapes.Add( aCheckEdge ) && + myInter3d.IsSectionEdge( TopoDS::Edge( aCheckEdge ))) + { + itF.Initialize( myInter3d.SectionEdgeFaces( TopoDS::Edge( aCheckEdge ))); + for (; itF.More(); itF.Next()) + if (aCheckFace != itF.Value()) + anIntFaces.Append( itF.Value() ); + } + } + + // process faces interfering with aCheckFace and shapes they + // belong to + for (itF.Initialize (anIntFaces); itF.More(); itF.Next()) + { + const TopoDS_Shape & F = itF.Value(); + if (! aCheckedShapes.Add( F )) + continue; + + Standard_Boolean isTool = myMapTools.Contains( F ); + if (isTool && + myFaceShapeMap( aCheckFace ).ShapeType() == TopAbs_SOLID ) + { + // a tool interfering with a solid + if (aSectionFaces.Contains( F )) + AddShape( F ); + ++ nbFoundTools; + if (nbFoundTools == myMapTools.Extent()) + return; + } + + const TopoDS_Shape & S = myFaceShapeMap( F ); + if (aCheckedShapes.Add( S )) + { + // a new shape interefering with aCurrentSolids is found + if (!isTool && S.ShapeType() == TopAbs_SOLID) + aCurrentSolids.Add ( S ); + // add faces to aFacesToCheck list + for ( exp.Init( S, TopAbs_FACE ); exp.More(); exp.Next()) + aFacesToCheck.Append ( exp.Current() ); + } + } + } // loop on aFacesToCheck + + // Here aCurrentSolids contains all solids interfering with each other. + // aCheckedShapes contains all faces belonging to shapes included + // in or interfering with aCurrentSolids or previously checked solids. + // Test if tool faces that do not interefere with other shapes are + // wrapped by any of aCurrentSolids + + TopTools_MapIteratorOfMapOfShape aSolidIt (aCurrentSolids); + for ( ; aSolidIt.More(); aSolidIt.Next()) + { + const TopoDS_Shape & aSolid = aSolidIt.Key(); + TopTools_MapOfShape aCheckedTools( myMapTools.Extent() ); + + TopTools_MapIteratorOfMapOfShape aToolIt (myMapTools); + for ( ; aToolIt.More(); aToolIt.Next()) + { + const TopoDS_Shape & aToolFace = aToolIt.Key(); + if (aCheckedShapes.Contains( aToolFace ) || // already found + aCheckedTools.Contains( aToolFace )) // checked against aSolid + continue; + + const TopoDS_Shape & aToolShape = myFaceShapeMap( aToolFace ); + TopExp_Explorer aToolFaceIt( aToolShape, TopAbs_FACE ); + + Standard_Boolean isInside = IsInside( aToolShape, aSolid ); + for ( ; aToolFaceIt.More(); aToolFaceIt.Next() ) + { + const TopoDS_Shape & aTool = aToolFaceIt.Current(); + aCheckedTools.Add( aTool ); + if (isInside) + { + if (aSectionFaces.Contains( aTool )) + AddShape( aTool ); + ++ nbFoundTools; + if (nbFoundTools == myMapTools.Extent()) + return; + aCheckedShapes.Add( aTool ); + } + } + } + } + + } // loop on solid shapes + } +} + +#endif diff --git a/libsrc/occ/Partition_Spliter.hxx b/libsrc/occ/Partition_Spliter.hxx new file mode 100644 index 00000000..f29917a3 --- /dev/null +++ b/libsrc/occ/Partition_Spliter.hxx @@ -0,0 +1,150 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 CEA/DEN, EDF R&D +// +// +// +// File : Partition_Spliter.hxx +// Module : GEOM + +#ifndef _Partition_Spliter_HeaderFile +#define _Partition_Spliter_HeaderFile + +#ifndef _TopAbs_ShapeEnum_HeaderFile +#include +#endif +#ifndef _TopoDS_Compound_HeaderFile +#include +#endif +#ifndef _BRep_Builder_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_MapOfShape_HeaderFile +#include +#endif +#ifndef _TopTools_DataMapOfShapeShape_HeaderFile +#include +#endif +#ifndef _Handle_BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _BRepAlgo_Image_HeaderFile +#include +#endif +#ifndef _Partition_Inter3d_HeaderFile +#include "Partition_Inter3d.hxx" +#endif +#ifndef _TopTools_MapOfOrientedShape_HeaderFile +#include +#endif +#ifndef _Standard_Boolean_HeaderFile +#include +#endif +class BRepAlgo_AsDes; +class TopoDS_Shape; +class TopTools_ListOfShape; +class TopoDS_Edge; + + +#ifndef _Standard_HeaderFile +#include +#endif +#ifndef _Standard_Macro_HeaderFile +#include +#endif + +class Partition_Spliter { + +public: + + void* operator new(size_t,void* anAddress) + { + return anAddress; + } + void* operator new(size_t size) + { + return Standard::Allocate(size); + } + void operator delete(void *anAddress) + { + if (anAddress) Standard::Free((Standard_Address&)anAddress); + } + // Methods PUBLIC + // + Partition_Spliter(); + void AddShape(const TopoDS_Shape& S) ; + void AddTool(const TopoDS_Shape& S) ; + void Compute(const TopAbs_ShapeEnum Limit = TopAbs_SHAPE) ; + void KeepShapesInside(const TopoDS_Shape& S) ; + void RemoveShapesInside(const TopoDS_Shape& S) ; + TopoDS_Shape Shape() const; + void Clear() ; + + + + + +protected: + + // Methods PROTECTED + // + + + // Fields PROTECTED + // + + +private: + + // Methods PRIVATE + // + void MakeSolids(const TopoDS_Shape& Solid,TopTools_ListOfShape& Shells) ; + void MakeShells(const TopoDS_Shape& S,TopTools_ListOfShape& NS) ; + TopoDS_Shape MakeFaces(const TopoDS_Shape& S) ; + void MakeEdges(const TopoDS_Edge& E,const TopTools_ListOfShape& VOnE,TopTools_ListOfShape& NE) const; + TopoDS_Shape FindFacesInside(const TopoDS_Shape& S,const Standard_Boolean CheckClosed = Standard_False,const Standard_Boolean All = Standard_False) ; + Standard_Boolean CheckTool(const TopoDS_Shape& S) ; + void MergeEqualEdges(const TopTools_ListOfShape& LE) ; + static Standard_Boolean IsInside(const TopoDS_Shape& S1,const TopoDS_Shape& S2) ; + TopoDS_Shape GetOriginalShape(const TopoDS_Shape& aShape) const; + void FindToolsToReconstruct() ; + + + // Fields PRIVATE + // + TopAbs_ShapeEnum myDoneStep; + TopoDS_Compound myShape; + BRep_Builder myBuilder; + TopTools_ListOfShape myListShapes; + TopTools_MapOfShape myMapFaces; + TopTools_MapOfShape myMapTools; + TopTools_MapOfShape myEqualEdges; + TopTools_MapOfShape myNewSection; + TopTools_MapOfShape myClosedShapes; + TopTools_MapOfShape mySharedFaces; + TopTools_MapOfShape myWrappingSolid; + TopTools_DataMapOfShapeShape myFaceShapeMap; + TopTools_DataMapOfShapeShape myInternalFaces; + TopTools_DataMapOfShapeShape myIntNotClFaces; + Handle_BRepAlgo_AsDes myAsDes; + BRepAlgo_Image myImagesFaces; + BRepAlgo_Image myImagesEdges; + BRepAlgo_Image myImageShape; + Partition_Inter3d myInter3d; + TopTools_MapOfOrientedShape myAddedFacesMap; + + +}; + + + + + +// other Inline functions and methods (like "C++: function call" methods) +// + + +#endif diff --git a/libsrc/occ/Partition_Spliter.ixx b/libsrc/occ/Partition_Spliter.ixx new file mode 100644 index 00000000..ee825946 --- /dev/null +++ b/libsrc/occ/Partition_Spliter.ixx @@ -0,0 +1,31 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Spliter.ixx +// Module : GEOM + +#include "Partition_Spliter.jxx" + + + + diff --git a/libsrc/occ/Partition_Spliter.jxx b/libsrc/occ/Partition_Spliter.jxx new file mode 100644 index 00000000..bf8622c9 --- /dev/null +++ b/libsrc/occ/Partition_Spliter.jxx @@ -0,0 +1,41 @@ +// GEOM PARTITION : partition algorithm +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : Partition_Spliter.jxx +// Module : GEOM + +#ifndef _BRepAlgo_AsDes_HeaderFile +#include +#endif +#ifndef _TopoDS_Shape_HeaderFile +#include +#endif +#ifndef _TopTools_ListOfShape_HeaderFile +#include +#endif +#ifndef _TopoDS_Edge_HeaderFile +#include +#endif +#ifndef _Partition_Spliter_HeaderFile +#include "Partition_Spliter.hxx" +#endif diff --git a/libsrc/occ/occconstruction.cpp b/libsrc/occ/occconstruction.cpp new file mode 100644 index 00000000..2945a147 --- /dev/null +++ b/libsrc/occ/occconstruction.cpp @@ -0,0 +1,157 @@ + +#ifdef OCCGEOMETRY + +#include +#include +#include "ShapeAnalysis_ShapeTolerance.hxx" +#include "ShapeAnalysis_ShapeContents.hxx" +#include "ShapeAnalysis_CheckSmallFace.hxx" +#include "ShapeAnalysis_DataMapOfShapeListOfReal.hxx" +#include "BRepAlgoAPI_Fuse.hxx" +#include "BRepCheck_Analyzer.hxx" +#include "BRepLib.hxx" +#include "ShapeBuild_ReShape.hxx" +#include "ShapeFix.hxx" +#include "ShapeFix_FixSmallFace.hxx" +#include "Partition_Spliter.hxx" +//#include "VrmlAPI.hxx" +//#include "StlAPI.hxx" + + +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +namespace netgen +{ + + void OCCConstructGeometry (OCCGeometry & geom) + { +#ifdef NOTHING + cout << "OCC construction" << endl; + + BRep_Builder builder; + BRepPrimAPI_MakeBox mbox(gp_Pnt(-10e5, -15e5, 0), gp_Pnt(20e5, 15e5, 10e5)); + + + /* + TopoDS_Shape air = TopoDS_Solid (mbox); + air = BRepAlgoAPI_Cut (air, geom.somap(1)); + air = BRepAlgoAPI_Cut (air, geom.somap(2)); + air = BRepAlgoAPI_Cut (air, geom.somap(3)); + air = BRepAlgoAPI_Cut (air, geom.somap(4)); + air = BRepAlgoAPI_Cut (air, geom.somap(5)); + air = BRepAlgoAPI_Cut (air, geom.somap(6)); + air = BRepAlgoAPI_Cut (air, geom.somap(7)); + // air = BRepAlgoAPI_Cut (air, geom.somap(8)); + air = BRepAlgoAPI_Cut (air, geom.somap(9)); + // air = BRepAlgoAPI_Cut (air, geom.somap(10)); + */ + + /* + BRepOffsetAPI_MakeOffsetShape dom8plus (geom.somap(8), 1e4, 1e-6); + BRepOffsetAPI_MakeOffsetShape dom6plus (geom.somap(6), 1e4, 1e-6); + dom8plus.Build(); + ShapeFix_Shape fixshape(dom8plus.Shape()); + fixshape.Perform(); + + ShapeFix_Shape fix_dom2(geom.somap(2)); + fix_dom2.Perform(); + + + BRepAlgoAPI_Cut dom2m8(fix_dom2.Shape(), fixshape.Shape()); + ShapeFix_Shape fix_dom2m8 (dom2m8); + fix_dom2m8.Perform(); + + builder.Add (geom.shape, + BRepAlgoAPI_Cut + (BRepAlgoAPI_Cut (geom.somap(2), dom6plus), + dom8plus)); + // builder.Add (geom.shape, fix_dom2m8.Shape()); + // builder.Add (geom.shape, fixshape.Shape()); + */ + + TopoDS_Shape my_fuse; + int cnt = 0; + for (TopExp_Explorer exp_solid(geom.shape, TopAbs_SOLID); exp_solid.More(); exp_solid.Next()) + { + if (cnt == 0) + my_fuse = exp_solid.Current(); + else + { + cout << "fuse, cnt = " << cnt << endl; + if (cnt != 7 && cnt != 9) + my_fuse = BRepAlgoAPI_Fuse (my_fuse, exp_solid.Current()); + } + cnt++; + } + builder.Add (geom.shape, my_fuse); + + /* + ShapeUpgrade_ShellSewing ss; + ss.ApplySewing(geom.shape,1e5); + */ + + /* + BRepAlgo_Sewing sewing(1.e5); + + int cnt = 0; + for (TopExp_Explorer exp_solid(geom.shape, TopAbs_SOLID); exp_solid.More(); exp_solid.Next()) + { + cout << "swe, cnt = " << cnt << endl; + if (cnt != 7 && cnt != 9) + sewing.Add (exp_solid.Current()); + cnt++; + } + + sewing.Perform(); + builder.Add (geom.shape, sewing.SewedShape()); + */ + + + /* + cout << "build air domain" << endl; + TopoDS_Shape air = BRepAlgoAPI_Cut (TopoDS_Solid (mbox), my_fuse); + + cnt = 0; + for (TopExp_Explorer exp_solid(geom.shape, TopAbs_SOLID); exp_solid.More(); exp_solid.Next()) + { + cout << "section, cnt = " << cnt << endl; + if (cnt == 7) + { + builder.Add (geom.shape, + BRepAlgoAPI_Section (air, exp_solid.Current())); + } + cnt++; + } + */ + + + + // builder.Add (geom.shape, air); + for (int i = 1; i <= 10; i++) + builder.Remove (geom.shape, geom.somap(i)); + + + + + geom.BuildFMap(); + geom.BuildVisualizationMesh(); + geom.changed = 1; +#endif + + } +} + + +#endif diff --git a/libsrc/occ/occgenmesh.cpp b/libsrc/occ/occgenmesh.cpp new file mode 100644 index 00000000..aefec844 --- /dev/null +++ b/libsrc/occ/occgenmesh.cpp @@ -0,0 +1,1460 @@ +#ifdef OCCGEOMETRY + +#include +#include +#include + + +namespace netgen +{ + +#include "occmeshsurf.hpp" + +#define TCL_OK 0 +#define TCL_ERROR 1 + +#define DIVIDEEDGESECTIONS 1000 +#define IGNORECURVELENGTH 1e-4 +#define VSMALL 1e-10 + + + bool merge_solids = 1; + + + // can you please explain what you intend to compute here (JS) !!! + double Line :: Dist (Line l) + { + Vec<3> n = p1-p0; + Vec<3> q = l.p1-l.p0; + double nq = n*q; + + Point<3> p = p0 + 0.5*n; + double lambda = (p-l.p0)*n / (nq + VSMALL); + + if (lambda >= 0 && lambda <= 1) + { + double d = (p-l.p0-lambda*q).Length(); + // if (d < 1e-3) d = 1e99; + return d; + } + else + return 1e99; + } + + + + double Line :: Length () + { + return (p1-p0).Length(); + } + + + + inline Point<3> occ2ng (const gp_Pnt & p) + { + return Point<3> (p.X(), p.Y(), p.Z()); + } + + + + double ComputeH (double kappa) + { + double hret; + kappa *= mparam.curvaturesafety; + + if (mparam.maxh * kappa < 1) + hret = mparam.maxh; + else + hret = 1 / (kappa + VSMALL); + + if (mparam.maxh < hret) + hret = mparam.maxh; + + return (hret); + } + + + + + void RestrictHTriangle (gp_Pnt2d & par0, gp_Pnt2d & par1, gp_Pnt2d & par2, + BRepLProp_SLProps * prop, Mesh & mesh, int depth, double h = 0) + { + int ls = -1; + + gp_Pnt pnt0,pnt1,pnt2; + + prop->SetParameters (par0.X(), par0.Y()); + pnt0 = prop->Value(); + + prop->SetParameters (par1.X(), par1.Y()); + pnt1 = prop->Value(); + + prop->SetParameters (par2.X(), par2.Y()); + pnt2 = prop->Value(); + + double aux; + double maxside = pnt0.Distance(pnt1); + ls = 2; + aux = pnt1.Distance(pnt2); + if(aux > maxside) + { + maxside = aux; + ls = 0; + } + aux = pnt2.Distance(pnt0); + if(aux > maxside) + { + maxside = aux; + ls = 1; + } + + + + gp_Pnt2d parmid; + + parmid.SetX( (par0.X()+par1.X()+par2.X()) / 3 ); + parmid.SetY( (par0.Y()+par1.Y()+par2.Y()) / 3 ); + + if (depth%3 == 0) + { + double curvature = 0; + + prop->SetParameters (parmid.X(), parmid.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature())); + + prop->SetParameters (par0.X(), par0.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + prop->SetParameters (par1.X(), par1.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + prop->SetParameters (par2.X(), par2.Y()); + if (!prop->IsCurvatureDefined()) + { + (*testout) << "curvature not defined!" << endl; + return; + } + curvature = max(curvature,max(fabs(prop->MinCurvature()), + fabs(prop->MaxCurvature()))); + + //(*testout) << "curvature " << curvature << endl; + + if (curvature < 1e-3) + { + //(*testout) << "curvature too small (" << curvature << ")!" << endl; + return; + // return war bis 10.2.05 auskommentiert + } + + + + h = ComputeH (curvature+1e-10); + + if(h < 1e-4*maxside) + return; + + + if (h > 30) return; + } + + if (h < maxside && depth < 10) + { + //cout << "\r h " << h << flush; + gp_Pnt2d pm; + + //cout << "h " << h << " maxside " << maxside << " depth " << depth << endl; + //cout << "par0 " << par0.X() << " " << par0.Y() + //<< " par1 " << par1.X() << " " << par1.Y() + // << " par2 " << par2.X() << " " << par2.Y()<< endl; + + if(ls == 0) + { + pm.SetX(0.5*(par1.X()+par2.X())); pm.SetY(0.5*(par1.Y()+par2.Y())); + RestrictHTriangle(pm, par2, par0, prop, mesh, depth+1, h); + RestrictHTriangle(pm, par0, par1, prop, mesh, depth+1, h); + } + else if(ls == 1) + { + pm.SetX(0.5*(par0.X()+par2.X())); pm.SetY(0.5*(par0.Y()+par2.Y())); + RestrictHTriangle(pm, par1, par2, prop, mesh, depth+1, h); + RestrictHTriangle(pm, par0, par1, prop, mesh, depth+1, h); + } + else if(ls == 2) + { + pm.SetX(0.5*(par0.X()+par1.X())); pm.SetY(0.5*(par0.Y()+par1.Y())); + RestrictHTriangle(pm, par1, par2, prop, mesh, depth+1, h); + RestrictHTriangle(pm, par2, par0, prop, mesh, depth+1, h); + } + + } + else + { + gp_Pnt pnt; + Point3d p3d; + + prop->SetParameters (parmid.X(), parmid.Y()); + pnt = prop->Value(); + p3d = Point3d(pnt.X(), pnt.Y(), pnt.Z()); + mesh.RestrictLocalH (p3d, h); + + p3d = Point3d(pnt0.X(), pnt0.Y(), pnt0.Z()); + mesh.RestrictLocalH (p3d, h); + + p3d = Point3d(pnt1.X(), pnt1.Y(), pnt1.Z()); + mesh.RestrictLocalH (p3d, h); + + p3d = Point3d(pnt2.X(), pnt2.Y(), pnt2.Z()); + mesh.RestrictLocalH (p3d, h); + + //(*testout) << "p = " << p3d << ", h = " << h << ", maxside = " << maxside << endl; + + } + } + + + + void DivideEdge (TopoDS_Edge & edge, Array & ps, + Array & params, Mesh & mesh) + { + double s0, s1; + double maxh = mparam.maxh; + int nsubedges = 1; + gp_Pnt pnt, oldpnt; + double svalue[DIVIDEEDGESECTIONS]; + + GProp_GProps system; + BRepGProp::LinearProperties(edge, system); + double L = system.Mass(); + + Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); + + double hvalue[DIVIDEEDGESECTIONS+1]; + hvalue[0] = 0; + pnt = c->Value(s0); + + double olddist = 0; + double dist = 0; + + int tmpVal = (int)(DIVIDEEDGESECTIONS); + + for (int i = 1; i <= tmpVal; i++) + { + oldpnt = pnt; + pnt = c->Value(s0+(i/double(DIVIDEEDGESECTIONS))*(s1-s0)); + hvalue[i] = hvalue[i-1] + + 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))* + pnt.Distance(oldpnt); + + //(*testout) << "mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) " << mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) + // << " pnt.Distance(oldpnt) " << pnt.Distance(oldpnt) << endl; + + olddist = dist; + dist = pnt.Distance(oldpnt); + } + + // nsubedges = int(ceil(hvalue[DIVIDEEDGESECTIONS])); + nsubedges = max (1, int(floor(hvalue[DIVIDEEDGESECTIONS]+0.5))); + + ps.SetSize(nsubedges-1); + params.SetSize(nsubedges+1); + + int i = 1; + int i1 = 0; + do + { + if (hvalue[i1]/hvalue[DIVIDEEDGESECTIONS]*nsubedges >= i) + { + params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0); + pnt = c->Value(params[i]); + ps[i-1] = MeshPoint (Point3d(pnt.X(), pnt.Y(), pnt.Z())); + i++; + } + i1++; + if (i1 > DIVIDEEDGESECTIONS) + { + nsubedges = i; + ps.SetSize(nsubedges-1); + params.SetSize(nsubedges+1); + cout << "divide edge: local h too small" << endl; + } + } while (i < nsubedges); + + params[0] = s0; + params[nsubedges] = s1; + + if (params[nsubedges] <= params[nsubedges-1]) + { + cout << "CORRECTED" << endl; + ps.SetSize (nsubedges-2); + params.SetSize (nsubedges); + params[nsubedges] = s1; + } + } + + + + + void OCCFindEdges (OCCGeometry & geom, Mesh & mesh) + { + const char * savetask = multithread.task; + multithread.task = "Edge meshing"; + + (*testout) << "edge meshing" << endl; + + int nvertices = geom.vmap.Extent(); + int nedges = geom.emap.Extent(); + + (*testout) << "nvertices = " << nvertices << endl; + (*testout) << "nedges = " << nedges << endl; + + double eps = 1e-6 * geom.GetBoundingBox().Diam(); + + for (int i = 1; i <= nvertices; i++) + { + gp_Pnt pnt = BRep_Tool::Pnt (TopoDS::Vertex(geom.vmap(i))); + MeshPoint mp( Point<3>(pnt.X(), pnt.Y(), pnt.Z()) ); + + bool exists = 0; + if (merge_solids) + for (PointIndex pi = 1; pi <= mesh.GetNP(); pi++) + if ( Dist2 (mesh[pi], Point<3>(mp)) < eps*eps) + { + exists = 1; + break; + } + + if (!exists) + mesh.AddPoint (mp); + } + + (*testout) << "different vertices = " << mesh.GetNP() << endl; + + + int first_ep = mesh.GetNP()+1; + + Array face2solid[2]; + for (int i = 0; i<2; i++) + { + face2solid[i].SetSize (geom.fmap.Extent()); + face2solid[i] = 0; + } + + int solidnr = 0; + for (TopExp_Explorer exp0(geom.shape, TopAbs_SOLID); exp0.More(); exp0.Next()) + { + solidnr++; + for (TopExp_Explorer exp1(exp0.Current(), TopAbs_FACE); exp1.More(); exp1.Next()) + { + TopoDS_Face face = TopoDS::Face(exp1.Current()); + int facenr = geom.fmap.FindIndex(face); + + if (face2solid[0][facenr-1] == 0) + face2solid[0][facenr-1] = solidnr; + else + face2solid[1][facenr-1] = solidnr; + } + } + + + int total = 0; + for (int i3 = 1; i3 <= geom.fmap.Extent(); i3++) + for (TopExp_Explorer exp2(geom.fmap(i3), TopAbs_WIRE); exp2.More(); exp2.Next()) + for (TopExp_Explorer exp3(exp2.Current(), TopAbs_EDGE); exp3.More(); exp3.Next()) + total++; + + + int facenr = 0; + int edgenr = 0; + + + (*testout) << "faces = " << geom.fmap.Extent() << endl; + int curr = 0; + + for (int i3 = 1; i3 <= geom.fmap.Extent(); i3++) + { + TopoDS_Face face = TopoDS::Face(geom.fmap(i3)); + facenr = geom.fmap.FindIndex (face); // sollte doch immer == i3 sein ??? JS + + int solidnr0 = face2solid[0][i3-1]; + int solidnr1 = face2solid[1][i3-1]; + + /* auskommentiert am 3.3.05 von robert + for (exp2.Init (geom.somap(solidnr0), TopAbs_FACE); exp2.More(); exp2.Next()) + { + TopoDS_Face face2 = TopoDS::Face(exp2.Current()); + if (geom.fmap.FindIndex(face2) == facenr) + { + // if (face.Orientation() != face2.Orientation()) swap (solidnr0, solidnr1); + } + } + */ + + mesh.AddFaceDescriptor (FaceDescriptor(facenr, solidnr0, solidnr1, 0)); + + // Philippose - 06/07/2009 + // Add the face colour to the mesh data + Quantity_Color face_colour; + + if(!(geom.face_colours.IsNull()) + && (geom.face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour))) + { + mesh.GetFaceDescriptor(facenr).SetSurfColour(Vec3d(face_colour.Red(),face_colour.Green(),face_colour.Blue())); + } + else + { + mesh.GetFaceDescriptor(facenr).SetSurfColour(Vec3d(0.0,1.0,0.0)); + } + // ACHTUNG! STIMMT NICHT ALLGEMEIN (RG) + + + Handle(Geom_Surface) occface = BRep_Tool::Surface(face); + + for (TopExp_Explorer exp2 (face, TopAbs_WIRE); exp2.More(); exp2.Next()) + { + TopoDS_Shape wire = exp2.Current(); + + for (TopExp_Explorer exp3 (wire, TopAbs_EDGE); exp3.More(); exp3.Next()) + { + curr++; + (*testout) << "edge nr " << curr << endl; + + multithread.percent = 100 * curr / double (total); + if (multithread.terminate) return; + + TopoDS_Edge edge = TopoDS::Edge (exp3.Current()); + if (BRep_Tool::Degenerated(edge)) + { + //(*testout) << "ignoring degenerated edge" << endl; + continue; + } + + if (geom.vmap.FindIndex(TopExp::FirstVertex (edge)) == + geom.vmap.FindIndex(TopExp::LastVertex (edge))) + { + GProp_GProps system; + BRepGProp::LinearProperties(edge, system); + + if (system.Mass() < eps) + { + cout << "ignoring edge " << geom.emap.FindIndex (edge) + << ". closed edge with length < " << eps << endl; + continue; + } + } + + + Handle(Geom2d_Curve) cof; + double s0, s1; + cof = BRep_Tool::CurveOnSurface (edge, face, s0, s1); + + int geomedgenr = geom.emap.FindIndex(edge); + + Array mp; + Array params; + + DivideEdge (edge, mp, params, mesh); + + Array pnums; + pnums.SetSize (mp.Size()+2); + + if (!merge_solids) + { + pnums[0] = geom.vmap.FindIndex (TopExp::FirstVertex (edge)); + pnums[pnums.Size()-1] = geom.vmap.FindIndex (TopExp::LastVertex (edge)); + } + else + { + Point<3> fp = occ2ng (BRep_Tool::Pnt (TopExp::FirstVertex (edge))); + Point<3> lp = occ2ng (BRep_Tool::Pnt (TopExp::LastVertex (edge))); + + pnums[0] = -1; + pnums.Last() = -1; + for (PointIndex pi = 1; pi < first_ep; pi++) + { + if (Dist2 (mesh[pi], fp) < eps*eps) pnums[0] = pi; + if (Dist2 (mesh[pi], lp) < eps*eps) pnums.Last() = pi; + } + } + + + for (int i = 1; i <= mp.Size(); i++) + { + bool exists = 0; + int j; + for (j = first_ep; j <= mesh.GetNP(); j++) + if ((mesh.Point(j)-Point<3>(mp[i-1])).Length() < eps) + { + exists = 1; + break; + } + + if (exists) + pnums[i] = j; + else + { + mesh.AddPoint (mp[i-1]); + (*testout) << "add meshpoint " << mp[i-1] << endl; + pnums[i] = mesh.GetNP(); + } + } + (*testout) << "NP = " << mesh.GetNP() << endl; + + //(*testout) << pnums[pnums.Size()-1] << endl; + + for (int i = 1; i <= mp.Size()+1; i++) + { + edgenr++; + Segment seg; + + seg[0] = pnums[i-1]; + seg[1] = pnums[i]; + seg.edgenr = edgenr; + seg.si = facenr; + seg.epgeominfo[0].dist = params[i-1]; + seg.epgeominfo[1].dist = params[i]; + seg.epgeominfo[0].edgenr = geomedgenr; + seg.epgeominfo[1].edgenr = geomedgenr; + + gp_Pnt2d p2d; + p2d = cof->Value(params[i-1]); + // if (i == 1) p2d = cof->Value(s0); + seg.epgeominfo[0].u = p2d.X(); + seg.epgeominfo[0].v = p2d.Y(); + p2d = cof->Value(params[i]); + // if (i == mp.Size()+1) p2d = cof -> Value(s1); + seg.epgeominfo[1].u = p2d.X(); + seg.epgeominfo[1].v = p2d.Y(); + + /* + if (occface->IsUPeriodic()) + { + cout << "U Periodic" << endl; + if (fabs(seg.epgeominfo[1].u-seg.epgeominfo[0].u) > + fabs(seg.epgeominfo[1].u- + (seg.epgeominfo[0].u-occface->UPeriod()))) + seg.epgeominfo[0].u = p2d.X()+occface->UPeriod(); + + if (fabs(seg.epgeominfo[1].u-seg.epgeominfo[0].u) > + fabs(seg.epgeominfo[1].u- + (seg.epgeominfo[0].u+occface->UPeriod()))) + seg.epgeominfo[0].u = p2d.X()-occface->UPeriod(); + } + + if (occface->IsVPeriodic()) + { + cout << "V Periodic" << endl; + if (fabs(seg.epgeominfo[1].v-seg.epgeominfo[0].v) > + fabs(seg.epgeominfo[1].v- + (seg.epgeominfo[0].v-occface->VPeriod()))) + seg.epgeominfo[0].v = p2d.Y()+occface->VPeriod(); + + if (fabs(seg.epgeominfo[1].v-seg.epgeominfo[0].v) > + fabs(seg.epgeominfo[1].v- + (seg.epgeominfo[0].v+occface->VPeriod()))) + seg.epgeominfo[0].v = p2d.Y()-occface->VPeriod(); + } + */ + + if (edge.Orientation() == TopAbs_REVERSED) + { + swap (seg[0], seg[1]); + swap (seg.epgeominfo[0].dist, seg.epgeominfo[1].dist); + swap (seg.epgeominfo[0].u, seg.epgeominfo[1].u); + swap (seg.epgeominfo[0].v, seg.epgeominfo[1].v); + } + + mesh.AddSegment (seg); + + //edgesegments[geomedgenr-1]->Append(mesh.GetNSeg()); + + } + } + } + } + + // for(i=1; i<=mesh.GetNSeg(); i++) + // (*testout) << "edge " << mesh.LineSegment(i).edgenr << " face " << mesh.LineSegment(i).si + // << " p1 " << mesh.LineSegment(i)[0] << " p2 " << mesh.LineSegment(i)[1] << endl; + // exit(10); + + mesh.CalcSurfacesOfNode(); + multithread.task = savetask; + } + + + + + void OCCMeshSurface (OCCGeometry & geom, Mesh & mesh, int perfstepsend) + { + int i, j, k; + int changed; + + const char * savetask = multithread.task; + multithread.task = "Surface meshing"; + + geom.facemeshstatus = 0; + + int noldp = mesh.GetNP(); + + double starttime = GetTime(); + + Array glob2loc(noldp); + + //int projecttype = PARAMETERSPACE; + + int projecttype = PARAMETERSPACE; + + int notrys = 1; + + int surfmesherror = 0; + + for (k = 1; k <= mesh.GetNFD(); k++) + { + if(1==0 && !geom.fvispar[k-1].IsDrawable()) + { + (*testout) << "ignoring face " << k << endl; + cout << "ignoring face " << k << endl; + continue; + } + + (*testout) << "mesh face " << k << endl; + multithread.percent = 100 * k / (mesh.GetNFD() + VSMALL); + geom.facemeshstatus[k-1] = -1; + + + /* + if (k != 42) + { + cout << "skipped" << endl; + continue; + } + */ + + + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + + int oldnf = mesh.GetNSE(); + + Box<3> bb = geom.GetBoundingBox(); + + // int projecttype = PLANESPACE; + + Meshing2OCCSurfaces meshing(TopoDS::Face(geom.fmap(k)), bb, projecttype); + + if (meshing.GetProjectionType() == PLANESPACE) + PrintMessage (2, "Face ", k, " / ", mesh.GetNFD(), " (plane space projection)"); + else + PrintMessage (2, "Face ", k, " / ", mesh.GetNFD(), " (parameter space projection)"); + + if (surfmesherror) + cout << "Surface meshing error occured before (in " << surfmesherror << " faces)" << endl; + + // Meshing2OCCSurfaces meshing(f2, bb); + meshing.SetStartTime (starttime); + + //(*testout) << "Face " << k << endl << endl; + + + if (meshing.GetProjectionType() == PLANESPACE) + { + int cntp = 0; + glob2loc = 0; + for (i = 1; i <= mesh.GetNSeg(); i++) + { + Segment & seg = mesh.LineSegment(i); + if (seg.si == k) + { + for (j = 1; j <= 2; j++) + { + int pi = (j == 1) ? seg[0] : seg[1]; + if (!glob2loc.Get(pi)) + { + meshing.AddPoint (mesh.Point(pi), pi); + cntp++; + glob2loc.Elem(pi) = cntp; + } + } + } + } + + for (i = 1; i <= mesh.GetNSeg(); i++) + { + Segment & seg = mesh.LineSegment(i); + if (seg.si == k) + { + PointGeomInfo gi0, gi1; + gi0.trignum = gi1.trignum = k; + gi0.u = seg.epgeominfo[0].u; + gi0.v = seg.epgeominfo[0].v; + gi1.u = seg.epgeominfo[1].u; + gi1.v = seg.epgeominfo[1].v; + + meshing.AddBoundaryElement (glob2loc.Get(seg[0]), glob2loc.Get(seg[1]), gi0, gi1); + //(*testout) << gi0.u << " " << gi0.v << endl; + //(*testout) << gi1.u << " " << gi1.v << endl; + } + } + } + else + { + int cntp = 0; + + for (i = 1; i <= mesh.GetNSeg(); i++) + if (mesh.LineSegment(i).si == k) + cntp+=2; + + + Array< PointGeomInfo > gis; + + gis.SetAllocSize (cntp); + gis.SetSize (0); + + for (i = 1; i <= mesh.GetNSeg(); i++) + { + Segment & seg = mesh.LineSegment(i); + if (seg.si == k) + { + PointGeomInfo gi0, gi1; + gi0.trignum = gi1.trignum = k; + gi0.u = seg.epgeominfo[0].u; + gi0.v = seg.epgeominfo[0].v; + gi1.u = seg.epgeominfo[1].u; + gi1.v = seg.epgeominfo[1].v; + + int locpnum[2] = {0, 0}; + + for (j = 0; j < 2; j++) + { + PointGeomInfo gi = (j == 0) ? gi0 : gi1; + + int l; + for (l = 0; l < gis.Size() && locpnum[j] == 0; l++) + { + double dist = sqr (gis[l].u-gi.u)+sqr(gis[l].v-gi.v); + + if (dist < 1e-10) + locpnum[j] = l+1; + } + + if (locpnum[j] == 0) + { + int pi = (j == 0) ? seg[0] : seg[1]; + meshing.AddPoint (mesh.Point(pi), pi); + + gis.SetSize (gis.Size()+1); + gis[l] = gi; + locpnum[j] = l+1; + } + } + + meshing.AddBoundaryElement (locpnum[0], locpnum[1], gi0, gi1); + //(*testout) << gi0.u << " " << gi0.v << endl; + //(*testout) << gi1.u << " " << gi1.v << endl; + + } + } + } + + + + + + // Philippose - 15/01/2009 + double maxh = geom.face_maxh[k-1]; + //double maxh = mparam.maxh; + mparam.checkoverlap = 0; + // int noldpoints = mesh->GetNP(); + int noldsurfel = mesh.GetNSE(); + + GProp_GProps sprops; + BRepGProp::SurfaceProperties(TopoDS::Face(geom.fmap(k)),sprops); + meshing.SetMaxArea(2.*sprops.Mass()); + + MESHING2_RESULT res; + + try { + res = meshing.GenerateMesh (mesh, mparam, maxh, k); + } + + catch (SingularMatrixException) + { + (*myerr) << "Singular Matrix" << endl; + res = MESHING2_GIVEUP; + } + + catch (UVBoundsException) + { + (*myerr) << "UV bounds exceeded" << endl; + res = MESHING2_GIVEUP; + } + + projecttype = PARAMETERSPACE; + + if (res != MESHING2_OK) + { + if (notrys == 1) + { + for (int i = noldsurfel+1; i <= mesh.GetNSE(); i++) + mesh.DeleteSurfaceElement (i); + + mesh.Compress(); + + cout << "retry Surface " << k << endl; + + k--; + projecttype*=-1; + notrys++; + continue; + } + else + { + geom.facemeshstatus[k-1] = -1; + PrintError ("Problem in Surface mesh generation"); + surfmesherror++; + // throw NgException ("Problem in Surface mesh generation"); + } + } + else + { + geom.facemeshstatus[k-1] = 1; + } + + notrys = 1; + + for (i = oldnf+1; i <= mesh.GetNSE(); i++) + mesh.SurfaceElement(i).SetIndex (k); + + } + +// ofstream problemfile("occmesh.rep"); + +// problemfile << "SURFACEMESHING" << endl << endl; + + if (surfmesherror) + { + cout << "WARNING! NOT ALL FACES HAVE BEEN MESHED" << endl; + cout << "SURFACE MESHING ERROR OCCURED IN " << surfmesherror << " FACES:" << endl; + for (int i = 1; i <= geom.fmap.Extent(); i++) + if (geom.facemeshstatus[i-1] == -1) + { + cout << "Face " << i << endl; +// problemfile << "problem with face " << i << endl; +// problemfile << "vertices: " << endl; + TopExp_Explorer exp0,exp1,exp2; + for ( exp0.Init(TopoDS::Face (geom.fmap(i)), TopAbs_WIRE); exp0.More(); exp0.Next() ) + { + TopoDS_Wire wire = TopoDS::Wire(exp0.Current()); + for ( exp1.Init(wire,TopAbs_EDGE); exp1.More(); exp1.Next() ) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + for ( exp2.Init(edge,TopAbs_VERTEX); exp2.More(); exp2.Next() ) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp2.Current()); + gp_Pnt point = BRep_Tool::Pnt(vertex); +// problemfile << point.X() << " " << point.Y() << " " << point.Z() << endl; + } + } + } +// problemfile << endl; + + } + cout << endl << endl; + cout << "for more information open IGES/STEP Topology Explorer" << endl; +// problemfile.close(); + throw NgException ("Problem in Surface mesh generation"); + } + else + { +// problemfile << "OK" << endl << endl; +// problemfile.close(); + } + + + + + if (multithread.terminate || perfstepsend < MESHCONST_OPTSURFACE) + return; + + multithread.task = "Optimizing surface"; + + static int timer_opt2d = NgProfiler::CreateTimer ("Optimization 2D"); + NgProfiler::StartTimer (timer_opt2d); + + for (k = 1; k <= mesh.GetNFD(); k++) + { + // if (k != 42) continue; + // if (k != 36) continue; + + // (*testout) << "optimize face " << k << endl; + multithread.percent = 100 * k / (mesh.GetNFD() + VSMALL); + + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + + PrintMessage (1, "Optimize Surface ", k); + for (i = 1; i <= mparam.optsteps2d; i++) + { + // (*testout) << "optstep " << i << endl; + if (multithread.terminate) return; + + { + MeshOptimize2dOCCSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + meshopt.SetMetricWeight (mparam.elsizeweight); + //meshopt.SetMetricWeight (0.2); + meshopt.SetWriteStatus (0); + + // (*testout) << "EdgeSwapping (mesh, (i > mparam.optsteps2d/2))" << endl; + meshopt.EdgeSwapping (mesh, (i > mparam.optsteps2d/2)); + } + + if (multithread.terminate) return; + { + MeshOptimize2dOCCSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + //meshopt.SetMetricWeight (0.2); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + // (*testout) << "ImproveMesh (mesh)" << endl; + meshopt.ImproveMesh (mesh, mparam); + } + + { + MeshOptimize2dOCCSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + //meshopt.SetMetricWeight (0.2); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + // (*testout) << "CombineImprove (mesh)" << endl; + meshopt.CombineImprove (mesh); + } + + if (multithread.terminate) return; + { + MeshOptimize2dOCCSurfaces meshopt(geom); + meshopt.SetFaceIndex (k); + meshopt.SetImproveEdges (0); + //meshopt.SetMetricWeight (0.2); + meshopt.SetMetricWeight (mparam.elsizeweight); + meshopt.SetWriteStatus (0); + + // (*testout) << "ImproveMesh (mesh)" << endl; + meshopt.ImproveMesh (mesh, mparam); + } + } + + } + + + mesh.CalcSurfacesOfNode(); + mesh.Compress(); + + NgProfiler::StopTimer (timer_opt2d); + + multithread.task = savetask; + } + + + + void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh) + { + mesh.SetGlobalH (mparam.maxh); + mesh.SetMinimalH (mparam.minh); + + Array maxhdom; + maxhdom.SetSize (geom.NrSolids()); + maxhdom = mparam.maxh; + + mesh.SetMaxHDomain (maxhdom); + + Box<3> bb = geom.GetBoundingBox(); + bb.Increase (bb.Diam()/10); + + mesh.SetLocalH (bb.PMin(), bb.PMax(), 0.5); + + if (mparam.uselocalh) + { + const char * savetask = multithread.task; + multithread.percent = 0; + + mesh.SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); + + int nedges = geom.emap.Extent(); + + double maxedgelen = 0; + double minedgelen = 1e99; + + multithread.task = "Setting local mesh size (elements per edge)"; + + // setting elements per edge + + for (int i = 1; i <= nedges && !multithread.terminate; i++) + { + TopoDS_Edge e = TopoDS::Edge (geom.emap(i)); + multithread.percent = 100 * (i-1)/double(nedges); + if (BRep_Tool::Degenerated(e)) continue; + + GProp_GProps system; + BRepGProp::LinearProperties(e, system); + double len = system.Mass(); + + if (len < IGNORECURVELENGTH) + { + (*testout) << "ignored" << endl; + continue; + } + + double localh = len/mparam.segmentsperedge; + double s0, s1; + + // Philippose - 23/01/2009 + // Find all the parent faces of a given edge + // and limit the mesh size of the edge based on the + // mesh size limit of the face + TopTools_IndexedDataMapOfShapeListOfShape edge_face_map; + edge_face_map.Clear(); + + TopExp::MapShapesAndAncestors(geom.shape, TopAbs_EDGE, TopAbs_FACE, edge_face_map); + const TopTools_ListOfShape& parent_faces = edge_face_map.FindFromKey(e); + + TopTools_ListIteratorOfListOfShape parent_face_list; + + for(parent_face_list.Initialize(parent_faces); parent_face_list.More(); parent_face_list.Next()) + { + TopoDS_Face parent_face = TopoDS::Face(parent_face_list.Value()); + + int face_index = geom.fmap.FindIndex(parent_face); + + if(face_index >= 1) localh = min(localh,geom.face_maxh[face_index - 1]); + } + + Handle(Geom_Curve) c = BRep_Tool::Curve(e, s0, s1); + + maxedgelen = max (maxedgelen, len); + minedgelen = min (minedgelen, len); + + // Philippose - 23/01/2009 + // Modified the calculation of maxj, because the + // method used so far always results in maxj = 2, + // which causes the localh to be set only at the + // starting, mid and end of the edge. + // Old Algorithm: + // int maxj = 2 * (int) ceil (localh/len); + int maxj = max((int) ceil(len/localh), 2); + + for (int j = 0; j <= maxj; j++) + { + gp_Pnt pnt = c->Value (s0+double(j)/maxj*(s1-s0)); + mesh.RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), localh); + } + } + + multithread.task = "Setting local mesh size (edge curvature)"; + + // setting edge curvature + + int nsections = 20; + + for (int i = 1; i <= nedges && !multithread.terminate; i++) + { + double maxcur = 0; + multithread.percent = 100 * (i-1)/double(nedges); + TopoDS_Edge edge = TopoDS::Edge (geom.emap(i)); + if (BRep_Tool::Degenerated(edge)) continue; + double s0, s1; + Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); + BRepAdaptor_Curve brepc(edge); + BRepLProp_CLProps prop(brepc, 2, 1e-5); + + for (int j = 1; j <= nsections; j++) + { + double s = s0 + j/(double) nsections * (s1-s0); + prop.SetParameter (s); + double curvature = prop.Curvature(); + if(curvature> maxcur) maxcur = curvature; + + if (curvature >= 1e99) + continue; + + gp_Pnt pnt = c->Value (s); + + mesh.RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), ComputeH (fabs(curvature))); + } + // (*testout) << "edge " << i << " max. curvature: " << maxcur << endl; + } + + multithread.task = "Setting local mesh size (face curvature)"; + + // setting face curvature + + int nfaces = geom.fmap.Extent(); + + for (int i = 1; i <= nfaces && !multithread.terminate; i++) + { + multithread.percent = 100 * (i-1)/double(nfaces); + TopoDS_Face face = TopoDS::Face(geom.fmap(i)); + TopLoc_Location loc; + Handle(Geom_Surface) surf = BRep_Tool::Surface (face); + Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc); + + if (triangulation.IsNull()) continue; + + BRepAdaptor_Surface sf(face, Standard_True); + BRepLProp_SLProps prop(sf, 2, 1e-5); + + int ntriangles = triangulation -> NbTriangles(); + for (int j = 1; j <= ntriangles; j++) + { + gp_Pnt p[3]; + gp_Pnt2d par[3]; + + for (int k = 1; k <=3; k++) + { + int n = triangulation->Triangles()(j)(k); + p[k-1] = triangulation->Nodes()(n).Transformed(loc); + par[k-1] = triangulation->UVNodes()(n); + } + + //double maxside = 0; + //maxside = max (maxside, p[0].Distance(p[1])); + //maxside = max (maxside, p[0].Distance(p[2])); + //maxside = max (maxside, p[1].Distance(p[2])); + //cout << "\rFace " << i << " pos11 ntriangles " << ntriangles << " maxside " << maxside << flush; + + RestrictHTriangle (par[0], par[1], par[2], &prop, mesh, 0); + //cout << "\rFace " << i << " pos12 ntriangles " << ntriangles << flush; + } + } + + // setting close edges + + if (occparam.resthcloseedgeenable) + { + multithread.task = "Setting local mesh size (close edges)"; + + int sections = 100; + + Array lines(sections*nedges); + + Box3dTree* searchtree = + new Box3dTree (bb.PMin(), bb.PMax()); + + int nlines = 0; + for (int i = 1; i <= nedges && !multithread.terminate; i++) + { + TopoDS_Edge edge = TopoDS::Edge (geom.emap(i)); + if (BRep_Tool::Degenerated(edge)) continue; + + double s0, s1; + Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); + BRepAdaptor_Curve brepc(edge); + BRepLProp_CLProps prop(brepc, 1, 1e-5); + prop.SetParameter (s0); + + gp_Vec d0 = prop.D1().Normalized(); + double s_start = s0; + int count = 0; + for (int j = 1; j <= sections; j++) + { + double s = s0 + (s1-s0)*(double)j/(double)sections; + prop.SetParameter (s); + gp_Vec d1 = prop.D1().Normalized(); + double cosalpha = fabs(d0*d1); + if ((j == sections) || (cosalpha < cos(10.0/180.0*M_PI))) + { + count++; + gp_Pnt p0 = c->Value (s_start); + gp_Pnt p1 = c->Value (s); + lines[nlines].p0 = Point<3> (p0.X(), p0.Y(), p0.Z()); + lines[nlines].p1 = Point<3> (p1.X(), p1.Y(), p1.Z()); + + Box3d box; + box.SetPoint (Point3d(lines[nlines].p0)); + box.AddPoint (Point3d(lines[nlines].p1)); + + searchtree->Insert (box.PMin(), box.PMax(), nlines+1); + nlines++; + + s_start = s; + d0 = d1; + } + } + } + + Array linenums; + + for (int i = 0; i < nlines; i++) + { + multithread.percent = (100*i)/double(nlines); + Line & line = lines[i]; + + Box3d box; + box.SetPoint (Point3d(line.p0)); + box.AddPoint (Point3d(line.p1)); + double maxhline = max (mesh.GetH(box.PMin()), + mesh.GetH(box.PMax())); + box.Increase(maxhline); + + double mindist = 1e99; + linenums.SetSize(0); + searchtree->GetIntersecting(box.PMin(),box.PMax(),linenums); + + for (int j = 0; j < linenums.Size(); j++) + { + int num = linenums[j]-1; + if (i == num) continue; + if ((line.p0-lines[num].p0).Length2() < 1e-15) continue; + if ((line.p0-lines[num].p1).Length2() < 1e-15) continue; + if ((line.p1-lines[num].p0).Length2() < 1e-15) continue; + if ((line.p1-lines[num].p1).Length2() < 1e-15) continue; + mindist = min (mindist, line.Dist(lines[num])); + } + + mindist /= (occparam.resthcloseedgefac + VSMALL); + + if (mindist < 1e-3) + { + (*testout) << "extremely small local h: " << mindist + << " --> setting to 1e-3" << endl; + (*testout) << "somewhere near " << line.p0 << " - " << line.p1 << endl; + mindist = 1e-3; + } + + mesh.RestrictLocalHLine(line.p0, line.p1, mindist); + } + } + + multithread.task = savetask; + + } + + // Philippose - 09/03/2009 + // Added the capability to load the mesh size from a + // file also for OpenCascade Geometry + // Note: + // ** If the "uselocalh" option is ticked in + // the "mesh options...insider" menu, the mesh + // size will be further modified by the topology + // analysis routines. + // ** To use the mesh size file as the sole source + // for defining the mesh size, uncheck the "uselocalh" + // option. + mesh.LoadLocalMeshSize (mparam.meshsizefilename); + } + + + + int OCCGenerateMesh (OCCGeometry & geom, Mesh *& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend) + { + multithread.percent = 0; + + if (perfstepsstart <= MESHCONST_ANALYSE) + { + delete mesh; + mesh = new Mesh(); + mesh->geomtype = Mesh::GEOM_OCC; + + OCCSetLocalMeshSize(geom,*mesh); + } + + if (multithread.terminate || perfstepsend <= MESHCONST_ANALYSE) + return TCL_OK; + + if (perfstepsstart <= MESHCONST_MESHEDGES) + { + OCCFindEdges (geom, *mesh); + + /* + cout << "Removing redundant points" << endl; + + int i, j; + int np = mesh->GetNP(); + Array equalto; + + equalto.SetSize (np); + equalto = 0; + + for (i = 1; i <= np; i++) + { + for (j = i+1; j <= np; j++) + { + if (!equalto[j-1] && (Dist2 (mesh->Point(i), mesh->Point(j)) < 1e-12)) + equalto[j-1] = i; + } + } + + for (i = 1; i <= np; i++) + if (equalto[i-1]) + { + cout << "Point " << i << " is equal to Point " << equalto[i-1] << endl; + for (j = 1; j <= mesh->GetNSeg(); j++) + { + Segment & seg = mesh->LineSegment(j); + if (seg[0] == i) seg[0] = equalto[i-1]; + if (seg[1] == i) seg[1] = equalto[i-1]; + } + } + + cout << "Removing degenerated segments" << endl; + for (j = 1; j <= mesh->GetNSeg(); j++) + { + Segment & seg = mesh->LineSegment(j); + if (seg[0] == seg[1]) + { + mesh->DeleteSegment(j); + cout << "Deleting Segment " << j << endl; + } + } + + mesh->Compress(); + */ + + /* + for (int i = 1; i <= geom.fmap.Extent(); i++) + { + Handle(Geom_Surface) hf1 = + BRep_Tool::Surface(TopoDS::Face(geom.fmap(i))); + for (int j = i+1; j <= geom.fmap.Extent(); j++) + { + Handle(Geom_Surface) hf2 = + BRep_Tool::Surface(TopoDS::Face(geom.fmap(j))); + if (hf1 == hf2) cout << "face " << i << " and face " << j << " lie on same surface" << endl; + } + } + */ + +#ifdef LOG_STREAM + (*logout) << "Edges meshed" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + } + + if (multithread.terminate || perfstepsend <= MESHCONST_MESHEDGES) + return TCL_OK; + + if (perfstepsstart <= MESHCONST_MESHSURFACE) + { + OCCMeshSurface (geom, *mesh, perfstepsend); + if (multithread.terminate) return TCL_OK; + +#ifdef LOG_STREAM + (*logout) << "Surfaces meshed" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + +#ifdef STAT_STREAM + (*statout) << mesh->GetNSeg() << " & " + << mesh->GetNSE() << " & - &" + << GetTime() << " & " << endl; +#endif + + // MeshQuality2d (*mesh); + mesh->CalcSurfacesOfNode(); + } + + if (multithread.terminate || perfstepsend <= MESHCONST_OPTSURFACE) + return TCL_OK; + + if (perfstepsstart <= MESHCONST_MESHVOLUME) + { + multithread.task = "Volume meshing"; + + MESHING3_RESULT res = MeshVolume (mparam, *mesh); + +/* + ofstream problemfile("occmesh.rep",ios_base::app); + + problemfile << "VOLUMEMESHING" << endl << endl; + if(res != MESHING3_OK) + problemfile << "ERROR" << endl << endl; + else + problemfile << "OK" << endl + << mesh->GetNE() << " elements" << endl << endl; + + problemfile.close(); +*/ + + if (res != MESHING3_OK) return TCL_ERROR; + + if (multithread.terminate) return TCL_OK; + + RemoveIllegalElements (*mesh); + if (multithread.terminate) return TCL_OK; + + MeshQuality3d (*mesh); + +#ifdef STAT_STREAM + (*statout) << GetTime() << " & "; +#endif + +#ifdef LOG_STREAM + (*logout) << "Volume meshed" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + } + + if (multithread.terminate || perfstepsend <= MESHCONST_MESHVOLUME) + return TCL_OK; + + if (perfstepsstart <= MESHCONST_OPTVOLUME) + { + multithread.task = "Volume optimization"; + + OptimizeVolume (mparam, *mesh); + if (multithread.terminate) return TCL_OK; + +#ifdef STAT_STREAM + (*statout) << GetTime() << " & " + << mesh->GetNE() << " & " + << mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl; +#endif + +#ifdef LOG_STREAM + (*logout) << "Volume optimized" << endl + << "time = " << GetTime() << " sec" << endl + << "points: " << mesh->GetNP() << endl; +#endif + + // cout << "Optimization complete" << endl; + + } + + (*testout) << "NP: " << mesh->GetNP() << endl; + for (int i = 1; i <= mesh->GetNP(); i++) + (*testout) << mesh->Point(i) << endl; + + (*testout) << endl << "NSegments: " << mesh->GetNSeg() << endl; + for (int i = 1; i <= mesh->GetNSeg(); i++) + (*testout) << mesh->LineSegment(i) << endl; + + return TCL_OK; + } +} + +#endif diff --git a/libsrc/occ/occgeom.cpp b/libsrc/occ/occgeom.cpp new file mode 100644 index 00000000..a363607b --- /dev/null +++ b/libsrc/occ/occgeom.cpp @@ -0,0 +1,1608 @@ + +#ifdef OCCGEOMETRY + +#include +#include +#include "ShapeAnalysis_ShapeTolerance.hxx" +#include "ShapeAnalysis_ShapeContents.hxx" +#include "ShapeAnalysis_CheckSmallFace.hxx" +#include "ShapeAnalysis_DataMapOfShapeListOfReal.hxx" +#include "ShapeAnalysis_Surface.hxx" +#include "BRepAlgoAPI_Fuse.hxx" +#include "BRepCheck_Analyzer.hxx" +#include "BRepLib.hxx" +#include "ShapeBuild_ReShape.hxx" +#include "ShapeFix.hxx" +#include "ShapeFix_FixSmallFace.hxx" +#include "Partition_Spliter.hxx" + + +namespace netgen +{ + void OCCGeometry :: PrintNrShapes () + { + TopExp_Explorer e; + int count = 0; + for (e.Init(shape, TopAbs_COMPSOLID); e.More(); e.Next()) count++; + cout << "CompSolids: " << count << endl; + + cout << "Solids : " << somap.Extent() << endl; + cout << "Shells : " << shmap.Extent() << endl; + cout << "Faces : " << fmap.Extent() << endl; + cout << "Edges : " << emap.Extent() << endl; + cout << "Vertices : " << vmap.Extent() << endl; + } + + + + + void PrintContents (OCCGeometry * geom) + { + ShapeAnalysis_ShapeContents cont; + cont.Clear(); + cont.Perform(geom->shape); + + (*testout) << "OCC CONTENTS" << endl; + (*testout) << "============" << endl; + (*testout) << "SOLIDS : " << cont.NbSolids() << endl; + (*testout) << "SHELLS : " << cont.NbShells() << endl; + (*testout) << "FACES : " << cont.NbFaces() << endl; + (*testout) << "WIRES : " << cont.NbWires() << endl; + (*testout) << "EDGES : " << cont.NbEdges() << endl; + (*testout) << "VERTICES : " << cont.NbVertices() << endl; + + TopExp_Explorer e; + int count = 0; + for (e.Init(geom->shape, TopAbs_COMPOUND); e.More(); e.Next()) + count++; + (*testout) << "Compounds: " << count << endl; + + count = 0; + for (e.Init(geom->shape, TopAbs_COMPSOLID); e.More(); e.Next()) + count++; + (*testout) << "CompSolids: " << count << endl; + + (*testout) << endl; + + cout << "Highest entry in topology hierarchy: " << endl; + if (count) + cout << count << " composite solid(s)" << endl; + else + if (geom->somap.Extent()) + cout << geom->somap.Extent() << " solid(s)" << endl; + else + if (geom->shmap.Extent()) + cout << geom->shmap.Extent() << " shells(s)" << endl; + else + if (geom->fmap.Extent()) + cout << geom->fmap.Extent() << " face(s)" << endl; + else + if (geom->wmap.Extent()) + cout << geom->wmap.Extent() << " wire(s)" << endl; + else + if (geom->emap.Extent()) + cout << geom->emap.Extent() << " edge(s)" << endl; + else + if (geom->vmap.Extent()) + cout << geom->vmap.Extent() << " vertices(s)" << endl; + else + cout << "no entities" << endl; + + } + + + + void OCCGeometry :: HealGeometry () + { + int nrc = 0, nrcs = 0, + nrso = somap.Extent(), + nrsh = shmap.Extent(), + nrf = fmap.Extent(), + nrw = wmap.Extent(), + nre = emap.Extent(), + nrv = vmap.Extent(); + + TopExp_Explorer exp0; + TopExp_Explorer exp1; + + + for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++; + for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++; + + double surfacecont = 0; + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + BuildFMap(); + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face(exp0.Current()); + + GProp_GProps system; + BRepGProp::SurfaceProperties(face, system); + surfacecont += system.Mass(); + } + + + cout << "Starting geometry healing procedure (tolerance: " << tolerance << ")" << endl + << "-----------------------------------" << endl; + + { + cout << endl << "- repairing faces" << endl; + + Handle(ShapeFix_Face) sff; + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + // Variable to hold the colour (if there exists one) of + // the current face being processed + Quantity_Color face_colour; + + TopoDS_Face face = TopoDS::Face (exp0.Current()); + + if(face_colours.IsNull() + || (!(face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour)))) + { + // Set the default face colour to green (Netgen Standard) + // if no colour has been defined for the face + face_colour = Quantity_Color(0.0,1.0,0.0,Quantity_TOC_RGB); + } + + sff = new ShapeFix_Face (face); + sff->FixAddNaturalBoundMode() = Standard_True; + sff->FixSmallAreaWireMode() = Standard_True; + sff->Perform(); + + if(sff->Status(ShapeExtend_DONE1) || + sff->Status(ShapeExtend_DONE2) || + sff->Status(ShapeExtend_DONE3) || + sff->Status(ShapeExtend_DONE4) || + sff->Status(ShapeExtend_DONE5)) + { + cout << "repaired face " << fmap.FindIndex(face) << " "; + if(sff->Status(ShapeExtend_DONE1)) + cout << "(some wires are fixed)" <Status(ShapeExtend_DONE2)) + cout << "(orientation of wires fixed)" <Status(ShapeExtend_DONE3)) + cout << "(missing seam added)" <Status(ShapeExtend_DONE4)) + cout << "(small area wire removed)" <Status(ShapeExtend_DONE5)) + cout << "(natural bounds added)" <Face(); + + rebuild->Replace(face, newface, Standard_False); + } + + // Set the original colour of the face to the newly created + // face (after the healing process) + face = TopoDS::Face (exp0.Current()); + face_colours->SetColor(face,face_colour,XCAFDoc_ColorSurf); + } + shape = rebuild->Apply(shape); + } + + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + + if (fixsmalledges) + { + cout << endl << "- fixing small edges" << endl; + + Handle(ShapeFix_Wire) sfw; + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face(exp0.Current()); + + for (exp1.Init (face, TopAbs_WIRE); exp1.More(); exp1.Next()) + { + TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current()); + sfw = new ShapeFix_Wire (oldwire, face ,tolerance); + sfw->ModifyTopologyMode() = Standard_True; + + sfw->ClosedWireMode() = Standard_True; + + bool replace = false; + + replace = sfw->FixReorder() || replace; + + replace = sfw->FixConnected() || replace; + + + + if (sfw->FixSmall (Standard_False, tolerance) && ! (sfw->StatusSmall(ShapeExtend_FAIL1) || + sfw->StatusSmall(ShapeExtend_FAIL2) || + sfw->StatusSmall(ShapeExtend_FAIL3))) + { + cout << "Fixed small edge in wire " << wmap.FindIndex (oldwire) << endl; + replace = true; + + } + else if (sfw->StatusSmall(ShapeExtend_FAIL1)) + cerr << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) + << ", edge cannot be checked (no 3d curve and no pcurve)" << endl; + else if (sfw->StatusSmall(ShapeExtend_FAIL2)) + cerr << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) + << ", edge is null-length and has different vertives at begin and end, and lockvtx is True or ModifiyTopologyMode is False" << endl; + else if (sfw->StatusSmall(ShapeExtend_FAIL3)) + cerr << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) + << ", CheckConnected has failed" << endl; + + replace = sfw->FixEdgeCurves() || replace; + + replace = sfw->FixDegenerated() || replace; + + replace = sfw->FixSelfIntersection() || replace; + + replace = sfw->FixLacking(Standard_True) || replace; + + if(replace) + { + TopoDS_Wire newwire = sfw->Wire(); + rebuild->Replace(oldwire, newwire, Standard_False); + } + + //delete sfw; sfw = NULL; + + } + } + + shape = rebuild->Apply(shape); + + + + { + BuildFMap(); + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if (vmap.FindIndex(TopExp::FirstVertex (edge)) == + vmap.FindIndex(TopExp::LastVertex (edge))) + { + GProp_GProps system; + BRepGProp::LinearProperties(edge, system); + if (system.Mass() < tolerance) + { + cout << "removing degenerated edge " << emap.FindIndex(edge) + << " from vertex " << vmap.FindIndex(TopExp::FirstVertex (edge)) + << " to vertex " << vmap.FindIndex(TopExp::LastVertex (edge)) << endl; + rebuild->Remove(edge, false); + } + } + } + shape = rebuild->Apply(shape); + + //delete rebuild; rebuild = NULL; + } + + + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + + + + Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe; + sfwf->SetPrecision(tolerance); + sfwf->Load (shape); + sfwf->ModeDropSmallEdges() = Standard_True; + + sfwf->SetPrecision(boundingbox.Diam()); + + if (sfwf->FixWireGaps()) + { + cout << endl << "- fixing wire gaps" << endl; + if (sfwf->StatusWireGaps(ShapeExtend_OK)) cout << "no gaps found" << endl; + if (sfwf->StatusWireGaps(ShapeExtend_DONE1)) cout << "some 2D gaps fixed" << endl; + if (sfwf->StatusWireGaps(ShapeExtend_DONE2)) cout << "some 3D gaps fixed" << endl; + if (sfwf->StatusWireGaps(ShapeExtend_FAIL1)) cout << "failed to fix some 2D gaps" << endl; + if (sfwf->StatusWireGaps(ShapeExtend_FAIL2)) cout << "failed to fix some 3D gaps" << endl; + } + + sfwf->SetPrecision(tolerance); + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 4" << endl; + } + } + + + + if (sfwf->FixSmallEdges()) + { + cout << endl << "- fixing wire frames" << endl; + if (sfwf->StatusSmallEdges(ShapeExtend_OK)) cout << "no small edges found" << endl; + if (sfwf->StatusSmallEdges(ShapeExtend_DONE1)) cout << "some small edges fixed" << endl; + if (sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) cout << "failed to fix some small edges" << endl; + } + + + + shape = sfwf->Shape(); + + //delete sfwf; sfwf = NULL; + //delete rebuild; rebuild = NULL; + + } + + + + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 5" << endl; + } + } + + + + + if (fixspotstripfaces) + { + + cout << endl << "- fixing spot and strip faces" << endl; + Handle(ShapeFix_FixSmallFace) sffsm = new ShapeFix_FixSmallFace(); + sffsm -> Init (shape); + sffsm -> SetPrecision (tolerance); + sffsm -> Perform(); + + shape = sffsm -> FixShape(); + //delete sffsm; sffsm = NULL; + } + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 6" << endl; + } + } + + + + if (sewfaces) + { + cout << endl << "- sewing faces" << endl; + + BRepOffsetAPI_Sewing sewedObj(tolerance); + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face (exp0.Current()); + sewedObj.Add (face); + } + + sewedObj.Perform(); + + if (!sewedObj.SewedShape().IsNull()) + shape = sewedObj.SewedShape(); + else + cout << " not possible"; + } + + + + { + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(shape); + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + rebuild->Remove(edge, false); + } + shape = rebuild->Apply(shape); + } + + + if (makesolids) + { + cout << endl << "- making solids" << endl; + + BRepBuilderAPI_MakeSolid ms; + int count = 0; + for (exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next()) + { + count++; + ms.Add (TopoDS::Shell(exp0.Current())); + } + + if (!count) + { + cout << " not possible (no shells)" << endl; + } + else + { + BRepCheck_Analyzer ba(ms); + if (ba.IsValid ()) + { + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init (ms); + sfs->SetPrecision(tolerance); + sfs->SetMaxTolerance(tolerance); + sfs->Perform(); + shape = sfs->Shape(); + + for (exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()) + { + TopoDS_Solid solid = TopoDS::Solid(exp0.Current()); + TopoDS_Solid newsolid = solid; + BRepLib::OrientClosedSolid (newsolid); + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + // rebuild->Apply(shape); + rebuild->Replace(solid, newsolid, Standard_False); + TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_COMPSOLID);//, 1); + // TopoDS_Shape newshape = rebuild->Apply(shape); + shape = newshape; + } + + //delete sfs; sfs = NULL; + } + else + cout << " not possible" << endl; + } + } + + + + if (splitpartitions) + { + cout << "- running SALOME partition splitter" << endl; + + TopExp_Explorer e2; + Partition_Spliter ps; + int count = 0; + + for (e2.Init (shape, TopAbs_SOLID); + e2.More(); e2.Next()) + { + count++; + ps.AddShape (e2.Current()); + } + + ps.Compute(); + shape = ps.Shape(); + + cout << " before: " << count << " solids" << endl; + + count = 0; + for (e2.Init (shape, TopAbs_SOLID); + e2.More(); e2.Next()) count++; + + cout << " after : " << count << " solids" << endl; + } + + BuildFMap(); + + + + { + for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp1.Current()); + if ( BRep_Tool::Degenerated(edge) ) + cout << "degenerated edge at position 8" << endl; + } + } + + + double newsurfacecont = 0; + + + for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next()) + { + TopoDS_Face face = TopoDS::Face(exp0.Current()); + GProp_GProps system; + BRepGProp::SurfaceProperties(face, system); + newsurfacecont += system.Mass(); + } + + + int nnrc = 0, nnrcs = 0, + nnrso = somap.Extent(), + nnrsh = shmap.Extent(), + nnrf = fmap.Extent(), + nnrw = wmap.Extent(), + nnre = emap.Extent(), + nnrv = vmap.Extent(); + + for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nnrc++; + for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nnrcs++; + + cout << "-----------------------------------" << endl; + cout << "Compounds : " << nnrc << " (" << nrc << ")" << endl; + cout << "Composite solids: " << nnrcs << " (" << nrcs << ")" << endl; + cout << "Solids : " << nnrso << " (" << nrso << ")" << endl; + cout << "Shells : " << nnrsh << " (" << nrsh << ")" << endl; + cout << "Wires : " << nnrw << " (" << nrw << ")" << endl; + cout << "Faces : " << nnrf << " (" << nrf << ")" << endl; + cout << "Edges : " << nnre << " (" << nre << ")" << endl; + cout << "Vertices : " << nnrv << " (" << nrv << ")" << endl; + cout << endl; + cout << "Totol surface area : " << newsurfacecont << " (" << surfacecont << ")" << endl; + cout << endl; + } + + + + + void OCCGeometry :: BuildFMap() + { + somap.Clear(); + shmap.Clear(); + fmap.Clear(); + wmap.Clear(); + emap.Clear(); + vmap.Clear(); + + TopExp_Explorer exp0, exp1, exp2, exp3, exp4, exp5; + + for (exp0.Init(shape, TopAbs_COMPOUND); + exp0.More(); exp0.Next()) + { + TopoDS_Compound compound = TopoDS::Compound (exp0.Current()); + (*testout) << "compound" << endl; + int i = 0; + for (exp1.Init(compound, TopAbs_SHELL); + exp1.More(); exp1.Next()) + { + (*testout) << "shell " << ++i << endl; + } + } + + for (exp0.Init(shape, TopAbs_SOLID); + exp0.More(); exp0.Next()) + { + TopoDS_Solid solid = TopoDS::Solid (exp0.Current()); + + if (somap.FindIndex(solid) < 1) + { + somap.Add (solid); + + for (exp1.Init(solid, TopAbs_SHELL); + exp1.More(); exp1.Next()) + { + TopoDS_Shell shell = TopoDS::Shell (exp1.Current()); + if (shmap.FindIndex(shell) < 1) + { + shmap.Add (shell); + + for (exp2.Init(shell, TopAbs_FACE); + exp2.More(); exp2.Next()) + { + TopoDS_Face face = TopoDS::Face(exp2.Current()); + if (fmap.FindIndex(face) < 1) + { + fmap.Add (face); + (*testout) << "face " << fmap.FindIndex(face) << " "; + (*testout) << ((face.Orientation() == TopAbs_REVERSED) ? "-" : "+") << ", "; + (*testout) << ((exp2.Current().Orientation() == TopAbs_REVERSED) ? "-" : "+") << endl; + for (exp3.Init(exp2.Current(), TopAbs_WIRE); + exp3.More(); exp3.Next()) + { + TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); + if (wmap.FindIndex(wire) < 1) + { + wmap.Add (wire); + + for (exp4.Init(exp3.Current(), TopAbs_EDGE); + exp4.More(); exp4.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); + if (emap.FindIndex(edge) < 1) + { + emap.Add (edge); + for (exp5.Init(exp4.Current(), TopAbs_VERTEX); + exp5.More(); exp5.Next()) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); + if (vmap.FindIndex(vertex) < 1) + vmap.Add (vertex); + } + } + } + } + } + } + } + } + } + } + } + + // Free Shells + for (exp1.Init(shape, TopAbs_SHELL, TopAbs_SOLID); exp1.More(); exp1.Next()) + { + TopoDS_Shell shell = TopoDS::Shell(exp1.Current()); + if (shmap.FindIndex(shell) < 1) + { + shmap.Add (shell); + + (*testout) << "shell " << shmap.FindIndex(shell) << " "; + (*testout) << ((shell.Orientation() == TopAbs_REVERSED) ? "-" : "+") << ", "; + (*testout) << ((exp1.Current().Orientation() == TopAbs_REVERSED) ? "-" : "+") << endl; + + for (exp2.Init(shell, TopAbs_FACE); exp2.More(); exp2.Next()) + { + TopoDS_Face face = TopoDS::Face(exp2.Current()); + if (fmap.FindIndex(face) < 1) + { + fmap.Add (face); + + for (exp3.Init(face, TopAbs_WIRE); exp3.More(); exp3.Next()) + { + TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); + if (wmap.FindIndex(wire) < 1) + { + wmap.Add (wire); + + for (exp4.Init(wire, TopAbs_EDGE); exp4.More(); exp4.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); + if (emap.FindIndex(edge) < 1) + { + emap.Add (edge); + for (exp5.Init(edge, TopAbs_VERTEX); exp5.More(); exp5.Next()) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); + if (vmap.FindIndex(vertex) < 1) + vmap.Add (vertex); + } + } + } + } + } + } + } + } + } + + + // Free Faces + + for (exp2.Init(shape, TopAbs_FACE, TopAbs_SHELL); exp2.More(); exp2.Next()) + { + TopoDS_Face face = TopoDS::Face(exp2.Current()); + if (fmap.FindIndex(face) < 1) + { + fmap.Add (face); + + for (exp3.Init(exp2.Current(), TopAbs_WIRE); exp3.More(); exp3.Next()) + { + TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); + if (wmap.FindIndex(wire) < 1) + { + wmap.Add (wire); + + for (exp4.Init(exp3.Current(), TopAbs_EDGE); exp4.More(); exp4.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); + if (emap.FindIndex(edge) < 1) + { + emap.Add (edge); + for (exp5.Init(exp4.Current(), TopAbs_VERTEX); exp5.More(); exp5.Next()) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); + if (vmap.FindIndex(vertex) < 1) + vmap.Add (vertex); + } + } + } + } + } + } + } + + + // Free Wires + + for (exp3.Init(shape, TopAbs_WIRE, TopAbs_FACE); exp3.More(); exp3.Next()) + { + TopoDS_Wire wire = TopoDS::Wire (exp3.Current()); + if (wmap.FindIndex(wire) < 1) + { + wmap.Add (wire); + + for (exp4.Init(exp3.Current(), TopAbs_EDGE); exp4.More(); exp4.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); + if (emap.FindIndex(edge) < 1) + { + emap.Add (edge); + for (exp5.Init(exp4.Current(), TopAbs_VERTEX); exp5.More(); exp5.Next()) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); + if (vmap.FindIndex(vertex) < 1) + vmap.Add (vertex); + } + } + } + } + } + + + // Free Edges + + for (exp4.Init(shape, TopAbs_EDGE, TopAbs_WIRE); exp4.More(); exp4.Next()) + { + TopoDS_Edge edge = TopoDS::Edge(exp4.Current()); + if (emap.FindIndex(edge) < 1) + { + emap.Add (edge); + for (exp5.Init(exp4.Current(), TopAbs_VERTEX); exp5.More(); exp5.Next()) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); + if (vmap.FindIndex(vertex) < 1) + vmap.Add (vertex); + } + } + } + + + // Free Vertices + + for (exp5.Init(shape, TopAbs_VERTEX, TopAbs_EDGE); exp5.More(); exp5.Next()) + { + TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current()); + if (vmap.FindIndex(vertex) < 1) + vmap.Add (vertex); + } + + + + + facemeshstatus.DeleteAll(); + facemeshstatus.SetSize (fmap.Extent()); + facemeshstatus = 0; + + // Philippose - 15/01/2009 + face_maxh.DeleteAll(); + face_maxh.SetSize (fmap.Extent()); + face_maxh = mparam.maxh; + + // Philippose - 15/01/2010 + face_maxh_modified.DeleteAll(); + face_maxh_modified.SetSize(fmap.Extent()); + face_maxh_modified = 0; + + + // Philippose - 17/01/2009 + face_sel_status.DeleteAll(); + face_sel_status.SetSize (fmap.Extent()); + face_sel_status = 0; + + fvispar.SetSize (fmap.Extent()); + evispar.SetSize (emap.Extent()); + vvispar.SetSize (vmap.Extent()); + + fsingular.SetSize (fmap.Extent()); + esingular.SetSize (emap.Extent()); + vsingular.SetSize (vmap.Extent()); + + fsingular = esingular = vsingular = false; + } + + + + void OCCGeometry :: SewFaces () + { + (*testout) << "Trying to sew faces ..." << endl; + cout << "Trying to sew faces ..." << flush; + + BRepOffsetAPI_Sewing sewedObj(1); + + for (int i = 1; i <= fmap.Extent(); i++) + { + TopoDS_Face face = TopoDS::Face (fmap(i)); + sewedObj.Add (face); + } + + sewedObj.Perform(); + + if (!sewedObj.SewedShape().IsNull()) + { + shape = sewedObj.SewedShape(); + cout << " done" << endl; + } + else + cout << " not possible"; + } + + + + + + void OCCGeometry :: MakeSolid () + { + TopExp_Explorer exp0; + + (*testout) << "Trying to build solids ..." << endl; + cout << "Trying to build solids ..." << flush; + + BRepBuilderAPI_MakeSolid ms; + int count = 0; + for (exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next()) + { + count++; + ms.Add (TopoDS::Shell(exp0.Current())); + } + + if (!count) + { + cout << " not possible (no shells)" << endl; + return; + } + + BRepCheck_Analyzer ba(ms); + if (ba.IsValid ()) + { + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init (ms); + + sfs->SetPrecision(1e-5); + sfs->SetMaxTolerance(1e-5); + + sfs->Perform(); + + shape = sfs->Shape(); + + for (exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next()) + { + TopoDS_Solid solid = TopoDS::Solid(exp0.Current()); + TopoDS_Solid newsolid = solid; + BRepLib::OrientClosedSolid (newsolid); + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Replace(solid, newsolid, Standard_False); + + TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_SHAPE, 1); + shape = newshape; + } + + cout << " done" << endl; + } + else + cout << " not possible" << endl; + } + + + + + void OCCGeometry :: BuildVisualizationMesh (double deflection) + { + cout << "Preparing visualization (deflection = " << deflection << ") ... " << flush; + + BRepTools::Clean (shape); + // BRepMesh_IncrementalMesh:: + BRepMesh_IncrementalMesh (shape, deflection, true); + cout << "done" << endl; + } + + + + + void OCCGeometry :: CalcBoundingBox () + { + Bnd_Box bb; + BRepBndLib::Add (shape, bb); + + double x1,y1,z1,x2,y2,z2; + bb.Get (x1,y1,z1,x2,y2,z2); + Point<3> p1 = Point<3> (x1,y1,z1); + Point<3> p2 = Point<3> (x2,y2,z2); + + (*testout) << "Bounding Box = [" << p1 << " - " << p2 << "]" << endl; + boundingbox = Box<3> (p1,p2); + SetCenter(); + } + + + + + void OCCGeometry :: Project (int surfi, Point<3> & p) const + { + static int cnt = 0; + if (++cnt % 1000 == 0) cout << "Project cnt = " << cnt << endl; + + gp_Pnt pnt(p(0), p(1), p(2)); + + double u,v; + Handle( Geom_Surface ) thesurf = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( thesurf ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(fmap(surfi)) ) ); + suval.Coord( u, v); + pnt = thesurf->Value( u, v ); + + + p = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + + } + + + + + bool OCCGeometry :: FastProject (int surfi, Point<3> & ap, double& u, double& v) const + { + gp_Pnt p(ap(0), ap(1), ap(2)); + + Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); + + gp_Pnt x = surface->Value (u,v); + + if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true; + + gp_Vec du, dv; + + surface->D1(u,v,x,du,dv); + + int count = 0; + + gp_Pnt xold; + gp_Vec n; + double det, lambda, mu; + + do { + count++; + + n = du^dv; + + det = Det3 (n.X(), du.X(), dv.X(), + n.Y(), du.Y(), dv.Y(), + n.Z(), du.Z(), dv.Z()); + + if (det < 1e-15) return false; + + lambda = Det3 (n.X(), p.X()-x.X(), dv.X(), + n.Y(), p.Y()-x.Y(), dv.Y(), + n.Z(), p.Z()-x.Z(), dv.Z())/det; + + mu = Det3 (n.X(), du.X(), p.X()-x.X(), + n.Y(), du.Y(), p.Y()-x.Y(), + n.Z(), du.Z(), p.Z()-x.Z())/det; + + u += lambda; + v += mu; + + xold = x; + surface->D1(u,v,x,du,dv); + + } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) && count < 50); + + // (*testout) << "FastProject count: " << count << endl; + + if (count == 50) return false; + + ap = Point<3> (x.X(), x.Y(), x.Z()); + + return true; + } + + + + + void OCCGeometry :: WriteOCC_STL(char * filename) + { + cout << "writing stl..."; cout.flush(); + StlAPI_Writer writer; + writer.RelativeMode() = Standard_False; + + writer.SetDeflection(0.02); + writer.Write(shape,filename); + + cout << "done" << endl; + } + + + + // Philippose - 23/02/2009 + /* Special IGES File load function including the ability + to extract individual surface colours via the extended + OpenCascade XDE and XCAF Feature set. + */ + OCCGeometry *LoadOCC_IGES(const char *filename) + { + OCCGeometry *occgeo; + occgeo = new OCCGeometry; + + // Initiate a dummy XCAF Application to handle the IGES XCAF Document + static Handle_XCAFApp_Application dummy_app = XCAFApp_Application::GetApplication(); + + // Create an XCAF Document to contain the IGES file itself + Handle_TDocStd_Document iges_doc; + + // Check if a IGES File is already open under this handle, if so, close it to prevent + // Segmentation Faults when trying to create a new document + if(dummy_app->NbDocuments() > 0) + { + dummy_app->GetDocument(1,iges_doc); + dummy_app->Close(iges_doc); + } + dummy_app->NewDocument ("IGES-XCAF",iges_doc); + + IGESCAFControl_Reader reader; + + Standard_Integer stat = reader.ReadFile((char*)filename); + + if(stat != IFSelect_RetDone) + { + delete occgeo; + return NULL; + } + + // Enable transfer of colours + reader.SetColorMode(Standard_True); + + reader.Transfer(iges_doc); + + // Read in the shape(s) and the colours present in the IGES File + Handle_XCAFDoc_ShapeTool iges_shape_contents = XCAFDoc_DocumentTool::ShapeTool(iges_doc->Main()); + Handle_XCAFDoc_ColorTool iges_colour_contents = XCAFDoc_DocumentTool::ColorTool(iges_doc->Main()); + + TDF_LabelSequence iges_shapes; + iges_shape_contents->GetShapes(iges_shapes); + + // List out the available colours in the IGES File as Colour Names + TDF_LabelSequence all_colours; + iges_colour_contents->GetColors(all_colours); + PrintMessage(1,"Number of colours in IGES File: ",all_colours.Length()); + for(int i = 1; i <= all_colours.Length(); i++) + { + Quantity_Color col; + stringstream col_rgb; + iges_colour_contents->GetColor(all_colours.Value(i),col); + col_rgb << " : (" << col.Red() << "," << col.Green() << "," << col.Blue() << ")"; + PrintMessage(1, "Colour [", i, "] = ",col.StringName(col.Name()),col_rgb.str()); + } + + + // For the IGES Reader, all the shapes can be exported as one compund shape + // using the "OneShape" member + occgeo->shape = reader.OneShape(); + occgeo->face_colours = iges_colour_contents; + occgeo->changed = 1; + occgeo->BuildFMap(); + + occgeo->CalcBoundingBox(); + PrintContents (occgeo); + + return occgeo; + } + + + + + + // Philippose - 29/01/2009 + /* Special STEP File load function including the ability + to extract individual surface colours via the extended + OpenCascade XDE and XCAF Feature set. + */ + OCCGeometry * LoadOCC_STEP (const char * filename) + { + OCCGeometry * occgeo; + occgeo = new OCCGeometry; + + // Initiate a dummy XCAF Application to handle the STEP XCAF Document + static Handle_XCAFApp_Application dummy_app = XCAFApp_Application::GetApplication(); + + // Create an XCAF Document to contain the STEP file itself + Handle_TDocStd_Document step_doc; + + // Check if a STEP File is already open under this handle, if so, close it to prevent + // Segmentation Faults when trying to create a new document + if(dummy_app->NbDocuments() > 0) + { + dummy_app->GetDocument(1,step_doc); + dummy_app->Close(step_doc); + } + dummy_app->NewDocument ("STEP-XCAF",step_doc); + + STEPCAFControl_Reader reader; + + // Enable transfer of colours + reader.SetColorMode(Standard_True); + + Standard_Integer stat = reader.ReadFile((char*)filename); + + if(stat != IFSelect_RetDone) + { + delete occgeo; + return NULL; + } + + reader.Transfer(step_doc); + + // Read in the shape(s) and the colours present in the STEP File + Handle_XCAFDoc_ShapeTool step_shape_contents = XCAFDoc_DocumentTool::ShapeTool(step_doc->Main()); + Handle_XCAFDoc_ColorTool step_colour_contents = XCAFDoc_DocumentTool::ColorTool(step_doc->Main()); + + TDF_LabelSequence step_shapes; + step_shape_contents->GetShapes(step_shapes); + + // List out the available colours in the STEP File as Colour Names + TDF_LabelSequence all_colours; + step_colour_contents->GetColors(all_colours); + PrintMessage(1,"Number of colours in STEP File: ",all_colours.Length()); + for(int i = 1; i <= all_colours.Length(); i++) + { + Quantity_Color col; + stringstream col_rgb; + step_colour_contents->GetColor(all_colours.Value(i),col); + col_rgb << " : (" << col.Red() << "," << col.Green() << "," << col.Blue() << ")"; + PrintMessage(1, "Colour [", i, "] = ",col.StringName(col.Name()),col_rgb.str()); + } + + + // For the STEP File Reader in OCC, the 1st Shape contains the entire + // compound geometry as one shape + occgeo->shape = step_shape_contents->GetShape(step_shapes.Value(1)); + occgeo->face_colours = step_colour_contents; + occgeo->changed = 1; + occgeo->BuildFMap(); + + occgeo->CalcBoundingBox(); + PrintContents (occgeo); + + return occgeo; + } + + + + + OCCGeometry *LoadOCC_BREP (const char *filename) + { + OCCGeometry * occgeo; + occgeo = new OCCGeometry; + + BRep_Builder aBuilder; + Standard_Boolean result = BRepTools::Read(occgeo->shape, const_cast (filename),aBuilder); + + if(!result) + { + delete occgeo; + return NULL; + } + + // Philippose - 23/02/2009 + // Fixed a bug in the OpenCascade XDE Colour handling when + // opening BREP Files, since BREP Files have no colour data. + // Hence, the face_colours Handle needs to be created as a NULL handle. + occgeo->face_colours = Handle_XCAFDoc_ColorTool(); + occgeo->face_colours.Nullify(); + occgeo->changed = 1; + occgeo->BuildFMap(); + + occgeo->CalcBoundingBox(); + PrintContents (occgeo); + + return occgeo; + } + + + void OCCGeometry :: Save (string sfilename) const + { + const char * filename = sfilename.c_str(); + if (strlen(filename) < 4) + throw NgException ("illegal filename"); + + if (strcmp (&filename[strlen(filename)-3], "igs") == 0) + { + IGESControl_Writer writer("millimeters", 1); + writer.AddShape (shape); + writer.Write (filename); + } + else if (strcmp (&filename[strlen(filename)-3], "stp") == 0) + { + STEPControl_Writer writer; + writer.Transfer (shape, STEPControl_AsIs); + writer.Write (filename); + } + else if (strcmp (&filename[strlen(filename)-3], "stl") == 0) + { + StlAPI_Writer writer; + writer.ASCIIMode() = Standard_True; + writer.Write (shape, filename); + } + else if (strcmp (&filename[strlen(filename)-4], "stlb") == 0) + { + StlAPI_Writer writer; + writer.ASCIIMode() = Standard_False; + writer.Write (shape, filename); + } + } + + + + const char * shapesname[] = + {" ", "CompSolids", "Solids", "Shells", + + "Faces", "Wires", "Edges", "Vertices"}; + + const char * shapename[] = + {" ", "CompSolid", "Solid", "Shell", + "Face", "Wire", "Edge", "Vertex"}; + + const char * orientationstring[] = + {"+", "-"}; + + + + + void OCCGeometry :: RecursiveTopologyTree (const TopoDS_Shape & sh, + stringstream & str, + TopAbs_ShapeEnum l, + bool isfree, + const char * lname) + { + if (l > TopAbs_VERTEX) return; + + TopExp_Explorer e; + int count = 0; + int count2 = 0; + + if (isfree) + e.Init(sh, l, TopAbs_ShapeEnum(l-1)); + else + e.Init(sh, l); + + for (; e.More(); e.Next()) + { + count++; + + stringstream lname2; + lname2 << lname << "/" << shapename[l] << count; + str << lname2.str() << " "; + + switch (e.Current().ShapeType()) + { + case TopAbs_SOLID: + count2 = somap.FindIndex(TopoDS::Solid(e.Current())); break; + case TopAbs_SHELL: + count2 = shmap.FindIndex(TopoDS::Shell(e.Current())); break; + case TopAbs_FACE: + count2 = fmap.FindIndex(TopoDS::Face(e.Current())); break; + case TopAbs_WIRE: + count2 = wmap.FindIndex(TopoDS::Wire(e.Current())); break; + case TopAbs_EDGE: + count2 = emap.FindIndex(TopoDS::Edge(e.Current())); break; + case TopAbs_VERTEX: + count2 = vmap.FindIndex(TopoDS::Vertex(e.Current())); break; + default: + cout << "RecursiveTopologyTree: Case " << e.Current().ShapeType() << " not handeled" << endl; + } + + int nrsubshapes = 0; + + if (l <= TopAbs_WIRE) + { + TopExp_Explorer e2; + for (e2.Init (e.Current(), TopAbs_ShapeEnum (l+1)); + e2.More(); e2.Next()) + nrsubshapes++; + } + + str << "{" << shapename[l] << " " << count2; + + if (l <= TopAbs_EDGE) + { + str << " (" << orientationstring[e.Current().Orientation()]; + if (nrsubshapes != 0) str << ", " << nrsubshapes; + str << ") } "; + } + else + str << " } "; + + RecursiveTopologyTree (e.Current(), str, TopAbs_ShapeEnum (l+1), + false, (char*)lname2.str().c_str()); + + } + } + + + + + void OCCGeometry :: GetTopologyTree (stringstream & str) + { + cout << "Building topology tree ... " << flush; + RecursiveTopologyTree (shape, str, TopAbs_COMPSOLID, false, "CompSolids"); + RecursiveTopologyTree (shape, str, TopAbs_SOLID, true, "FreeSolids"); + RecursiveTopologyTree (shape, str, TopAbs_SHELL, true, "FreeShells"); + RecursiveTopologyTree (shape, str, TopAbs_FACE, true, "FreeFaces"); + RecursiveTopologyTree (shape, str, TopAbs_WIRE, true, "FreeWires"); + RecursiveTopologyTree (shape, str, TopAbs_EDGE, true, "FreeEdges"); + RecursiveTopologyTree (shape, str, TopAbs_VERTEX, true, "FreeVertices"); + str << flush; + // cout << "done" << endl; + } + + + + + void OCCGeometry :: CheckIrregularEntities(stringstream & str) + { + ShapeAnalysis_CheckSmallFace csm; + + csm.SetTolerance (1e-6); + + TopTools_DataMapOfShapeListOfShape mapEdges; + ShapeAnalysis_DataMapOfShapeListOfReal mapParam; + TopoDS_Compound theAllVert; + + int spotfaces = 0; + int stripsupportfaces = 0; + int singlestripfaces = 0; + int stripfaces = 0; + int facessplitbyvertices = 0; + int stretchedpinfaces = 0; + int smoothpinfaces = 0; + int twistedfaces = 0; + // int edgessamebutnotidentified = 0; + + cout << "checking faces ... " << flush; + + int i; + for (i = 1; i <= fmap.Extent(); i++) + { + TopoDS_Face face = TopoDS::Face (fmap(i)); + TopoDS_Edge e1, e2; + + if (csm.CheckSpotFace (face)) + { + if (!spotfaces++) + str << "SpotFace {Spot face} "; + + (*testout) << "Face " << i << " is a spot face" << endl; + str << "SpotFace/Face" << i << " "; + str << "{Face " << i << " } "; + } + + if (csm.IsStripSupport (face)) + { + if (!stripsupportfaces++) + str << "StripSupportFace {Strip support face} "; + + (*testout) << "Face " << i << " has strip support" << endl; + str << "StripSupportFace/Face" << i << " "; + str << "{Face " << i << " } "; + } + + if (csm.CheckSingleStrip(face, e1, e2)) + { + if (!singlestripfaces++) + str << "SingleStripFace {Single strip face} "; + + (*testout) << "Face " << i << " is a single strip (edge " << emap.FindIndex(e1) + << " and edge " << emap.FindIndex(e2) << " are identical)" << endl; + str << "SingleStripFace/Face" << i << " "; + str << "{Face " << i << " (edge " << emap.FindIndex(e1) + << " and edge " << emap.FindIndex(e2) << " are identical)} "; + } + + if (csm.CheckStripFace(face, e1, e2)) + { + if (!stripfaces++) + str << "StripFace {Strip face} "; + + (*testout) << "Face " << i << " is a strip (edge " << emap.FindIndex(e1) + << " and edge " << emap.FindIndex(e2) + << " are identical)" << endl; + str << "StripFace/Face" << i << " "; + str << "{Face " << i << " (edge " << emap.FindIndex(e1) + << " and edge " << emap.FindIndex(e2) << " are identical)} "; + } + + if (int count = csm.CheckSplittingVertices(face, mapEdges, mapParam, theAllVert)) + { + if (!facessplitbyvertices++) + str << "FaceSplitByVertices {Face split by vertices} "; + + (*testout) << "Face " << i << " is split by " << count + << " vertex/vertices " << endl; + str << "FaceSplitByVertices/Face" << i << " "; + str << "{Face " << i << " (split by " << count << "vertex/vertices)} "; + } + + int whatrow, sens; + if (int type = csm.CheckPin (face, whatrow, sens)) + { + if (type == 1) + { + if (!smoothpinfaces++) + str << "SmoothPinFace {Smooth pin face} "; + + (*testout) << "Face " << i << " is a smooth pin" << endl; + str << "SmoothPinFace/Face" << i << " "; + str << "{Face " << i << " } "; + } + else + { + if (!stretchedpinfaces++) + str << "StretchedPinFace {Stretched pin face} "; + + (*testout) << "Face " << i << " is a streched pin" << endl; + str << "StretchedPinFace/Face" << i << " "; + str << "{Face " << i << " } "; + } + } + + double paramu, paramv; + if (csm.CheckTwisted (face, paramu, paramv)) + { + if (!twistedfaces++) + str << "TwistedFace {Twisted face} "; + + (*testout) << "Face " << i << " is twisted" << endl; + str << "TwistedFace/Face" << i << " "; + str << "{Face " << i << " } "; + } + } + + cout << "done" << endl; + cout << "checking edges ... " << flush; + + // double dmax; + // int cnt = 0; + Array edgeLengths; + Array order; + edgeLengths.SetSize (emap.Extent()); + order.SetSize (emap.Extent()); + + for (i = 1; i <= emap.Extent(); i++) + { + TopoDS_Edge edge1 = TopoDS::Edge (emap(i)); + GProp_GProps system; + BRepGProp::LinearProperties(edge1, system); + edgeLengths[i-1] = system.Mass(); + } + + Sort (edgeLengths, order); + + str << "ShortestEdges {Shortest edges} "; + for (i = 1; i <= min(20, emap.Extent()); i++) + { + str << "ShortestEdges/Edge" << i; + str << " {Edge " << order[i-1] << " (L=" << edgeLengths[order[i-1]-1] << ")} "; + } + + str << flush; + + cout << "done" << endl; + } + + + + + void OCCGeometry :: GetUnmeshedFaceInfo (stringstream & str) + { + for (int i = 1; i <= fmap.Extent(); i++) + { + if (facemeshstatus[i-1] == -1) + str << "Face" << i << " {Face " << i << " } "; + } + str << flush; + } + + + + + void OCCGeometry :: GetNotDrawableFaces (stringstream & str) + { + for (int i = 1; i <= fmap.Extent(); i++) + { + if (!fvispar[i-1].IsDrawable()) + str << "Face" << i << " {Face " << i << " } "; + } + str << flush; + } + + + + + bool OCCGeometry :: ErrorInSurfaceMeshing () + { + for (int i = 1; i <= fmap.Extent(); i++) + if (facemeshstatus[i-1] == -1) + return true; + + return false; + } + + + + + int OCCGeometry :: GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend) + { + return OCCGenerateMesh (*this, mesh, mparam, perfstepsstart, perfstepsend); + } + + + + + const Refinement & OCCGeometry :: GetRefinement () const + { + return * new OCCRefinementSurfaces (*this); + } + + + + + OCCParameters :: OCCParameters() + { + resthcloseedgefac = 1; + resthcloseedgeenable = 1; + } + + + + + void OCCParameters :: Print(ostream & ost) const + { + ost << "OCC Parameters:" << endl + << "close edges: " << resthcloseedgeenable + << ", fac = " << resthcloseedgefac << endl; + } + + + + + OCCParameters occparam; + +} + + +#endif diff --git a/libsrc/occ/occgeom.hpp b/libsrc/occ/occgeom.hpp new file mode 100644 index 00000000..16b2f761 --- /dev/null +++ b/libsrc/occ/occgeom.hpp @@ -0,0 +1,451 @@ +#ifndef FILE_OCCGEOM +#define FILE_OCCGEOM + +/* *************************************************************************/ +/* File: occgeom.hpp */ +/* Author: Robert Gaisbauer */ +/* Date: 26. May 03 */ +/* *************************************************************************/ + +#ifdef OCCGEOMETRY + +#include + +#include "BRep_Tool.hxx" +#include "Geom_Curve.hxx" +#include "Geom2d_Curve.hxx" +#include "Geom_Surface.hxx" +#include "GeomAPI_ProjectPointOnSurf.hxx" +#include "GeomAPI_ProjectPointOnCurve.hxx" +#include "BRepTools.hxx" +#include "TopExp.hxx" +#include "BRepBuilderAPI_MakeVertex.hxx" +#include "BRepBuilderAPI_MakeShell.hxx" +#include "BRepBuilderAPI_MakeSolid.hxx" +#include "BRepOffsetAPI_Sewing.hxx" +#include "BRepLProp_SLProps.hxx" +#include "BRepAdaptor_Surface.hxx" +#include "Poly_Triangulation.hxx" +#include "Poly_Array1OfTriangle.hxx" +#include "TColgp_Array1OfPnt2d.hxx" +#include "Poly_Triangle.hxx" +#include "GProp_GProps.hxx" +#include "BRepGProp.hxx" +#include "Geom_Surface.hxx" +#include "TopExp.hxx" +#include "gp_Pnt.hxx" +#include "TopoDS.hxx" +#include "TopoDS_Solid.hxx" +#include "TopExp_Explorer.hxx" +#include "TopTools_ListIteratorOfListOfShape.hxx" +#include "BRep_Tool.hxx" +#include "Geom_Curve.hxx" +#include "Geom2d_Curve.hxx" +#include "Geom_Surface.hxx" +#include "GeomAPI_ProjectPointOnSurf.hxx" +#include "GeomAPI_ProjectPointOnCurve.hxx" +#include "TopoDS_Wire.hxx" +#include "BRepTools_WireExplorer.hxx" +#include "BRepTools.hxx" +#include "TopTools_IndexedMapOfShape.hxx" +#include "TopExp.hxx" +#include "BRepBuilderAPI_MakeVertex.hxx" +#include "BRepBuilderAPI_MakeShell.hxx" +#include "BRepBuilderAPI_MakeSolid.hxx" +#include "BRepOffsetAPI_Sewing.hxx" +#include "BRepLProp_CLProps.hxx" +#include "BRepLProp_SLProps.hxx" +#include "BRepAdaptor_Surface.hxx" +#include "BRepAdaptor_Curve.hxx" +#include "Poly_Triangulation.hxx" +#include "Poly_Array1OfTriangle.hxx" +#include "TColgp_Array1OfPnt2d.hxx" +#include "Poly_Triangle.hxx" +#include "GProp_GProps.hxx" +#include "BRepGProp.hxx" +#include "TopoDS_Shape.hxx" +#include "TopoDS_Face.hxx" +#include "IGESToBRep_Reader.hxx" +#include "Interface_Static.hxx" +#include "GeomAPI_ExtremaCurveCurve.hxx" +#include "Standard_ErrorHandler.hxx" +#include "Standard_Failure.hxx" +#include "ShapeUpgrade_ShellSewing.hxx" +#include "ShapeFix_Shape.hxx" +#include "ShapeFix_Wireframe.hxx" +#include "BRepMesh.hxx" +#include "BRepMesh_IncrementalMesh.hxx" +#include "BRepBndLib.hxx" +#include "Bnd_Box.hxx" +#include "ShapeAnalysis.hxx" +#include "ShapeBuild_ReShape.hxx" + + +// Philippose - 29/01/2009 +// OpenCascade XDE Support +// Include support for OpenCascade XDE Features +#include "TDocStd_Document.hxx" +#include "Quantity_Color.hxx" +#include "XCAFApp_Application.hxx" +#include "XCAFDoc_ShapeTool.hxx" +#include "XCAFDoc_Color.hxx" +#include "XCAFDoc_ColorTool.hxx" +#include "XCAFDoc_ColorType.hxx" +#include "XCAFDoc_LayerTool.hxx" +#include "XCAFDoc_DimTolTool.hxx" +#include "XCAFDoc_MaterialTool.hxx" +#include "XCAFDoc_DocumentTool.hxx" +#include "TDF_Label.hxx" +#include "TDF_LabelSequence.hxx" +#include "STEPCAFControl_Reader.hxx" +#include "STEPCAFControl_Writer.hxx" +#include "IGESCAFControl_Reader.hxx" +#include "IGESCAFControl_Writer.hxx" + +#include "IGESControl_Reader.hxx" +#include "STEPControl_Reader.hxx" +#include "IGESControl_Writer.hxx" +#include "STEPControl_Writer.hxx" + +#include "StlAPI_Writer.hxx" +#include "STEPControl_StepModelType.hxx" + +namespace netgen +{ +#include "occmeshsurf.hpp" + + extern DLL_HEADER MeshingParameters mparam; + +#define PROJECTION_TOLERANCE 1e-10 + +#define ENTITYISVISIBLE 1 +#define ENTITYISHIGHLIGHTED 2 +#define ENTITYISDRAWABLE 4 + +#define OCCGEOMETRYVISUALIZATIONNOCHANGE 0 +#define OCCGEOMETRYVISUALIZATIONFULLCHANGE 1 // Compute transformation matrices and redraw +#define OCCGEOMETRYVISUALIZATIONHALFCHANGE 2 // Redraw + + + + class EntityVisualizationCode + { + int code; + + public: + + EntityVisualizationCode() + { code = ENTITYISVISIBLE + !ENTITYISHIGHLIGHTED + ENTITYISDRAWABLE;} + + int IsVisible () + { return code & ENTITYISVISIBLE;} + + int IsHighlighted () + { return code & ENTITYISHIGHLIGHTED;} + + int IsDrawable () + { return code & ENTITYISDRAWABLE;} + + void Show () + { code |= ENTITYISVISIBLE;} + + void Hide () + { code &= ~ENTITYISVISIBLE;} + + void Highlight () + { code |= ENTITYISHIGHLIGHTED;} + + void Lowlight () + { code &= ~ENTITYISHIGHLIGHTED;} + + void SetDrawable () + { code |= ENTITYISDRAWABLE;} + + void SetNotDrawable () + { code &= ~ENTITYISDRAWABLE;} + }; + + + + class Line + { + public: + Point<3> p0, p1; + + double Dist (Line l); + + double Length (); + }; + + + + inline double Det3 (double a00, double a01, double a02, + double a10, double a11, double a12, + double a20, double a21, double a22) + { + return a00*a11*a22 + a01*a12*a20 + a10*a21*a02 - a20*a11*a02 - a10*a01*a22 - a21*a12*a00; + } + + + + + class OCCGeometry : public NetgenGeometry + { + Point<3> center; + + public: + TopoDS_Shape shape; + TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap; + Array fsingular, esingular, vsingular; + Box<3> boundingbox; + + // Philippose - 29/01/2009 + // OpenCascade XDE Support + // XCAF Handle to make the face colours available to the rest of + // the system + Handle_XCAFDoc_ColorTool face_colours; + + mutable int changed; + Array facemeshstatus; + + // Philippose - 15/01/2009 + // Maximum mesh size for a given face + // (Used to explicitly define mesh size limits on individual faces) + Array face_maxh; + + // Philippose - 14/01/2010 + // Boolean array to detect whether a face has been explicitly modified + // by the user or not + Array face_maxh_modified; + + // Philippose - 15/01/2009 + // Indicates which faces have been selected by the user in geometry mode + // (Currently handles only selection of one face at a time, but an array would + // help to extend this to multiple faces) + Array face_sel_status; + + Array fvispar, evispar, vvispar; + + double tolerance; + bool fixsmalledges; + bool fixspotstripfaces; + bool sewfaces; + bool makesolids; + bool splitpartitions; + + OCCGeometry() + { + somap.Clear(); + shmap.Clear(); + fmap.Clear(); + wmap.Clear(); + emap.Clear(); + vmap.Clear(); + } + + + virtual void Save (string filename) const; + + + void BuildFMap(); + + Box<3> GetBoundingBox() + { return boundingbox;} + + int NrSolids() + { return somap.Extent();} + + // Philippose - 17/01/2009 + // Total number of faces in the geometry + int NrFaces() + { return fmap.Extent();} + + void SetCenter() + { center = boundingbox.Center();} + + Point<3> Center() + { return center;} + + void Project (int surfi, Point<3> & p) const; + bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const; + + OCCSurface GetSurface (int surfi) + { + cout << "OCCGeometry::GetSurface using PLANESPACE" << endl; + return OCCSurface (TopoDS::Face(fmap(surfi)), PLANESPACE); + } + + void CalcBoundingBox (); + void BuildVisualizationMesh (double deflection); + + void RecursiveTopologyTree (const TopoDS_Shape & sh, + stringstream & str, + TopAbs_ShapeEnum l, + bool free, + const char * lname); + + void GetTopologyTree (stringstream & str); + + void PrintNrShapes (); + + void CheckIrregularEntities (stringstream & str); + + void SewFaces(); + + void MakeSolid(); + + void HealGeometry(); + + // Philippose - 15/01/2009 + // Sets the maximum mesh size for a given face + // (Note: Local mesh size limited by the global max mesh size) + void SetFaceMaxH(int facenr, double faceh) + { + if((facenr> 0) && (facenr <= fmap.Extent())) + { + face_maxh[facenr-1] = min(mparam.maxh,faceh); + + // Philippose - 14/01/2010 + // If the face maxh is greater than or equal to the + // current global maximum, then identify the face as + // not explicitly controlled by the user any more + if(faceh >= mparam.maxh) + { + face_maxh_modified[facenr-1] = 0; + } + else + { + face_maxh_modified[facenr-1] = 1; + } + } + } + + // Philippose - 15/01/2009 + // Returns the local mesh size of a given face + double GetFaceMaxH(int facenr) + { + if((facenr> 0) && (facenr <= fmap.Extent())) + { + return face_maxh[facenr-1]; + } + else + { + return 0.0; + } + } + + // Philippose - 14/01/2010 + // Returns the flag whether the given face + // has a mesh size controlled by the user or not + bool GetFaceMaxhModified(int facenr) + { + return face_maxh_modified[facenr-1]; + } + + // Philippose - 17/01/2009 + // Returns the index of the currently selected face + int SelectedFace() + { + int i; + + for(i = 1; i <= fmap.Extent(); i++) + { + if(face_sel_status[i-1]) + { + return i; + } + } + + return 0; + } + + // Philippose - 17/01/2009 + // Sets the currently selected face + void SetSelectedFace(int facenr) + { + face_sel_status = 0; + + if((facenr >= 1) && (facenr <= fmap.Extent())) + { + face_sel_status[facenr-1] = 1; + } + } + + void LowLightAll() + { + for (int i = 1; i <= fmap.Extent(); i++) + fvispar[i-1].Lowlight(); + for (int i = 1; i <= emap.Extent(); i++) + evispar[i-1].Lowlight(); + for (int i = 1; i <= vmap.Extent(); i++) + vvispar[i-1].Lowlight(); + } + + void GetUnmeshedFaceInfo (stringstream & str); + void GetNotDrawableFaces (stringstream & str); + bool ErrorInSurfaceMeshing (); + + void WriteOCC_STL(char * filename); + + virtual int GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend); + + virtual const Refinement & GetRefinement () const; + }; + + + + class OCCParameters + { + public: + + /// Factor for meshing close edges + double resthcloseedgefac; + + + /// Enable / Disable detection of close edges + int resthcloseedgeenable; + + + + /*! + Default Constructor for the OpenCascade + Mesh generation parameter set + */ + OCCParameters(); + + + /*! + Dump all the OpenCascade specific meshing parameters + to console + */ + void Print (ostream & ost) const; + }; + + + void PrintContents (OCCGeometry * geom); + + OCCGeometry * LoadOCC_IGES (const char * filename); + OCCGeometry * LoadOCC_STEP (const char * filename); + OCCGeometry * LoadOCC_BREP (const char * filename); + + extern OCCParameters occparam; + + + // Philippose - 31.09.2009 + // External access to the mesh generation functions within the OCC + // subsystem (Not sure if this is the best way to implement this....!!) + extern int OCCGenerateMesh (OCCGeometry & occgeometry, Mesh*& mesh, + MeshingParameters & mparam, + int perfstepsstart, int perfstepsend); + + extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); + + extern void OCCMeshSurface (OCCGeometry & geom, Mesh & mesh, int perfstepsend); + + extern void OCCFindEdges (OCCGeometry & geom, Mesh & mesh); +} + +#endif + +#endif diff --git a/libsrc/occ/occmeshsurf.cpp b/libsrc/occ/occmeshsurf.cpp new file mode 100644 index 00000000..a1f60db6 --- /dev/null +++ b/libsrc/occ/occmeshsurf.cpp @@ -0,0 +1,735 @@ +#ifdef OCCGEOMETRY + +#include + +#include +#include +#include +#include + + +namespace netgen +{ +#include "occmeshsurf.hpp" + + + bool glob_testout(false); + + void OCCSurface :: GetNormalVector (const Point<3> & p, + const PointGeomInfo & geominfo, + Vec<3> & n) const + { + gp_Pnt pnt; + gp_Vec du, dv; + + /* + double gu = geominfo.u; + double gv = geominfo.v; + + if (fabs (gu) < 1e-3) gu = 0; + if (fabs (gv) < 1e-3) gv = 0; + + occface->D1(gu,gv,pnt,du,dv); + */ + + /* + occface->D1(geominfo.u,geominfo.v,pnt,du,dv); + + n = Cross (Vec<3>(du.X(), du.Y(), du.Z()), + Vec<3>(dv.X(), dv.Y(), dv.Z())); + n.Normalize(); + */ + + + + GeomLProp_SLProps lprop(occface,geominfo.u,geominfo.v,1,1e-5); + double setu=geominfo.u,setv=geominfo.v; + + if(lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5) + { + double ustep = 0.01*(umax-umin); + double vstep = 0.01*(vmax-vmin); + + n=0; + + while(setu < umax && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setu += ustep; + if(setu < umax) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setu = geominfo.u; + while(setu > umin && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setu -= ustep; + if(setu > umin) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setu = geominfo.u; + + while(setv < vmax && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setv += ustep; + if(setv < vmax) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setv = geominfo.v; + while(setv > vmin && (lprop.D1U().Magnitude() < 1e-5 || lprop.D1V().Magnitude() < 1e-5)) + setv -= ustep; + if(setv > vmin) + { + lprop.SetParameters(setu,setv); + n(0)+=lprop.Normal().X(); + n(1)+=lprop.Normal().Y(); + n(2)+=lprop.Normal().Z(); + } + setv = geominfo.v; + + n.Normalize(); + } + else + { + n(0)=lprop.Normal().X(); + n(1)=lprop.Normal().Y(); + n(2)=lprop.Normal().Z(); + } + + if(glob_testout) + { + (*testout) << "u " << geominfo.u << " v " << geominfo.v + << " du " << lprop.D1U().X() << " "<< lprop.D1U().Y() << " "<< lprop.D1U().Z() + << " dv " << lprop.D1V().X() << " "<< lprop.D1V().Y() << " "<< lprop.D1V().Z() << endl; + } + + + + if (orient == TopAbs_REVERSED) n = -1*n; + // (*testout) << "GetNormalVector" << endl; + } + + + void OCCSurface :: DefineTangentialPlane (const Point<3> & ap1, + const PointGeomInfo & geominfo1, + const Point<3> & ap2, + const PointGeomInfo & geominfo2) + { + if (projecttype == PLANESPACE) + { + p1 = ap1; p2 = ap2; + + //cout << "p1 = " << p1 << endl; + //cout << "p2 = " << p2 << endl; + + GetNormalVector (p1, geominfo1, ez); + + ex = p2 - p1; + ex -= (ex * ez) * ez; + ex.Normalize(); + ey = Cross (ez, ex); + + GetNormalVector (p2, geominfo2, n2); + + nmid = 0.5*(n2+ez); + + ez = nmid; + ez.Normalize(); + + ex = (p2 - p1).Normalize(); + ez -= (ez * ex) * ex; + ez.Normalize(); + ey = Cross (ez, ex); + nmid = ez; + //cout << "ex " << ex << " ey " << ey << " ez " << ez << endl; + } + else + { + if ( (geominfo1.u < umin) || + (geominfo1.u > umax) || + (geominfo2.u < umin) || + (geominfo2.u > umax) || + (geominfo1.v < vmin) || + (geominfo1.v > vmax) || + (geominfo2.v < vmin) || + (geominfo2.v > vmax) ) throw UVBoundsException(); + + + p1 = ap1; p2 = ap2; + psp1 = Point<2>(geominfo1.u, geominfo1.v); + psp2 = Point<2>(geominfo2.u, geominfo2.v); + + Vec<3> n; + GetNormalVector (p1, geominfo1, n); + + gp_Pnt pnt; + gp_Vec du, dv; + occface->D1 (geominfo1.u, geominfo1.v, pnt, du, dv); + + DenseMatrix D1(3,2), D1T(2,3), DDTinv(2,2); + D1(0,0) = du.X(); D1(1,0) = du.Y(); D1(2,0) = du.Z(); + D1(0,1) = dv.X(); D1(1,1) = dv.Y(); D1(2,1) = dv.Z(); + + /* + (*testout) << "DefineTangentialPlane" << endl + << "---------------------" << endl; + (*testout) << "D1 = " << endl << D1 << endl; + */ + + Transpose (D1, D1T); + DenseMatrix D1TD1(3,3); + + D1TD1 = D1T*D1; + if (D1TD1.Det() == 0) throw SingularMatrixException(); + + CalcInverse (D1TD1, DDTinv); + DenseMatrix Y(3,2); + Vec<3> y1 = (ap2-ap1).Normalize(); + Vec<3> y2 = Cross(n, y1).Normalize(); + for (int i = 0; i < 3; i++) + { + Y(i,0) = y1(i); + Y(i,1) = y2(i); + } + + DenseMatrix A(2,2); + A = DDTinv * D1T * Y; + DenseMatrix Ainv(2,2); + + if (A.Det() == 0) throw SingularMatrixException(); + + CalcInverse (A, Ainv); + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + { + Amat(i,j) = A(i,j); + Amatinv(i,j) = Ainv(i,j); + } + + Vec<2> temp = Amatinv * (psp2-psp1); + + + double r = temp.Length(); + // double alpha = -acos (temp(0)/r); + double alpha = -atan2 (temp(1),temp(0)); + DenseMatrix R(2,2); + R(0,0) = cos (alpha); + R(1,0) = -sin (alpha); + R(0,1) = sin (alpha); + R(1,1) = cos (alpha); + + + A = A*R; + + if (A.Det() == 0) throw SingularMatrixException(); + + CalcInverse (A, Ainv); + + + for (int i = 0; i < 2; i++) + for (int j = 0; j < 2; j++) + { + Amat(i,j) = A(i,j); + Amatinv(i,j) = Ainv(i,j); + } + + temp = Amatinv * (psp2-psp1); + + }; + + } + + + void OCCSurface :: ToPlane (const Point<3> & p3d, + const PointGeomInfo & geominfo, + Point<2> & pplane, + double h, int & zone) const + { + if (projecttype == PLANESPACE) + { + Vec<3> p1p, n; + GetNormalVector (p3d, geominfo, n); + + p1p = p3d - p1; + pplane(0) = (p1p * ex) / h; + pplane(1) = (p1p * ey) / h; + + if (n * nmid < 0) + zone = -1; + else + zone = 0; + + /* + if(zone == -1) + { + (*testout) << "zone = -1 for " << p3d << " 2D: " << pplane << " n " << n << " nmid " << nmid << endl; + glob_testout = true; + GetNormalVector (p3d, geominfo, n); + glob_testout = false; + } + */ + } + else + { + pplane = Point<2>(geominfo.u, geominfo.v); + // (*testout) << "(u,v) = " << geominfo.u << ", " << geominfo.v << endl; + pplane = Point<2> (1/h * (Amatinv * (pplane-psp1))); + // pplane = Point<2> (h * (Amatinv * (pplane-psp1))); + // pplane = Point<2> (1/h * ((pplane-psp1))); + + zone = 0; + }; + } + + + void OCCSurface :: FromPlane (const Point<2> & pplane, + Point<3> & p3d, + PointGeomInfo & gi, + double h) + { + if (projecttype == PLANESPACE) + { + // cout << "2d : " << pplane << endl; + p3d = p1 + (h * pplane(0)) * ex + (h * pplane(1)) * ey; + // cout << "3d : " << p3d << endl; + Project (p3d, gi); + // cout << "proj : " << p3d << endl; + } + else + { + // Point<2> pspnew = Point<2>(1/h * (Amat * Vec<2>(pplane)) + Vec<2>(psp1)); + Point<2> pspnew = Point<2>(h * (Amat * Vec<2>(pplane)) + Vec<2>(psp1)); + // Point<2> pspnew = Point<2>(h * (Vec<2>(pplane)) + Vec<2>(psp1)); + gi.u = pspnew(0); + gi.v = pspnew(1); + gi.trignum = 1; + gp_Pnt val = occface->Value (gi.u, gi.v); + p3d = Point<3> (val.X(), val.Y(), val.Z()); + }; + } + + + + void OCCSurface :: Project (Point<3> & p, PointGeomInfo & gi) + { + // static int cnt = 0; + // if (cnt++ % 1000 == 0) cout << "********************************************** OCCSurfce :: Project, cnt = " << cnt << endl; + + gp_Pnt pnt(p(0), p(1), p(2)); + + //(*testout) << "pnt = " << pnt.X() << ", " << pnt.Y() << ", " << pnt.Z() << endl; + + + /* + GeomAPI_ProjectPointOnSurf proj(pnt, occface, umin, umax, vmin, vmax); + + if (!proj.NbPoints()) + { + cout << "Project Point on Surface FAIL" << endl; + throw UVBoundsException(); + } + */ + + + + + + /* + cout << "NP = " << proj.NbPoints() << endl; + + for (int i = 1; i <= proj.NbPoints(); i++) + { + gp_Pnt pnt2 = proj.Point(i); + Point<3> p2 = Point<3> (pnt2.X(), pnt2.Y(), pnt2.Z()); + cout << i << ". p = " << p2 << ", dist = " << (p2-p).Length() << endl; + } + */ + + /* + pnt = proj.NearestPoint(); + proj.LowerDistanceParameters (gi.u, gi.v); + */ + + double u,v; + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( topods_face ) ); + suval.Coord( u, v); + pnt = occface->Value( u, v ); + + //(*testout) << "pnt(proj) = " << pnt.X() << ", " << pnt.Y() << ", " << pnt.Z() << endl; + gi.u = u; + gi.v = v; + + + gi.trignum = 1; + + p = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + } + + + Meshing2OCCSurfaces :: Meshing2OCCSurfaces (const TopoDS_Shape & asurf, + const Box<3> & abb, int aprojecttype) + : Meshing2(mparam, Box<3>(abb.PMin(), abb.PMax())), surface(TopoDS::Face(asurf), aprojecttype) + { + ; + } + + + void Meshing2OCCSurfaces :: DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo1, + const PointGeomInfo * geominfo2) + { + ((OCCSurface&)surface).DefineTangentialPlane (p1, *geominfo1, p2, *geominfo2); + } + + void Meshing2OCCSurfaces :: TransformToPlain (const Point3d & locpoint, + const MultiPointGeomInfo & geominfo, + Point2d & planepoint, + double h, int & zone) + { + Point<2> hp; + surface.ToPlane (locpoint, geominfo.GetPGI(1), hp, h, zone); + planepoint.X() = hp(0); + planepoint.Y() = hp(1); + } + + int Meshing2OCCSurfaces :: TransformFromPlain (Point2d & planepoint, + Point3d & locpoint, + PointGeomInfo & gi, + double h) + { + Point<3> hp; + Point<2> hp2 (planepoint.X(), planepoint.Y()); + surface.FromPlane (hp2, hp, gi, h); + locpoint = hp; + return 0; + } + + + + double Meshing2OCCSurfaces :: CalcLocalH (const Point3d & p, double gh) const + { + return gh; + } + + + + + + + MeshOptimize2dOCCSurfaces :: MeshOptimize2dOCCSurfaces (const OCCGeometry & ageometry) + : MeshOptimize2d(), geometry(ageometry) + { + ; + } + + + void MeshOptimize2dOCCSurfaces :: ProjectPoint (INDEX surfind, Point<3> & p) const + { + geometry.Project (surfind, p); + } + + + int MeshOptimize2dOCCSurfaces :: ProjectPointGI (INDEX surfind, Point<3> & p, PointGeomInfo & gi) const + { + double u = gi.u; + double v = gi.v; + + Point<3> hp = p; + if (geometry.FastProject (surfind, hp, u, v)) + { + p = hp; + return 1; + } + ProjectPoint (surfind, p); + return CalcPointGeomInfo (surfind, gi, p); + } + + + void MeshOptimize2dOCCSurfaces :: ProjectPoint2 (INDEX surfind, INDEX surfind2, + Point<3> & p) const + { + TopExp_Explorer exp0, exp1; + bool done = false; + Handle(Geom_Curve) c; + + for (exp0.Init(geometry.fmap(surfind), TopAbs_EDGE); !done && exp0.More(); exp0.Next()) + for (exp1.Init(geometry.fmap(surfind2), TopAbs_EDGE); !done && exp1.More(); exp1.Next()) + { + if (TopoDS::Edge(exp0.Current()).IsSame(TopoDS::Edge(exp1.Current()))) + { + done = true; + double s0, s1; + c = BRep_Tool::Curve(TopoDS::Edge(exp0.Current()), s0, s1); + } + } + + gp_Pnt pnt(p(0), p(1), p(2)); + GeomAPI_ProjectPointOnCurve proj(pnt, c); + pnt = proj.NearestPoint(); + p(0) = pnt.X(); + p(1) = pnt.Y(); + p(2) = pnt.Z(); + + } + + void MeshOptimize2dOCCSurfaces :: + GetNormalVector(INDEX surfind, const Point<3> & p, PointGeomInfo & geominfo, Vec<3> & n) const + { + gp_Pnt pnt; + gp_Vec du, dv; + + Handle(Geom_Surface) occface; + occface = BRep_Tool::Surface(TopoDS::Face(geometry.fmap(surfind))); + + occface->D1(geominfo.u,geominfo.v,pnt,du,dv); + + n = Cross (Vec<3>(du.X(), du.Y(), du.Z()), + Vec<3>(dv.X(), dv.Y(), dv.Z())); + n.Normalize(); + + if (geometry.fmap(surfind).Orientation() == TopAbs_REVERSED) n = -1*n; + + // GetNormalVector (surfind, p, n); + } + + + void MeshOptimize2dOCCSurfaces :: + GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const + { + // static int cnt = 0; + // if (cnt++ % 1000 == 0) cout << "GetNV cnt = " << cnt << endl; + Standard_Real u,v; + + gp_Pnt pnt(p(0), p(1), p(2)); + + Handle(Geom_Surface) occface; + occface = BRep_Tool::Surface(TopoDS::Face(geometry.fmap(surfind))); + + /* + GeomAPI_ProjectPointOnSurf proj(pnt, occface); + + if (proj.NbPoints() < 1) + { + cout << "ERROR: OCCSurface :: GetNormalVector: GeomAPI_ProjectPointOnSurf failed!" + << endl; + cout << p << endl; + return; + } + + proj.LowerDistanceParameters (u, v); + */ + + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(geometry.fmap(surfind)) ) ); + suval.Coord( u, v); + pnt = occface->Value( u, v ); + + + + gp_Vec du, dv; + occface->D1(u,v,pnt,du,dv); + + /* + if (!occface->IsCNu (1) || !occface->IsCNv (1)) + (*testout) << "SurfOpt: Differentiation FAIL" << endl; + */ + + n = Cross (Vec3d(du.X(), du.Y(), du.Z()), + Vec3d(dv.X(), dv.Y(), dv.Z())); + n.Normalize(); + + if (geometry.fmap(surfind).Orientation() == TopAbs_REVERSED) n = -1*n; + } + + + int MeshOptimize2dOCCSurfaces :: + CalcPointGeomInfo(int surfind, PointGeomInfo& gi, const Point<3> & p) const + { + Standard_Real u,v; + + gp_Pnt pnt(p(0), p(1), p(2)); + + Handle(Geom_Surface) occface; + occface = BRep_Tool::Surface(TopoDS::Face(geometry.fmap(surfind))); + + /* + GeomAPI_ProjectPointOnSurf proj(pnt, occface); + + if (proj.NbPoints() < 1) + { + cout << "ERROR: OCCSurface :: GetNormalVector: GeomAPI_ProjectPointOnSurf failed!" + << endl; + cout << p << endl; + return 0; + } + + proj.LowerDistanceParameters (u, v); + */ + + Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( occface ); + gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(geometry.fmap(surfind)) ) ); + suval.Coord( u, v); + //pnt = occface->Value( u, v ); + + + gi.u = u; + gi.v = v; + return 1; + } + + + + + + + OCCRefinementSurfaces :: OCCRefinementSurfaces (const OCCGeometry & ageometry) + : Refinement(), geometry(ageometry) + { + ; + } + + OCCRefinementSurfaces :: ~OCCRefinementSurfaces () + { + ; + } + + /* + inline double Det3 (double a00, double a01, double a02, + double a10, double a11, double a12, + double a20, double a21, double a22) + { + return a00*a11*a22 + a01*a12*a20 + a10*a21*a02 - a20*a11*a02 - a10*a01*a22 - a21*a12*a00; + } + + bool ProjectToSurface (gp_Pnt & p, Handle(Geom_Surface) surface, double& u, double& v) + { + gp_Pnt x = surface->Value (u,v); + + if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true; + + gp_Vec du, dv; + + surface->D1(u,v,x,du,dv); + + int count = 0; + + gp_Pnt xold; + gp_Vec n; + double det, lambda, mu; + + do { + count++; + + n = du^dv; + + det = Det3 (n.X(), du.X(), dv.X(), + n.Y(), du.Y(), dv.Y(), + n.Z(), du.Z(), dv.Z()); + + if (det < 1e-15) return false; + + lambda = Det3 (n.X(), p.X()-x.X(), dv.X(), + n.Y(), p.Y()-x.Y(), dv.Y(), + n.Z(), p.Z()-x.Z(), dv.Z())/det; + + mu = Det3 (n.X(), du.X(), p.X()-x.X(), + n.Y(), du.Y(), p.Y()-x.Y(), + n.Z(), du.Z(), p.Z()-x.Z())/det; + + u += lambda; + v += mu; + + xold = x; + surface->D1(u,v,x,du,dv); + + } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) || count > 50); + + if (count > 50) return false; + + p = x; + + return true; + } + */ + + void OCCRefinementSurfaces :: + PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const + { + Point<3> hnewp; + hnewp = p1+secpoint*(p2-p1); + + if (surfi > 0) + { + + double u = gi1.u+secpoint*(gi2.u-gi1.u); + double v = gi1.v+secpoint*(gi2.v-gi1.v); + + if (!geometry.FastProject (surfi, hnewp, u, v)) + { + // cout << "Fast projection to surface fails! Using OCC projection" << endl; + geometry.Project (surfi, hnewp); + } + + newgi.trignum = 1; + newgi.u = u; + newgi.v = v; + } + + newp = hnewp; + } + + + void OCCRefinementSurfaces :: + PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const + { + double s0, s1; + + Point<3> hnewp = p1+secpoint*(p2-p1); + gp_Pnt pnt(hnewp(0), hnewp(1), hnewp(2)); + GeomAPI_ProjectPointOnCurve proj(pnt, BRep_Tool::Curve(TopoDS::Edge(geometry.emap(ap1.edgenr)), s0, s1)); + pnt = proj.NearestPoint(); + hnewp = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + newp = hnewp; + newgi = ap1; + }; + + + void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi) const + { + if (surfi > 0) + geometry.Project (surfi, p); + }; + + void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi) const + { + if (surfi > 0) + if (!geometry.FastProject (surfi, p, gi.u, gi.v)) + { + cout << "Fast projection to surface fails! Using OCC projection" << endl; + geometry.Project (surfi, p); + } + }; + + + +} + + +#endif diff --git a/libsrc/occ/occmeshsurf.hpp b/libsrc/occ/occmeshsurf.hpp new file mode 100644 index 00000000..198ade67 --- /dev/null +++ b/libsrc/occ/occmeshsurf.hpp @@ -0,0 +1,203 @@ +#ifdef OCCGEOMETRY + +#ifndef FILE_OCCMESHSURF +#define FILE_OCCMESHSURF + +#include "occgeom.hpp" + +#define PARAMETERSPACE -1 +#define PLANESPACE 1 + +class OCCGeometry; + +class SingularMatrixException +{}; + +class UVBoundsException +{}; + +class OCCSurface +{ +public: + TopoDS_Face topods_face; + Handle(Geom_Surface) occface; + TopAbs_Orientation orient; + int projecttype; + +protected: + Point<3> p1; + Point<3> p2; + + /// in plane, directed p1->p2 + Vec<3> ex; + /// in plane + Vec<3> ey; + /// outer normal direction + Vec<3> ez; + + /// normal vector in p2 + Vec<3> n2; + + /// average normal vector + Vec<3> nmid; + + // for transformation to parameter space + Point<2> psp1; + Point<2> psp2; + Vec<2> psex; + Vec<2> psey; + Mat<2,2> Amat, Amatinv; + + // UV Bounds + double umin, umax, vmin, vmax; + +public: + OCCSurface (const TopoDS_Face & aface, int aprojecttype) + { + topods_face = aface; + occface = BRep_Tool::Surface(topods_face); + orient = topods_face.Orientation(); + projecttype = aprojecttype; + ShapeAnalysis::GetFaceUVBounds (topods_face, umin, umax, vmin, vmax); + umin -= fabs(umax-umin)/100.0; + vmin -= fabs(vmax-vmin)/100.0; + umax += fabs(umax-umin)/100.0; + vmax += fabs(vmax-vmin)/100.0; + // projecttype = PLANESPACE; + /* + TopExp_Explorer exp1; + exp1.Init (topods_face, TopAbs_WIRE); + orient = TopAbs::Compose (orient, exp1.Current().Orientation()); + */ + }; + + ~OCCSurface() + {}; + + void Project (Point<3> & p, PointGeomInfo & gi); + + void GetNormalVector (const Point<3> & p, + const PointGeomInfo & geominfo, + Vec<3> & n) const; + + /** + Defines tangential plane in ap1. + The local x-coordinate axis point to the direction of ap2 */ + void DefineTangentialPlane (const Point<3> & ap1, + const PointGeomInfo & geominfo1, + const Point<3> & ap2, + const PointGeomInfo & geominfo2); + + + /// Transforms 3d point p3d to local coordinates pplane + void ToPlane (const Point<3> & p3d, const PointGeomInfo & geominfo, + Point<2> & pplane, double h, int & zone) const; + + /// Transforms point pplane in local coordinates to 3d point + void FromPlane (const Point<2> & pplane, + Point<3> & p3d, + PointGeomInfo & gi, + double h); +}; + + + +/// +class Meshing2OCCSurfaces : public Meshing2 +{ + /// + OCCSurface surface; + + +public: + /// + Meshing2OCCSurfaces (const TopoDS_Shape & asurf, const Box<3> & aboundingbox, int aprojecttype); + + /// + int GetProjectionType () + { return surface.projecttype; } + +protected: + /// + virtual void DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo1, + const PointGeomInfo * geominfo2); + /// + virtual void TransformToPlain (const Point3d & locpoint, + const MultiPointGeomInfo & geominfo, + Point2d & plainpoint, + double h, int & zone); + /// + + virtual int TransformFromPlain (Point2d & plainpoint, + Point3d & locpoint, + PointGeomInfo & gi, + double h); + /// + virtual double CalcLocalH (const Point3d & p, double gh) const; + +}; + + + +/// +class MeshOptimize2dOCCSurfaces : public MeshOptimize2d + { + /// + const OCCGeometry & geometry; + +public: + /// + MeshOptimize2dOCCSurfaces (const OCCGeometry & ageometry); + + /// + virtual void ProjectPoint (INDEX surfind, Point<3> & p) const; + /// + virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const; + /// + virtual int ProjectPointGI (INDEX surfind, Point<3> & p, PointGeomInfo & gi) const; + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const; + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, PointGeomInfo & gi, Vec<3> & n) const; + + virtual int CalcPointGeomInfo(int surfind, PointGeomInfo& gi, const Point<3> & p3) const; +}; + + + +class OCCGeometry; + + +class OCCRefinementSurfaces : public Refinement +{ + const OCCGeometry & geometry; + +public: + OCCRefinementSurfaces (const OCCGeometry & ageometry); + virtual ~OCCRefinementSurfaces (); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const; + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const; + + virtual void ProjectToSurface (Point<3> & p, int surfi) const; + + virtual void ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi) const; +}; + + + +#endif + + + +#endif diff --git a/libsrc/occ/occpkg.cpp b/libsrc/occ/occpkg.cpp new file mode 100644 index 00000000..71695e2c --- /dev/null +++ b/libsrc/occ/occpkg.cpp @@ -0,0 +1,1020 @@ +#ifdef OCCGEOMETRY + +#include +#include +#include +#include +#include + + +#include +#include + +#include "../meshing/bcfunctions.hpp" + +#include "vsocc.hpp" + + +extern "C" int Ng_occ_Init (Tcl_Interp * interp); + + + +namespace netgen +{ + extern AutoPtr ng_geometry; + extern AutoPtr mesh; + + char * err_needsoccgeometry = (char*) "This operation needs an OCC geometry"; + extern char * err_needsmesh; + extern char * err_jobrunning; + + + + + class OCCGeometryRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const; + virtual VisualScene * GetVisualScene (const NetgenGeometry * geom) const; + + virtual void SetParameters (Tcl_Interp * interp) + { + occparam.resthcloseedgefac = + atof (Tcl_GetVar (interp, "::stloptions.resthcloseedgefac", 0)); + occparam.resthcloseedgeenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthcloseedgeenable", 0)); + } + }; + + + + + int Ng_SetOCCVisParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + int showvolume; + OCCGeometry * occgeometry = dynamic_cast (ng_geometry.Ptr()); + + showvolume = atoi (Tcl_GetVar (interp, "::occoptions.showvolumenr", 0)); + + if (occgeometry) + if (showvolume != vispar.occshowvolumenr) + { + if (showvolume < 0 || showvolume > occgeometry->NrSolids()) + { + char buf[20]; + sprintf (buf, "%5i", vispar.occshowvolumenr); + Tcl_SetVar (interp, "::occoptions.showvolumenr", buf, 0); + } + else + { + vispar.occshowvolumenr = showvolume; + if (occgeometry) + occgeometry -> changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + } + + int temp; + + temp = atoi (Tcl_GetVar (interp, "::occoptions.visproblemfaces", 0)); + + if ((bool) temp != vispar.occvisproblemfaces) + { + vispar.occvisproblemfaces = temp; + if (occgeometry) + occgeometry -> changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + vispar.occshowsurfaces = atoi (Tcl_GetVar (interp, "::occoptions.showsurfaces", 0)); + vispar.occshowedges = atoi (Tcl_GetVar (interp, "::occoptions.showedges", 0)); + vispar.occzoomtohighlightedentity = atoi (Tcl_GetVar (interp, "::occoptions.zoomtohighlightedentity", 0)); + vispar.occdeflection = pow(10.0,-1-atof (Tcl_GetVar (interp, "::occoptions.deflection", 0))); + +#endif + + + + + +#ifdef ACIS + vispar.ACISshowfaces = atoi (Tcl_GetVar (interp, "::occoptions.showsurfaces", 0)); + vispar.ACISshowedges = atoi (Tcl_GetVar (interp, "::occoptions.showedges", 0)); + vispar.ACISshowsolidnr = atoi (Tcl_GetVar (interp, "::occoptions.showsolidnr", 0)); + vispar.ACISshowsolidnr2 = atoi (Tcl_GetVar (interp, "::occoptions.showsolidnr2", 0)); + +#endif + + + + return TCL_OK; + } + + + + + int Ng_GetOCCData (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + OCCGeometry * occgeometry = dynamic_cast (ng_geometry.Ptr()); + + static char buf[1000]; + buf[0] = 0; + stringstream str; + + if (argc >= 2) + { + if (strcmp (argv[1], "getentities") == 0) + { + if (occgeometry) + { + occgeometry->GetTopologyTree(str); + } + } + } + + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + +#endif + return TCL_OK; + } + + + + int Ng_OCCCommand (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + OCCGeometry * occgeometry = dynamic_cast (ng_geometry.Ptr()); + + stringstream str; + if (argc >= 2) + { + if (strcmp (argv[1], "isoccgeometryloaded") == 0) + { + if (occgeometry) + str << "1 " << flush; + else str << "0 " << flush; + + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (occgeometry) + { + if (strcmp (argv[1], "buildvisualizationmesh") == 0) + { + occgeometry->BuildVisualizationMesh(vispar.occdeflection); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "mesherror") == 0) + { + if (occgeometry->ErrorInSurfaceMeshing()) + str << 1; + else + str << 0; + } + if (strcmp (argv[1], "sewfaces") == 0) + { + cout << "Before operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->SewFaces(); + occgeometry->BuildFMap(); + cout << endl << "After operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(vispar.occdeflection); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "makesolid") == 0) + { + cout << "Before operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->MakeSolid(); + occgeometry->BuildFMap(); + cout << endl << "After operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(vispar.occdeflection); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "upgradetopology") == 0) + { + cout << "Before operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->SewFaces(); + occgeometry->MakeSolid(); + occgeometry->BuildFMap(); + cout << endl << "After operation:" << endl; + occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(vispar.occdeflection); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[1], "shapehealing") == 0) + { + occgeometry->tolerance = + atof (Tcl_GetVar (interp, "::occoptions.tolerance", 0)); + occgeometry->fixsmalledges = + atoi (Tcl_GetVar (interp, "::occoptions.fixsmalledges", 0)); + occgeometry->fixspotstripfaces = + atoi (Tcl_GetVar (interp, "::occoptions.fixspotstripfaces", 0)); + occgeometry->sewfaces = + atoi (Tcl_GetVar (interp, "::occoptions.sewfaces", 0)); + occgeometry->makesolids = + atoi (Tcl_GetVar (interp, "::occoptions.makesolids", 0)); + occgeometry->splitpartitions = + atoi (Tcl_GetVar (interp, "::occoptions.splitpartitions", 0)); + + // cout << "Before operation:" << endl; + // occgeometry->PrintNrShapes(); + occgeometry->HealGeometry(); + occgeometry->BuildFMap(); + // cout << endl << "After operation:" << endl; + // occgeometry->PrintNrShapes(); + occgeometry->BuildVisualizationMesh(vispar.occdeflection); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + + if (strcmp (argv[1], "highlightentity") == 0) + { + if (strcmp (argv[2], "Face") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + occgeometry->fvispar[nr-1].Highlight(); + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[2], "Shell") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->shmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Highlight(); + } + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[2], "Solid") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->somap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Highlight(); + } + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + /* + if (strcmp (argv[2], "CompSolid") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->cmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Highlight(); + } + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + */ + + if (strcmp (argv[2], "Edge") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + occgeometry->evispar[nr-1].Highlight(); + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + if (strcmp (argv[2], "Wire") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + TopExp_Explorer exp; + for (exp.Init (occgeometry->wmap(nr), TopAbs_EDGE); + exp.More(); exp.Next()) + { + int i = occgeometry->emap.FindIndex (TopoDS::Edge(exp.Current())); + occgeometry->evispar[i-1].Highlight(); + } + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + if (strcmp (argv[2], "Vertex") == 0) + { + int nr = atoi (argv[3]); + occgeometry->LowLightAll(); + + occgeometry->vvispar[nr-1].Highlight(); + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + } + + + + if (strcmp (argv[1], "show") == 0) + { + int nr = atoi (argv[3]); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + + if (strcmp (argv[2], "Face") == 0) + { + occgeometry->fvispar[nr-1].Show(); + } + if (strcmp (argv[2], "Shell") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->shmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Show(); + } + } + if (strcmp (argv[2], "Solid") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->somap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Show(); + } + } + if (strcmp (argv[2], "Edge") == 0) + { + occgeometry->evispar[nr-1].Show(); + } + if (strcmp (argv[2], "Wire") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->wmap(nr), TopAbs_EDGE); + exp.More(); exp.Next()) + { + int i = occgeometry->emap.FindIndex (TopoDS::Edge(exp.Current())); + occgeometry->evispar[i-1].Show(); + } + } + } + + + if (strcmp (argv[1], "hide") == 0) + { + int nr = atoi (argv[3]); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + + if (strcmp (argv[2], "Face") == 0) + { + occgeometry->fvispar[nr-1].Hide(); + } + if (strcmp (argv[2], "Shell") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->shmap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Hide(); + } + } + if (strcmp (argv[2], "Solid") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->somap(nr), TopAbs_FACE); + exp.More(); exp.Next()) + { + int i = occgeometry->fmap.FindIndex (TopoDS::Face(exp.Current())); + occgeometry->fvispar[i-1].Hide(); + } + } + if (strcmp (argv[2], "Edge") == 0) + { + occgeometry->evispar[nr-1].Hide(); + } + if (strcmp (argv[2], "Wire") == 0) + { + TopExp_Explorer exp; + for (exp.Init (occgeometry->wmap(nr), TopAbs_EDGE); + exp.More(); exp.Next()) + { + int i = occgeometry->emap.FindIndex (TopoDS::Edge(exp.Current())); + occgeometry->evispar[i-1].Hide(); + } + } + } + + + + if (strcmp (argv[1], "findsmallentities") == 0) + { + stringstream str(""); + occgeometry->CheckIrregularEntities(str); + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (strcmp (argv[1], "getunmeshedfaceinfo") == 0) + { + occgeometry->GetUnmeshedFaceInfo(str); + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (strcmp (argv[1], "getnotdrawablefaces") == 0) + { + occgeometry->GetNotDrawableFaces(str); + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + } + if (strcmp (argv[1], "redrawstatus") == 0) + { + int i = atoi (argv[2]); + occgeometry->changed = i; + } + if (strcmp (argv[1], "swaporientation") == 0) + { + IGESControl_Writer writer("millimeters", 1); + writer.AddShape (occgeometry->shape); + writer.Write ("1.igs"); + /* + int nr = atoi (argv[3]); + + // const_cast (occgeometry->fmap(nr)).Reverse(); + + Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape; + rebuild->Apply(occgeometry->shape); + + TopoDS_Shape sh; + + // if (strcmp (argv[2], "CompSolid") == 0) sh = occgeometry->cmap(nr); + if (strcmp (argv[2], "Solid") == 0) sh = occgeometry->somap(nr); + if (strcmp (argv[2], "Shell") == 0) sh = occgeometry->shmap(nr); + if (strcmp (argv[2], "Face") == 0) sh = occgeometry->fmap(nr); + if (strcmp (argv[2], "Wire") == 0) sh = occgeometry->wmap(nr); + if (strcmp (argv[2], "Edge") == 0) sh = occgeometry->emap(nr); + + rebuild->Replace(sh, sh.Reversed(), Standard_False); + + TopoDS_Shape newshape = rebuild->Apply(occgeometry->shape, TopAbs_SHELL, 1); + occgeometry->shape = newshape; + + occgeometry->BuildFMap(); + occgeometry->BuildVisualizationMesh(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + */ + } + if (strcmp (argv[1], "marksingular") == 0) + { + int nr = atoi (argv[3]); + cout << "marking " << argv[2] << " " << nr << endl; + char buf[2]; buf[0] = '0'; buf[1] = 0; + bool sing = false; + if (strcmp (argv[2], "Face") == 0) + sing = occgeometry->fsingular[nr-1] = !occgeometry->fsingular[nr-1]; + if (strcmp (argv[2], "Edge") == 0) + sing = occgeometry->esingular[nr-1] = !occgeometry->esingular[nr-1]; + if (strcmp (argv[2], "Vertex") == 0) + sing = occgeometry->vsingular[nr-1] = !occgeometry->vsingular[nr-1]; + + if (sing) buf[0] = '1'; + + Tcl_SetVar (interp, "::ismarkedsingular", buf, 0); + + stringstream str; + occgeometry->GetTopologyTree (str); + + char* cstr = (char*)str.str().c_str(); + + (*testout) << cstr << endl; + + char helpstr[1000]; + + while (strchr (cstr, '}')) + { + strncpy (helpstr, cstr+2, strlen(strchr(cstr+2, '}'))); + (*testout) << "***" << cstr << "***" << endl; + cstr = strchr (cstr, '}'); + } + } + } + } + +#endif + return TCL_OK; + } + + + +#ifdef OCCGEOMETRY + /* + void OCCConstructGeometry (OCCGeometry & geom); + + int Ng_OCCConstruction (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (occgeometry) + OCCConstructGeometry (*occgeometry); + return TCL_OK; + } + */ +#endif + + + + + // Philippose - 30/01/2009 + // TCL interface function for the Local Face Mesh size + // definition functionality + int Ng_SurfaceMeshSize (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef OCCGEOMETRY + + static char buf[100]; + + if (argc < 2) + { + Tcl_SetResult (interp, (char *)"Ng_SurfaceMeshSize needs arguments", TCL_STATIC); + return TCL_ERROR; + } + + OCCGeometry * occgeometry = dynamic_cast (ng_geometry.Ptr()); + if (!occgeometry) + { + Tcl_SetResult (interp, (char *)"Ng_SurfaceMeshSize currently supports only OCC (STEP/IGES) Files", TCL_STATIC); + return TCL_ERROR; + } + + // Update the face mesh sizes to reflect the global maximum mesh size + for(int i = 1; i <= occgeometry->NrFaces(); i++) + { + if(!occgeometry->GetFaceMaxhModified(i)) + { + occgeometry->SetFaceMaxH(i, mparam.maxh); + } + } + + if (strcmp (argv[1], "setsurfms") == 0) + { + int facenr = atoi (argv[2]); + double surfms = atof (argv[3]); + if (occgeometry && facenr >= 1 && facenr <= occgeometry->NrFaces()) + occgeometry->SetFaceMaxH(facenr, surfms); + + } + + if (strcmp (argv[1], "setall") == 0) + { + double surfms = atof (argv[2]); + if (occgeometry) + { + int nrFaces = occgeometry->NrFaces(); + for (int i = 1; i <= nrFaces; i++) + occgeometry->SetFaceMaxH(i, surfms); + } + } + + if (strcmp (argv[1], "getsurfms") == 0) + { + int facenr = atoi (argv[2]); + if (occgeometry && facenr >= 1 && facenr <= occgeometry->NrFaces()) + { + sprintf (buf, "%5.2f", occgeometry->GetFaceMaxH(facenr)); + } + else + { + sprintf (buf, "%5.2f", mparam.maxh); + } + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + if (strcmp (argv[1], "getactive") == 0) + { + sprintf (buf, "%d", occgeometry->SelectedFace()); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + if (strcmp (argv[1], "setactive") == 0) + { + int facenr = atoi (argv[2]); + if (occgeometry && facenr >= 1 && facenr <= occgeometry->NrFaces()) + { + occgeometry->SetSelectedFace (facenr); + + occgeometry->LowLightAll(); + occgeometry->fvispar[facenr-1].Highlight(); + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + } + + if (strcmp (argv[1], "getnfd") == 0) + { + if (occgeometry) + sprintf (buf, "%d", occgeometry->NrFaces()); + else + sprintf (buf, "0"); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + return TCL_OK; +#else // No OCCGEOMETRY + + Tcl_SetResult (interp, (char *)"Ng_SurfaceMeshSize currently supports only OCC (STEP/IGES) Files", TCL_STATIC); + return TCL_ERROR; + +#endif // OCCGEOMETRY + } + + + + // Philippose - 25/07/2010 + // TCL interface function for extracting and eventually + // setting or editing the current colours present in the mesh + int Ng_CurrentFaceColours (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if(argc < 1) + { + Tcl_SetResult (interp, (char *)"Ng_GetCurrentFaceColours needs arguments", TCL_STATIC); + return TCL_ERROR; + } + + if(!mesh.Ptr()) + { + Tcl_SetResult (interp, (char *)"Ng_GetCurrentFaceColours: Valid netgen mesh required...please mesh the Geometry first", TCL_STATIC); + return TCL_ERROR; + } + + if(strcmp(argv[1], "getcolours") == 0) + { + stringstream outVar; + Array face_colours; + GetFaceColours(*mesh, face_colours); + + for(int i = 0; i < face_colours.Size();i++) + { + outVar << "{ " << face_colours[i].X(1) + << " " << face_colours[i].X(2) + << " " << face_colours[i].X(3) + << " } "; + } + + tcl_const char * valuevar = argv[2]; + Tcl_SetVar (interp, valuevar, (char*)outVar.str().c_str(), 0); + } + + if(strcmp(argv[1], "showalso") == 0) + { + Array face_colours; + GetFaceColours(*mesh,face_colours); + + int colourind = atoi (argv[2]); + + for(int i = 1; i <= mesh->GetNFD(); i++) + { + Array surfElems; + mesh->GetSurfaceElementsOfFace(i,surfElems); + + if(ColourMatch(face_colours[colourind],mesh->GetFaceDescriptor(i).SurfColour())) + { + for(int j = 0; j < surfElems.Size(); j++) + { + mesh->SurfaceElement(surfElems[j]).Visible(1); + } + } + } + + mesh->SetNextTimeStamp(); + } + + if(strcmp(argv[1], "hidealso") == 0) + { + Array face_colours; + GetFaceColours(*mesh,face_colours); + + int colourind = atoi (argv[2]); + + for(int i = 1; i <= mesh->GetNFD(); i++) + { + Array surfElems; + mesh->GetSurfaceElementsOfFace(i,surfElems); + + if(ColourMatch(face_colours[colourind],mesh->GetFaceDescriptor(i).SurfColour())) + { + for(int j = 0; j < surfElems.Size(); j++) + { + mesh->SurfaceElement(surfElems[j]).Visible(0); + } + } + } + + mesh->SetNextTimeStamp(); + } + + if(strcmp(argv[1], "showonly") == 0) + { + Array face_colours; + GetFaceColours(*mesh,face_colours); + + int colourind = atoi (argv[2]); + + for(int i = 1; i <= mesh->GetNFD(); i++) + { + Array surfElems; + mesh->GetSurfaceElementsOfFace(i,surfElems); + + if(ColourMatch(face_colours[colourind],mesh->GetFaceDescriptor(i).SurfColour())) + { + for(int j = 0; j < surfElems.Size(); j++) + { + mesh->SurfaceElement(surfElems[j]).Visible(1); + } + } + else + { + for(int j = 0; j < surfElems.Size(); j++) + { + mesh->SurfaceElement(surfElems[j]).Visible(0); + } + } + } + + mesh->SetNextTimeStamp(); + } + + if(strcmp(argv[1], "hideonly") == 0) + { + Array face_colours; + GetFaceColours(*mesh,face_colours); + + int colourind = atoi (argv[2]); + + for(int i = 1; i <= mesh->GetNFD(); i++) + { + Array surfElems; + mesh->GetSurfaceElementsOfFace(i,surfElems); + + if(ColourMatch(face_colours[colourind],mesh->GetFaceDescriptor(i).SurfColour())) + { + for(int j = 0; j < surfElems.Size(); j++) + { + mesh->SurfaceElement(surfElems[j]).Visible(0); + } + } + else + { + for(int j = 0; j < surfElems.Size(); j++) + { + mesh->SurfaceElement(surfElems[j]).Visible(1); + } + } + } + + mesh->SetNextTimeStamp(); + } + + if(strcmp(argv[1], "showall") == 0) + { + for(int i = 1; i <= mesh->GetNSE(); i++) + { + mesh->SurfaceElement(i).Visible(1); + } + + mesh->SetNextTimeStamp(); + } + + if(strcmp(argv[1], "hideall") == 0) + { + for(int i = 1; i <= mesh->GetNSE(); i++) + { + mesh->SurfaceElement(i).Visible(0); + } + + mesh->SetNextTimeStamp(); + } + + return TCL_OK; + } + + + + + // Philippose - 10/03/2009 + // TCL interface function for the Automatic Colour-based + // definition of boundary conditions for OCC Geometry + int Ng_AutoColourBcProps (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if(argc < 1) + { + Tcl_SetResult (interp, (char *)"Ng_AutoColourBcProps needs arguments", TCL_STATIC); + return TCL_ERROR; + } + + if(!mesh.Ptr()) + { + Tcl_SetResult (interp, (char *)"Ng_AutoColourBcProps: Valid netgen mesh required...please mesh the Geometry first", TCL_STATIC); + return TCL_ERROR; + } + + if(strcmp(argv[1], "auto") == 0) + { + AutoColourBcProps(*mesh, 0); + } + + if(strcmp(argv[1], "profile") == 0) + { + AutoColourBcProps(*mesh, argv[2]); + } + + return TCL_OK; + } + + + int Ng_SetOCCParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + OCCGeometryRegister reg; + reg.SetParameters (interp); + /* + occparam.resthcloseedgefac = + atof (Tcl_GetVar (interp, "::stloptions.resthcloseedgefac", 0)); + + occparam.resthcloseedgeenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthcloseedgeenable", 0)); + */ + return TCL_OK; + } + + + + + NetgenGeometry * OCCGeometryRegister :: Load (string filename) const + { + const char * lgfilename = filename.c_str(); + + + /* + if (strcmp (&cfilename[strlen(cfilename)-3], "geo") == 0) + { + PrintMessage (1, "Load OCCG geometry file ", cfilename); + + extern OCCGeometry * ParseOCCG (istream & istr); + + ifstream infile(cfilename); + + OCCGeometry * hgeom = ParseOCCG (infile); + if (!hgeom) + throw NgException ("geo-file should start with 'algebraic3d'"); + + hgeom -> FindIdenticSurfaces(1e-8 * hgeom->MaxSize()); + return hgeom; + } + */ + + + if ((strcmp (&lgfilename[strlen(lgfilename)-4], "iges") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "igs") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "IGS") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "IGES") == 0)) + { + PrintMessage (1, "Load IGES geometry file ", lgfilename); + OCCGeometry * occgeometry = LoadOCC_IGES (lgfilename); + return occgeometry; + } + + else if ((strcmp (&lgfilename[strlen(lgfilename)-4], "step") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "stp") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "STP") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "STEP") == 0)) + { + PrintMessage (1, "Load STEP geometry file ", lgfilename); + OCCGeometry * occgeometry = LoadOCC_STEP (lgfilename); + return occgeometry; + } + else if ((strcmp (&lgfilename[strlen(lgfilename)-4], "brep") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "Brep") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "BREP") == 0)) + { + PrintMessage (1, "Load BREP geometry file ", lgfilename); + OCCGeometry * occgeometry = LoadOCC_BREP (lgfilename); + return occgeometry; + } + + return NULL; + } + + + static VisualSceneOCCGeometry vsoccgeom; + + VisualScene * OCCGeometryRegister :: GetVisualScene (const NetgenGeometry * geom) const + { + OCCGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + if (geometry) + { + vsoccgeom.SetGeometry (geometry); + return &vsoccgeom; + } + return NULL; + } + + + +} + + + +using namespace netgen; + +int Ng_occ_Init (Tcl_Interp * interp) +{ + geometryregister.Append (new OCCGeometryRegister); + + + Tcl_CreateCommand (interp, "Ng_SetOCCVisParameters", + Ng_SetOCCVisParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetOCCData", + Ng_GetOCCData, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + /* +#ifdef OCCGEOMETRY + Tcl_CreateCommand (interp, "Ng_OCCConstruction", + Ng_OCCConstruction, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); +#endif + */ + + Tcl_CreateCommand (interp, "Ng_OCCCommand", + Ng_OCCCommand, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_SetOCCParameters", Ng_SetOCCParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + + // Philippose - 30/01/2009 + // Register the TCL Interface Command for local face mesh size + // definition + Tcl_CreateCommand (interp, "Ng_SurfaceMeshSize", Ng_SurfaceMeshSize, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_AutoColourBcProps", Ng_AutoColourBcProps, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + // Philippose - 25/07/2010 + // Register the TCL Interface Command for handling the face colours + // present in the mesh + Tcl_CreateCommand(interp, "Ng_CurrentFaceColours", Ng_CurrentFaceColours, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + return TCL_OK; +} + +#endif + diff --git a/libsrc/occ/utilities.h b/libsrc/occ/utilities.h new file mode 100644 index 00000000..8cb9e305 --- /dev/null +++ b/libsrc/occ/utilities.h @@ -0,0 +1,112 @@ +// SALOME Utils : general SALOME's definitions and tools +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// 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. +// +// 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, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : utilities.h +// Author : Antoine YESSAYAN, Paul RASCLE, EDF +// Module : SALOME +// $Header: /cvs/netgen/netgen/libsrc/occ/utilities.h,v 1.3 2008/03/31 14:20:28 wabro Exp $ + +/* --- Definition macros file to print informations if _DEBUG_ is defined --- */ + +#ifndef UTILITIES_H +#define UTILITIES_H + +#include +#include +#include +// #include "SALOME_Log.hxx" + +/* --- INFOS is always defined (without _DEBUG_): to be used for warnings, with release version --- */ + +#define INFOS(msg) {SLog->putMessage(*SLog<<__FILE__<<" ["<<__LINE__<<"] : "<putMessage(*SLog<<"---PYSCRIPT--- "<putMessage(\ + *SLog<<__FILE__<<" ["<< __LINE__<<"] : "\ + << "COMPILED with " << COMPILER \ + << ", " << __DATE__ \ + << " at " << __TIME__ <putMessage( MYTRACE <putMessage( MYTRACE << #var << "=" << var < +#include +#include + +#include + +#include "TopoDS_Shape.hxx" +#include "TopoDS_Vertex.hxx" +#include "TopExp_Explorer.hxx" +#include "BRep_Tool.hxx" +#include "TopoDS.hxx" +#include "gp_Pnt.hxx" +#include "Geom_Curve.hxx" +#include "Poly_Triangulation.hxx" +#include "Poly_Array1OfTriangle.hxx" +#include "TColgp_Array1OfPnt2d.hxx" +#include "Poly_Triangle.hxx" +#include "Poly_Polygon3D.hxx" +#include "Poly_PolygonOnTriangulation.hxx" + +#include + +#include "vsocc.hpp" + +namespace netgen +{ + // extern OCCGeometry * occgeometry; + + /* *********************** Draw OCC Geometry **************** */ + + VisualSceneOCCGeometry :: VisualSceneOCCGeometry () + : VisualScene() + { + trilists.SetSize(0); + linelists.SetSize(1); + + } + + VisualSceneOCCGeometry :: ~VisualSceneOCCGeometry () + { + ; + } + + void VisualSceneOCCGeometry :: DrawScene () + { + if ( occgeometry->changed ) + { + BuildScene(); + occgeometry -> changed = 0; + } + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + SetLight(); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + glShadeModel (GL_SMOOTH); + glDisable (GL_COLOR_MATERIAL); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // glEnable (GL_LIGHTING); + + double shine = vispar.shininess; + // double transp = vispar.transp; + + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); + glLogicOp (GL_COPY); + + glEnable (GL_NORMALIZE); + + float mat_col[] = { 0.2f, 0.2f, 0.8f, 1.0f}; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + // Philippose - 30/01/2009 + // Added clipping planes to Geometry view + SetClippingPlane(); + + GLfloat matcoledge[] = { 0, 0, 1, 1}; + GLfloat matcolhiedge[] = { 1, 0, 0, 1}; + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcoledge); + glLineWidth (1.0f); + + if (vispar.occshowedges) glCallList (linelists.Get(1)); + if (vispar.occshowsurfaces) glCallList (trilists.Get(1)); + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolhiedge); + glLineWidth (5.0f); + + if (vispar.occshowedges) glCallList (linelists.Get(2)); + + for (int i = 1; i <= occgeometry->vmap.Extent(); i++) + if (occgeometry->vvispar[i-1].IsHighlighted()) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolhiedge); + glLineWidth (5.0f); + + glBegin (GL_LINES); + + gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(occgeometry->vmap(i))); + double d = rad/100; + glVertex3f (p.X()-d, p.Y(), p.Z()); + glVertex3f (p.X()+d, p.Y(), p.Z()); + glVertex3f (p.X(), p.Y()-d, p.Z()); + glVertex3f (p.X(), p.Y()+d, p.Z()); + glVertex3f (p.X(), p.Y(), p.Z()-d); + glVertex3f (p.X(), p.Y(), p.Z()+d); + glEnd(); + } + + glDisable (GL_POLYGON_OFFSET_FILL); + + glPopMatrix(); + // DrawCoordinateCross (); + // DrawNetgenLogo (); + glFinish(); + + glDisable (GL_POLYGON_OFFSET_FILL); + } + + /* + void VisualSceneOCCGeometry :: BuildScene (int zoomall) + { + int i = 0, j, k; + + TopExp_Explorer ex, ex_edge; + + if (vispar.occvisproblemfaces || (occgeometry -> changed != 2)) + { + Box<3> bb = occgeometry -> GetBoundingBox(); + + center = bb.Center(); + rad = bb.Diam() / 2; + + + + if (vispar.occvisproblemfaces) + { + for (i = 1; i <= occgeometry->fmap.Extent(); i++) + if (occgeometry->facemeshstatus[i-1] == -1) + { + GProp_GProps system; + BRepGProp::LinearProperties(occgeometry->fmap(i), system); + gp_Pnt pnt = system.CentreOfMass(); + center = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + cout << "Setting center to mid of face " << i << " = " << center << endl; + } + } + + + CalcTransformationMatrices(); + } + + + for (i = 1; i <= linelists.Size(); i++) + glDeleteLists (linelists.Elem(i), 1); + linelists.SetSize(0); + + linelists.Append (glGenLists (1)); + glNewList (linelists.Last(), GL_COMPILE); + + i = 0; + for (ex_edge.Init(occgeometry -> shape, TopAbs_EDGE); + ex_edge.More(); ex_edge.Next()) + { + if (BRep_Tool::Degenerated(TopoDS::Edge(ex_edge.Current()))) continue; + i++; + + + TopoDS_Edge edge = TopoDS::Edge(ex_edge.Current()); + + Handle(Poly_PolygonOnTriangulation) aEdgePoly; + Handle(Poly_Triangulation) T; + TopLoc_Location aEdgeLoc; + BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc); + + if(aEdgePoly.IsNull()) + { + cout << "cannot visualize edge " << i << endl; + continue; + } + + glBegin (GL_LINE_STRIP); + + int nbnodes = aEdgePoly -> NbNodes(); + for (j = 1; j <= nbnodes; j++) + { + gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); + glVertex3f (p.X(), p.Y(), p.Z()); + } + + glEnd (); + + + } + + glEndList (); + + for (i = 1; i <= trilists.Size(); i++) + glDeleteLists (trilists.Elem(i), 1); + trilists.SetSize(0); + + + trilists.Append (glGenLists (1)); + glNewList (trilists.Last(), GL_COMPILE); + + i = 0; + + TopExp_Explorer exp0, exp1, exp2, exp3; + int shapenr = 0; + for (exp0.Init(occgeometry -> shape, TopAbs_SOLID); exp0.More(); exp0.Next()) + { + shapenr++; + + if (vispar.occshowvolumenr != 0 && + vispar.occshowvolumenr != shapenr) continue; + + float mat_col[4]; + mat_col[3] = 1; + switch (shapenr) + { + case 1: + mat_col[0] = 0.2; + mat_col[1] = 0.2; + mat_col[2] = 0.8; + break; + case 2: + mat_col[0] = 0.8; + mat_col[1] = 0.2; + mat_col[2] = 0.8; + break; + case 3: + mat_col[0] = 0.2; + mat_col[1] = 0.8; + mat_col[2] = 0.8; + break; + case 4: + mat_col[0] = 0.8; + mat_col[1] = 0.2; + mat_col[2] = 0.2; + break; + case 5: + mat_col[0] = 0.8; + mat_col[1] = 0.8; + mat_col[2] = 0.8; + break; + case 6: + mat_col[0] = 0.6; + mat_col[1] = 0.6; + mat_col[2] = 0.6; + break; + case 7: + mat_col[0] = 0.2; + mat_col[1] = 0.8; + mat_col[2] = 0.2; + break; + case 8: + mat_col[0] = 0.8; + mat_col[1] = 0.8; + mat_col[2] = 0.2; + break; + default: + // mat_col[0] = 1-(1.0/double(shapenr)); + // mat_col[1] = 0.5; + mat_col[0] = 0.5+double((shapenr*shapenr*shapenr*shapenr) % 10)/20.0; + mat_col[1] = 0.5+double(int(shapenr*shapenr*shapenr*shapenr*sin(double(shapenr))) % 10)/20.0; + mat_col[2] = 0.5+double((shapenr*shapenr*shapenr) % 10)/20.0; + } + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + for (exp1.Init(exp0.Current(), TopAbs_SHELL); exp1.More(); exp1.Next()) + for (exp2.Init(exp1.Current().Composed(exp0.Current().Orientation()), TopAbs_FACE); exp2.More(); exp2.Next()) + { + TopoDS_Face face = TopoDS::Face (exp2.Current().Composed(exp1.Current().Orientation())); + + i = occgeometry->fmap.FindIndex(face); + + TopLoc_Location loc; + Handle(Geom_Surface) surf = BRep_Tool::Surface (face); + BRepAdaptor_Surface sf(face, Standard_False); + BRepLProp_SLProps prop(sf, 1, 1e-5); + Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc); + + if (triangulation.IsNull()) + { + cout << "cannot visualize face " << i << endl; + continue; + } + + if (vispar.occvisproblemfaces) + { + switch (occgeometry->facemeshstatus[i-1]) + { + case 0: + mat_col[0] = 0.2; + mat_col[1] = 0.2; + mat_col[2] = 0.8; + break; + case 1: + mat_col[0] = 0.2; + mat_col[1] = 0.8; + mat_col[2] = 0.2; + break; + case -1: + mat_col[0] = 0.8; + mat_col[1] = 0.2; + mat_col[2] = 0.2; + break; + } + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + } + glBegin (GL_TRIANGLES); + + int ntriangles = triangulation -> NbTriangles(); + for (j = 1; j <= ntriangles; j++) + { + Poly_Triangle triangle = (triangulation -> Triangles())(j); + for (k = 1; k <= 3; k++) + { + gp_Pnt2d uv = (triangulation -> UVNodes())(triangle(k)); + gp_Pnt pnt; + gp_Vec du, dv; + prop.SetParameters (uv.X(), uv.Y()); + surf->D0 (uv.X(), uv.Y(), pnt); + gp_Vec n; + + if (prop.IsNormalDefined()) + n = prop.Normal(); + else + n = gp_Vec (0,0,0); + + if (face.Orientation() == TopAbs_REVERSED) n *= -1; + glNormal3f (n.X(), n.Y(), n.Z()); + glVertex3f (pnt.X(), pnt.Y(), pnt.Z()); + } + } + glEnd (); + + } + } + + + glEndList (); + + } + */ + + void VisualSceneOCCGeometry :: BuildScene (int zoomall) + { + if (occgeometry -> changed == OCCGEOMETRYVISUALIZATIONFULLCHANGE) + { + occgeometry -> BuildVisualizationMesh (vispar.occdeflection); + + center = occgeometry -> Center(); + rad = occgeometry -> GetBoundingBox().Diam() / 2; + + if (vispar.occzoomtohighlightedentity) + { + bool hilite = false; + bool hiliteonepoint = false; + Bnd_Box bb; + + for (int i = 1; i <= occgeometry->fmap.Extent(); i++) + if (occgeometry->fvispar[i-1].IsHighlighted()) + { + hilite = true; + BRepBndLib::Add (occgeometry->fmap(i), bb); + } + + for (int i = 1; i <= occgeometry->emap.Extent(); i++) + if (occgeometry->evispar[i-1].IsHighlighted()) + { + hilite = true; + BRepBndLib::Add (occgeometry->emap(i), bb); + } + + for (int i = 1; i <= occgeometry->vmap.Extent(); i++) + if (occgeometry->vvispar[i-1].IsHighlighted()) + { + hiliteonepoint = true; + BRepBndLib::Add (occgeometry->vmap(i), bb); + } + + if (hilite || hiliteonepoint) + { + double x1,y1,z1,x2,y2,z2; + bb.Get (x1,y1,z1,x2,y2,z2); + Point<3> p1 = Point<3> (x1,y1,z1); + Point<3> p2 = Point<3> (x2,y2,z2); + Box<3> boundingbox(p1,p2); + + center = boundingbox.Center(); + if (hiliteonepoint) + rad = occgeometry -> GetBoundingBox().Diam() / 100; + else + rad = boundingbox.Diam() / 2; + } + } + + CalcTransformationMatrices(); + } + + // Clear lists + + for (int i = 1; i <= linelists.Size(); i++) + glDeleteLists (linelists.Elem(i), 1); + linelists.SetSize(0); + + for (int i = 1; i <= trilists.Size(); i++) + glDeleteLists (trilists.Elem(i), 1); + trilists.SetSize(0); + + // Total wireframe + + linelists.Append (glGenLists (1)); + glNewList (linelists.Last(), GL_COMPILE); + + for (int i = 1; i <= occgeometry->emap.Extent(); i++) + { + TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i)); + if (BRep_Tool::Degenerated(edge)) continue; + if (occgeometry->evispar[i-1].IsHighlighted()) continue; + + Handle(Poly_PolygonOnTriangulation) aEdgePoly; + Handle(Poly_Triangulation) T; + TopLoc_Location aEdgeLoc; + BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc); + + if(aEdgePoly.IsNull()) + { + (*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge) + << " without using the occ visualization triangulation" << endl; + + double s0, s1; + Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); + + glBegin (GL_LINE_STRIP); + for (int i = 0; i<=50; i++) + { + gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0); + glVertex3f (p.X(),p.Y(),p.Z()); + } + glEnd (); + + continue; + } + + int nbnodes = aEdgePoly -> NbNodes(); + glBegin (GL_LINE_STRIP); + for (int j = 1; j <= nbnodes; j++) + { + gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); + glVertex3f (p.X(), p.Y(), p.Z()); + } + glEnd (); + } + + glEndList (); + + // Highlighted edge list + + linelists.Append (glGenLists (1)); + glNewList (linelists.Last(), GL_COMPILE); + + for (int i = 1; i <= occgeometry->emap.Extent(); i++) + if (occgeometry->evispar[i-1].IsHighlighted()) + { + TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i)); + if (BRep_Tool::Degenerated(edge)) continue; + + Handle(Poly_PolygonOnTriangulation) aEdgePoly; + Handle(Poly_Triangulation) T; + TopLoc_Location aEdgeLoc; + BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc); + + if(aEdgePoly.IsNull()) + { + (*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge) + << " without using the occ visualization triangulation" << endl; + + double s0, s1; + Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); + + glBegin (GL_LINE_STRIP); + for (int i = 0; i<=50; i++) + { + gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0); + glVertex3f (p.X(),p.Y(),p.Z()); + } + glEnd (); + + continue; + } + + int nbnodes = aEdgePoly -> NbNodes(); + glBegin (GL_LINE_STRIP); + for (int j = 1; j <= nbnodes; j++) + { + gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); + glVertex3f (p.X(), p.Y(), p.Z()); + } + glEnd (); + } + + glEndList (); + + // display faces + + trilists.Append (glGenLists (1)); + glNewList (trilists.Last(), GL_COMPILE); + + for (int i = 1; i <= occgeometry->fmap.Extent(); i++) + { + if (!occgeometry->fvispar[i-1].IsVisible()) continue; + + glLoadName (i); + float mat_col[4]; + mat_col[3] = 1; + + TopoDS_Face face = TopoDS::Face(occgeometry->fmap(i)); + + if (!occgeometry->fvispar[i-1].IsHighlighted()) + { + // Philippose - 30/01/2009 + // OpenCascade XDE Support + Quantity_Color face_colour; + // Philippose - 23/02/2009 + // Check to see if colours have been extracted first!! + // Forum bug-fox (Jean-Yves - 23/02/2009) + if(!(occgeometry->face_colours.IsNull()) + && (occgeometry->face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour))) + { + mat_col[0] = face_colour.Red(); + mat_col[1] = face_colour.Green(); + mat_col[2] = face_colour.Blue(); + } + else + { + mat_col[0] = 0.0; + mat_col[1] = 1.0; + mat_col[2] = 0.0; + } + } + else + { + mat_col[0] = 0.8; + mat_col[1] = 0.2; + mat_col[2] = 0.2; + } + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + TopLoc_Location loc; + Handle(Geom_Surface) surf = BRep_Tool::Surface (face); + BRepAdaptor_Surface sf(face, Standard_False); + BRepLProp_SLProps prop(sf, 1, 1e-5); + Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc); + + if (triangulation.IsNull()) + { + cout << "cannot visualize face " << i << endl; + occgeometry->fvispar[i-1].SetNotDrawable(); + continue; + } + + gp_Pnt2d uv; + gp_Pnt pnt; + gp_Vec n; + + glBegin (GL_TRIANGLES); + + int ntriangles = triangulation -> NbTriangles(); + for (int j = 1; j <= ntriangles; j++) + { + Poly_Triangle triangle = (triangulation -> Triangles())(j); + gp_Pnt p[3]; + for (int k = 1; k <= 3; k++) + p[k-1] = (triangulation -> Nodes())(triangle(k)).Transformed(loc); + + for (int k = 1; k <= 3; k++) + { + uv = (triangulation -> UVNodes())(triangle(k)); + prop.SetParameters (uv.X(), uv.Y()); + + // surf->D0 (uv.X(), uv.Y(), pnt); + + if (prop.IsNormalDefined()) + n = prop.Normal(); + else + { + (*testout) << "Visualization of face " << i + << ": Normal vector not defined" << endl; + // n = gp_Vec (0,0,0); + gp_Vec a(p[0],p[1]); + gp_Vec b(p[0],p[2]); + n = b^a; + } + + if (face.Orientation() == TopAbs_REVERSED) n *= -1; + glNormal3f (n.X(), n.Y(), n.Z()); + glVertex3f (p[k-1].X(), p[k-1].Y(), p[k-1].Z()); + } + } + glEnd (); + + } + glEndList (); + + } + + void SelectFaceInOCCDialogTree (int facenr); + + void VisualSceneOCCGeometry :: MouseDblClick (int px, int py) + { + int hits; + + // select surface triangle by mouse click + + GLuint selbuf[10000]; + glSelectBuffer (10000, selbuf); + + glRenderMode (GL_SELECT); + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + + GLdouble projmat[16]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + + glLoadIdentity(); + gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); + glMultMatrixd (projmat); + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_MODELVIEW); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + glInitNames(); + glPushName (1); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glDisable(GL_CLIP_PLANE0); + + // Philippose - 30/01/2009 + // Enable clipping planes for Selection mode in OCC Geometry + if (vispar.clipping.enable) + { + Vec<3> n(clipplane[0], clipplane[1], clipplane[2]); + double len = Abs(n); + double mu = -clipplane[3] / (len*len); + Point<3> p (mu * n); + n /= len; + Vec<3> t1 = n.GetNormal (); + Vec<3> t2 = Cross (n, t1); + + double xi1mid = (center - p) * t1; + double xi2mid = (center - p) * t2; + + glLoadName (0); + glBegin (GL_QUADS); + glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2); + glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2); + glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2); + glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2); + glEnd (); + } + + glCallList (trilists.Get(1)); + + glDisable (GL_POLYGON_OFFSET_FILL); + + glPopName(); + + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + + glFlush(); + + hits = glRenderMode (GL_RENDER); + + int minname = 0; + GLuint mindepth = 0; + + // find clippingplane + GLuint clipdepth = 0; // GLuint(-1); + + for (int i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + if (!curname) clipdepth = selbuf[4*i+1]; + } + + for (int i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + GLuint curdepth = selbuf[4*i+1]; + if (curname && (curdepth> clipdepth) && + (curdepth < mindepth || !minname)) + { + mindepth = curdepth; + minname = curname; + } + } + + occgeometry->LowLightAll(); + + if (minname) + { + occgeometry->fvispar[minname-1].Highlight(); + + if (vispar.occzoomtohighlightedentity) + occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE; + else + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + cout << "Selected face: " << minname << endl; + } + else + { + occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE; + } + + glDisable(GL_CLIP_PLANE0); + + SelectFaceInOCCDialogTree (minname); + + // Philippose - 30/01/2009 + // Set the currently selected face in the array + // for local face mesh size definition + occgeometry->SetSelectedFace(minname); + + // selecttimestamp = NextTimeStamp(); + } + +} + +#endif + +#endif // NOTCL diff --git a/libsrc/occ/vsocc.hpp b/libsrc/occ/vsocc.hpp new file mode 100644 index 00000000..3021fe7c --- /dev/null +++ b/libsrc/occ/vsocc.hpp @@ -0,0 +1,33 @@ +#ifndef FILE_VSOCC +#define FILE_VSOCC + +/**************************************************************************/ +/* File: vsocc.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 05. Jan. 2011 */ +/**************************************************************************/ + +namespace netgen +{ + + class VisualSceneOCCGeometry : public VisualScene + { + Array trilists; + Array linelists; + int selsurf; + class OCCGeometry * occgeometry; + public: + VisualSceneOCCGeometry (); + virtual ~VisualSceneOCCGeometry (); + void SetGeometry (class OCCGeometry * ageom) { occgeometry = ageom; } + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + virtual void MouseDblClick (int px, int py); + }; + + + +} + +#endif diff --git a/libsrc/stlgeom/Makefile.am b/libsrc/stlgeom/Makefile.am new file mode 100644 index 00000000..04e598cf --- /dev/null +++ b/libsrc/stlgeom/Makefile.am @@ -0,0 +1,21 @@ +noinst_HEADERS = meshstlsurface.hpp stlgeom.hpp stlline.hpp \ +stltool.hpp stltopology.hpp vsstl.hpp + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(TCL_INCLUDES) +METASOURCES = AUTO + +lib_LTLIBRARIES = libstl.la + +if NGGUI +lib_LTLIBRARIES += libstlvis.la +endif + +libstl_la_SOURCES = meshstlsurface.cpp stlgeom.cpp stlgeomchart.cpp \ + stlgeommesh.cpp stlline.cpp stltool.cpp stltopology.cpp + + +libstlvis_la_SOURCES = stlpkg.cpp vsstl.cpp +libstlvis_la_LIBADD = libstl.la +libstl_la_LIBADD = $(top_builddir)/libsrc/meshing/libmesh.la +# libstlvis_la_LIBADD = libstl.la $(top_builddir)/libsrc/linalg/libla.la + diff --git a/libsrc/stlgeom/Makefile.in b/libsrc/stlgeom/Makefile.in new file mode 100644 index 00000000..3635468b --- /dev/null +++ b/libsrc/stlgeom/Makefile.in @@ -0,0 +1,614 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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@ +@NGGUI_TRUE@am__append_1 = libstlvis.la +subdir = libsrc/stlgeom +DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libstl_la_DEPENDENCIES = $(top_builddir)/libsrc/meshing/libmesh.la +am_libstl_la_OBJECTS = meshstlsurface.lo stlgeom.lo stlgeomchart.lo \ + stlgeommesh.lo stlline.lo stltool.lo stltopology.lo +libstl_la_OBJECTS = $(am_libstl_la_OBJECTS) +libstlvis_la_DEPENDENCIES = libstl.la +am_libstlvis_la_OBJECTS = stlpkg.lo vsstl.lo +libstlvis_la_OBJECTS = $(am_libstlvis_la_OBJECTS) +@NGGUI_TRUE@am_libstlvis_la_rpath = -rpath $(libdir) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstl_la_SOURCES) $(libstlvis_la_SOURCES) +DIST_SOURCES = $(libstl_la_SOURCES) $(libstlvis_la_SOURCES) +HEADERS = $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = meshstlsurface.hpp stlgeom.hpp stlline.hpp \ +stltool.hpp stltopology.hpp vsstl.hpp + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include $(TCL_INCLUDES) +METASOURCES = AUTO +lib_LTLIBRARIES = libstl.la $(am__append_1) +libstl_la_SOURCES = meshstlsurface.cpp stlgeom.cpp stlgeomchart.cpp \ + stlgeommesh.cpp stlline.cpp stltool.cpp stltopology.cpp + +libstlvis_la_SOURCES = stlpkg.cpp vsstl.cpp +libstlvis_la_LIBADD = libstl.la +libstl_la_LIBADD = $(top_builddir)/libsrc/meshing/libmesh.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/stlgeom/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/stlgeom/Makefile +.PRECIOUS: 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): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libstl.la: $(libstl_la_OBJECTS) $(libstl_la_DEPENDENCIES) $(EXTRA_libstl_la_DEPENDENCIES) + $(CXXLINK) -rpath $(libdir) $(libstl_la_OBJECTS) $(libstl_la_LIBADD) $(LIBS) +libstlvis.la: $(libstlvis_la_OBJECTS) $(libstlvis_la_DEPENDENCIES) $(EXTRA_libstlvis_la_DEPENDENCIES) + $(CXXLINK) $(am_libstlvis_la_rpath) $(libstlvis_la_OBJECTS) $(libstlvis_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshstlsurface.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlgeom.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlgeomchart.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlgeommesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlline.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stlpkg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stltool.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stltopology.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsstl.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-libLTLIBRARIES clean-libtool \ + 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-libLTLIBRARIES + +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: uninstall-libLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool ctags 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-libLTLIBRARIES 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 uninstall uninstall-am uninstall-libLTLIBRARIES + +# libstlvis_la_LIBADD = libstl.la $(top_builddir)/libsrc/linalg/libla.la + +# 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/libsrc/stlgeom/meshstlsurface.cpp b/libsrc/stlgeom/meshstlsurface.cpp new file mode 100644 index 00000000..96c5bd18 --- /dev/null +++ b/libsrc/stlgeom/meshstlsurface.cpp @@ -0,0 +1,1171 @@ +#include +#include + +#include +#include + +#include + + +#include "stlgeom.hpp" + + +namespace netgen +{ + +static void STLFindEdges (STLGeometry & geom, + class Mesh & mesh) +{ + double h = mparam.maxh; + + // mark edge points: + //int ngp = geom.GetNP(); + + geom.RestrictLocalH(mesh, h); + + PushStatusF("Mesh Lines"); + + Array meshlines; + Array meshpoints; + + PrintMessage(3,"Mesh Lines"); + + /* + cout << geom.GetNLines() << " lines" << endl; + double totnp = 0; + for (int i = 1; i <= geom.GetNLines(); i++) + totnp += geom.GetLine(i)->NP(); + cout << "avg np per line " << totnp/geom.GetNLines() << endl; + */ + + for (int i = 1; i <= geom.GetNLines(); i++) + { + meshlines.Append(geom.GetLine(i)->Mesh(geom.GetPoints(), meshpoints, h, mesh)); + SetThreadPercent(100.0 * (double)i/(double)geom.GetNLines()); + } + + geom.meshpoints.SetSize(0); //testing + geom.meshlines.SetSize(0); //testing + for (int i = 1; i <= meshpoints.Size(); i++) + { + geom.meshpoints.Append(meshpoints.Get(i)); //testing + mesh.AddPoint(meshpoints.Get(i)); + } + //(++++++++++++++testing + for (int i = 1; i <= geom.GetNLines(); i++) + { + geom.meshlines.Append(meshlines.Get(i)); + } + //++++++++++++++testing) + + PrintMessage(7,"feed with edges"); + + for (int i = 1; i <= meshlines.Size(); i++) + { + STLLine* line = meshlines.Get(i); + (*testout) << "store line " << i << endl; + for (int j = 1; j <= line->GetNS(); j++) + { + int p1, p2; + + line->GetSeg(j, p1, p2); + int trig1, trig2, trig1b, trig2b; + + if (p1 == p2) + cout << "Add Segment, p1 == p2 == " << p1 << endl; + + // Test auf geschlossener Rand mit 2 Segmenten + + if ((j == 2) && (line->GetNS() == 2)) + { + int oldp1, oldp2; + line->GetSeg (1, oldp1, oldp2); + if (oldp1 == p2 && oldp2 == p1) + { + PrintMessage(7,"MESSAGE: don't use second segment"); + continue; + } + } + + + //mesh point number + //p1 = geom2meshnum.Get(p1); // for unmeshed lines!!! + //p2 = geom2meshnum.Get(p2); // for unmeshed lines!!! + + //left and right trigs + trig1 = line->GetLeftTrig(j); + trig2 = line->GetRightTrig(j); + trig1b = line->GetLeftTrig(j+1); + trig2b = line->GetRightTrig(j+1); + + (*testout) << "j = " << j << ", p1 = " << p1 << ", p2 = " << p2 << endl; + (*testout) << "segm-trigs: " + << "trig1 = " << trig1 + << ", trig1b = " << trig1b + << ", trig2 = " << trig2 + << ", trig2b = " << trig2b << endl; + + if (trig1 <= 0 || trig2 <= 0 || trig1b <= 0 || trig2b <= 0) + { + cout << "negative trigs, " + << ", trig1 = " << trig1 + << ", trig1b = " << trig1b + << ", trig2 = " << trig2 + << ", trig2b = " << trig2b << endl; + } + /* + (*testout) << " trigs p1: " << trig1 << " - " << trig2 << endl; + (*testout) << " trigs p2: " << trig1b << " - " << trig2b << endl; + (*testout) << " charts p1: " << geom.GetChartNr(trig1) << " - " << geom.GetChartNr(trig2) << endl; + (*testout) << " charts p2: " << geom.GetChartNr(trig1b) << " - " << geom.GetChartNr(trig2b) << endl; + */ + Point3d hp, hp2; + Segment seg; + seg[0] = p1; + seg[1] = p2; + seg.si = geom.GetTriangle(trig1).GetFaceNum(); + seg.edgenr = i; + + seg.epgeominfo[0].edgenr = i; + seg.epgeominfo[0].dist = line->GetDist(j); + seg.epgeominfo[1].edgenr = i; + seg.epgeominfo[1].dist = line->GetDist(j+1); + /* + (*testout) << "seg = " + << "edgenr " << seg.epgeominfo[0].edgenr + << " dist " << seg.epgeominfo[0].dist + << " edgenr " << seg.epgeominfo[1].edgenr + << " dist " << seg.epgeominfo[1].dist << endl; + */ + + seg.geominfo[0].trignum = trig1; + seg.geominfo[1].trignum = trig1b; + + /* + geom.SelectChartOfTriangle (trig1); + hp = hp2 = mesh.Point (seg[0]); + seg.geominfo[0].trignum = geom.Project (hp); + + (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[0].trignum << endl; + if (Dist (hp, hp2) > 1e-5 || seg.geominfo[0].trignum == 0) + { + (*testout) << "PROBLEM" << endl; + } + + geom.SelectChartOfTriangle (trig1b); + hp = hp2 = mesh.Point (seg[1]); + seg.geominfo[1].trignum = geom.Project (hp); + + (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[1].trignum << endl; + if (Dist (hp, hp2) > 1e-5 || seg.geominfo[1].trignum == 0) + { + (*testout) << "PROBLEM" << endl; + } + */ + + + if (Dist (mesh.Point(seg[0]), mesh.Point(seg[1])) < 1e-10) + { + (*testout) << "ERROR: Line segment of length 0" << endl; + (*testout) << "pi1, 2 = " << seg[0] << ", " << seg[1] << endl; + (*testout) << "p1, 2 = " << mesh.Point(seg[0]) + << ", " << mesh.Point(seg[1]) << endl; + throw NgException ("Line segment of length 0"); + } + + mesh.AddSegment (seg); + + + Segment seg2; + seg2[0] = p2; + seg2[1] = p1; + seg2.si = geom.GetTriangle(trig2).GetFaceNum(); + seg2.edgenr = i; + + seg2.epgeominfo[0].edgenr = i; + seg2.epgeominfo[0].dist = line->GetDist(j+1); + seg2.epgeominfo[1].edgenr = i; + seg2.epgeominfo[1].dist = line->GetDist(j); + /* + (*testout) << "seg = " + << "edgenr " << seg2.epgeominfo[0].edgenr + << " dist " << seg2.epgeominfo[0].dist + << " edgenr " << seg2.epgeominfo[1].edgenr + << " dist " << seg2.epgeominfo[1].dist << endl; + */ + + seg2.geominfo[0].trignum = trig2b; + seg2.geominfo[1].trignum = trig2; + + /* + geom.SelectChartOfTriangle (trig2); + hp = hp2 = mesh.Point (seg[0]); + seg2.geominfo[0].trignum = geom.Project (hp); + + (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[0].trignum << endl; + if (Dist (hp, hp2) > 1e-5 || seg2.geominfo[0].trignum == 0) + { + (*testout) << "Get GeomInfo PROBLEM" << endl; + } + + + geom.SelectChartOfTriangle (trig2b); + hp = hp2 = mesh.Point (seg[1]); + seg2.geominfo[1].trignum = geom.Project (hp); + (*testout) << "hp = " << hp2 << ", hp proj = " << hp << ", trignum = " << seg.geominfo[1].trignum << endl; + if (Dist (hp, hp2) > 1e-5 || seg2.geominfo[1].trignum == 0) + { + (*testout) << "Get GeomInfo PROBLEM" << endl; + } + */ + + mesh.AddSegment (seg2); + } + } + + PopStatus(); +} + + + + +void STLSurfaceMeshing1 (STLGeometry & geom, class Mesh & mesh, + int retrynr); + + +int STLSurfaceMeshing (STLGeometry & geom, class Mesh & mesh) +{ + PrintFnStart("Do Surface Meshing"); + + geom.PrepareSurfaceMeshing(); + + if (mesh.GetNSeg() == 0) + STLFindEdges (geom, mesh); + + int nopen; + int outercnt = 20; + + for (int i = 1; i <= mesh.GetNSeg(); i++) + { + const Segment & seg = mesh.LineSegment (i); + if (seg.geominfo[0].trignum <= 0 || seg.geominfo[1].trignum <= 0) + (*testout) << "Problem with segment " << i << ": " << seg << endl; + } + + + do + { + outercnt--; + if (outercnt <= 0) + return MESHING3_OUTERSTEPSEXCEEDED; + + if (multithread.terminate) return MESHING3_TERMINATE; + + mesh.FindOpenSegments(); + nopen = mesh.GetNOpenSegments(); + + if (nopen) + { + int trialcnt = 0; + while (nopen && trialcnt <= 5) + { + if (multithread.terminate) { return MESHING3_TERMINATE; } + + trialcnt++; + STLSurfaceMeshing1 (geom, mesh, trialcnt); + + mesh.FindOpenSegments(); + nopen = mesh.GetNOpenSegments(); + + if (nopen) + { + geom.ClearMarkedSegs(); + for (int i = 1; i <= nopen; i++) + { + const Segment & seg = mesh.GetOpenSegment (i); + geom.AddMarkedSeg(mesh.Point(seg[0]),mesh.Point(seg[1])); + } + + geom.InitMarkedTrigs(); + for (int i = 1; i <= nopen; i++) + { + const Segment & seg = mesh.GetOpenSegment (i); + geom.SetMarkedTrig(seg.geominfo[0].trignum,1); + geom.SetMarkedTrig(seg.geominfo[1].trignum,1); + } + + MeshOptimizeSTLSurface optmesh(geom); + optmesh.SetFaceIndex (0); + optmesh.SetImproveEdges (0); + optmesh.SetMetricWeight (0); + + mesh.CalcSurfacesOfNode(); + optmesh.EdgeSwapping (mesh, 0); + mesh.CalcSurfacesOfNode(); + optmesh.ImproveMesh (mesh, mparam); + } + + mesh.Compress(); + mesh.FindOpenSegments(); + nopen = mesh.GetNOpenSegments(); + + if (trialcnt <= 5 && nopen) + { + mesh.RemoveOneLayerSurfaceElements(); + + if (trialcnt >= 4) + { + mesh.FindOpenSegments(); + mesh.RemoveOneLayerSurfaceElements(); + + mesh.FindOpenSegments (); + nopen = mesh.GetNOpenSegments(); + } + } + } + + + if (multithread.terminate) + return MESHING3_TERMINATE; + + if (nopen) + { + + PrintMessage(3,"Meshing failed, trying to refine"); + + mesh.FindOpenSegments (); + nopen = mesh.GetNOpenSegments(); + + mesh.FindOpenSegments (); + mesh.RemoveOneLayerSurfaceElements(); + mesh.FindOpenSegments (); + mesh.RemoveOneLayerSurfaceElements(); + + // Open edge-segments will be refined ! + INDEX_2_HASHTABLE openseght (nopen+1); + for (int i = 1; i <= mesh.GetNOpenSegments(); i++) + { + const Segment & seg = mesh.GetOpenSegment (i); + INDEX_2 i2(seg[0], seg[1]); + i2.Sort(); + openseght.Set (i2, 1); + } + + + mesh.FindOpenSegments (); + mesh.RemoveOneLayerSurfaceElements(); + mesh.FindOpenSegments (); + mesh.RemoveOneLayerSurfaceElements(); + + + INDEX_2_HASHTABLE newpht(100); + + int nsegold = mesh.GetNSeg(); + for (int i = 1; i <= nsegold; i++) + { + Segment seg = mesh.LineSegment(i); + INDEX_2 i2(seg[0], seg[1]); + i2.Sort(); + if (openseght.Used (i2)) + { + // segment will be split + PrintMessage(7,"Split segment ", int(seg[0]), "-", int(seg[1])); + + Segment nseg1, nseg2; + EdgePointGeomInfo newgi; + + const EdgePointGeomInfo & gi1 = seg.epgeominfo[0]; + const EdgePointGeomInfo & gi2 = seg.epgeominfo[1]; + + newgi.dist = 0.5 * (gi1.dist + gi2.dist); + newgi.edgenr = gi1.edgenr; + + int hi; + + Point3d newp; + int newpi; + + if (!newpht.Used (i2)) + { + newp = geom.GetLine (gi1.edgenr)-> + GetPointInDist (geom.GetPoints(), newgi.dist, hi); + newpi = mesh.AddPoint (newp); + newpht.Set (i2, newpi); + } + else + { + newpi = newpht.Get (i2); + newp = mesh.Point (newpi); + } + + nseg1 = seg; + nseg2 = seg; + nseg1[1] = newpi; + nseg1.epgeominfo[1] = newgi; + + nseg2[0] = newpi; + nseg2.epgeominfo[0] = newgi; + + mesh.LineSegment(i) = nseg1; + mesh.AddSegment (nseg2); + + mesh.RestrictLocalH (Center (mesh.Point(nseg1[0]), + mesh.Point(nseg1[1])), + Dist (mesh.Point(nseg1[0]), + mesh.Point(nseg1[1]))); + mesh.RestrictLocalH (Center (mesh.Point(nseg2[0]), + mesh.Point(nseg2[1])), + Dist (mesh.Point(nseg2[0]), + mesh.Point(nseg2[1]))); + } + } + + } + + nopen = -1; + } + + else + + { + PrintMessage(5,"mesh is closed, verifying ..."); + + // no open elements, check wrong elemetns (intersecting..) + + + + PrintMessage(5,"check overlapping"); + // mesh.FindOpenElements(); // would leed to locked points + if(mesh.CheckOverlappingBoundary()) + return MESHING3_BADSURFACEMESH; + + geom.InitMarkedTrigs(); + + for (int i = 1; i <= mesh.GetNSE(); i++) + if (mesh.SurfaceElement(i).BadElement()) + { + int trig = mesh.SurfaceElement(i).PNum(1); + geom.SetMarkedTrig(trig,1); + PrintMessage(7, "overlapping element, will be removed"); + } + + + + Array refpts; + Array refh; + + // was commented: + + for (int i = 1; i <= mesh.GetNSE(); i++) + if (mesh.SurfaceElement(i).BadElement()) + { + for (int j = 1; j <= 3; j++) + { + refpts.Append (mesh.Point (mesh.SurfaceElement(i).PNum(j))); + refh.Append (mesh.GetH (refpts.Last()) / 2); + } + mesh.DeleteSurfaceElement(i); + } + + // delete wrong oriented element + for (int i = 1; i <= mesh.GetNSE(); i++) + { + const Element2d & el = mesh.SurfaceElement(i); + if (!el.PNum(1)) + continue; + + Vec3d n = Cross (Vec3d (mesh.Point(el.PNum(1)), + mesh.Point(el.PNum(2))), + Vec3d (mesh.Point(el.PNum(1)), + mesh.Point(el.PNum(3)))); + Vec3d ng = geom.GetTriangle(el.GeomInfoPi(1).trignum).Normal(); + if (n * ng < 0) + { + refpts.Append (mesh.Point (mesh.SurfaceElement(i).PNum(1))); + refh.Append (mesh.GetH (refpts.Last()) / 2); + mesh.DeleteSurfaceElement(i); + } + } + // end comments + + for (int i = 1; i <= refpts.Size(); i++) + mesh.RestrictLocalH (refpts.Get(i), refh.Get(i)); + + mesh.RemoveOneLayerSurfaceElements(); + + mesh.Compress(); + + mesh.FindOpenSegments (); + nopen = mesh.GetNOpenSegments(); + + /* + if (!nopen) + { + // mesh is still ok + + void STLSurfaceOptimization (STLGeometry & geom, + class Mesh & mesh, + MeshingParameters & mparam) + + } + */ + } + + } + while (nopen); + + mesh.Compress(); + mesh.CalcSurfacesOfNode(); + + return MESHING3_OK; +} + + + + + + +void STLSurfaceMeshing1 (STLGeometry & geom, + class Mesh & mesh, + int retrynr) +{ + static int timer1 = NgProfiler::CreateTimer ("STL surface meshing1"); + static int timer1a = NgProfiler::CreateTimer ("STL surface meshing1a"); + static int timer1b = NgProfiler::CreateTimer ("STL surface meshing1b"); + static int timer1c = NgProfiler::CreateTimer ("STL surface meshing1c"); + static int timer1d = NgProfiler::CreateTimer ("STL surface meshing1d"); + + double h = mparam.maxh; + + mesh.FindOpenSegments(); + + Array spiralps(0); + spiralps.SetSize(0); + for (int i = 1; i <= geom.GetNP(); i++) + if (geom.GetSpiralPoint(i)) + spiralps.Append(i); + + PrintMessage(7,"NO spiralpoints = ", spiralps.Size()); + //int spfound; + + /* + Array meshsp(mesh.GetNP()); + meshsp = 0; + for (int i = 1; i <= mesh.GetNP(); i++) + for (int j = 1; j <= spiralps.Size(); j++) + if (Dist2(geom.GetPoint(spiralps.Get(j)), mesh.Point(i)) < 1e-20) + meshsp.Elem(i) = spiralps.Get(j); + Array imeshsp; + for (int i = 1; i <= meshsp.Size(); i++) + if (meshsp.Elem(i)) imeshsp.Append(i); + */ + Array imeshsp; + Array ispiral_point; + for (int i = 1; i <= mesh.GetNP(); i++) + { + for (int j = 1; j <= spiralps.Size(); j++) + if (Dist2(geom.GetPoint(spiralps.Get(j)), mesh.Point(i)) < 1e-20) + { + imeshsp.Append(i); + ispiral_point.Append(spiralps.Get(j)); + break; + } + } + + double starttime = GetTime (); + mesh.SurfaceArea().ReCalc(); + + int oldnp = mesh.GetNP(); + + Array compress(mesh.GetNP()); + compress = 0; + Array icompress; + + Array opensegsperface(mesh.GetNFD()); + opensegsperface = 0; + for (int i = 1; i <= mesh.GetNOpenSegments(); i++) + opensegsperface[mesh.GetOpenSegment(i).si]++; + + TABLE opensegments(mesh.GetNFD()); + for (int i = 1; i <= mesh.GetNOpenSegments(); i++) + { + const Segment & seg = mesh.GetOpenSegment (i); + if (seg.si < 1 || seg.si > mesh.GetNFD()) + cerr << "segment index " << seg.si << " out of range [1, " << mesh.GetNFD() << "]" << endl; + opensegments.Add (seg.si, i); + } + + + for (int fnr = 1; fnr <= mesh.GetNFD(); fnr++) + { + if (fnr == 100) NgProfiler::ClearTimers(); + if (!opensegsperface[fnr]) continue; + if (multithread.terminate) return; + + NgProfiler::StartTimer (timer1); + NgProfiler::StartTimer (timer1a); + + + PrintMessage(5,"Meshing surface ", fnr, "/", mesh.GetNFD()); + MeshingSTLSurface meshing (geom, mparam); + meshing.SetStartTime (starttime); + + // compress = 0; + icompress.SetSize(0); + int cntused = 0; + + for (int i = 0; i < imeshsp.Size(); i++) + { + compress[imeshsp[i]] = ++cntused; + icompress.Append(imeshsp[i]); + } + + NgProfiler::StopTimer (timer1a); + NgProfiler::StartTimer (timer1b); + + + + /* + for (int i = 1; i <= mesh.GetNOpenSegments(); i++) + { + const Segment & seg = mesh.GetOpenSegment (i); + if (seg.si == fnr) + for (int j = 0; j < 2; j++) + if (compress[seg[j]] == 0) + { + compress[seg[j]] = ++cntused; + icompress.Append(seg[j]); + } + } + */ + FlatArray segs = opensegments[fnr]; + for (int hi = 0; hi < segs.Size(); hi++) + { + int i = segs[hi]; + const Segment & seg = mesh.GetOpenSegment (i); + for (int j = 0; j < 2; j++) + if (compress[seg[j]] == 0) + { + compress[seg[j]] = ++cntused; + icompress.Append(seg[j]); + } + } + + NgProfiler::StopTimer (timer1b); + NgProfiler::StartTimer (timer1c); + + + for (int hi = 0; hi < icompress.Size(); hi++) + { + PointIndex pi = icompress[hi]; + + /* + // int sppointnum = meshsp.Get(i); + int sppointnum = 0; + if (hi < ispiral_point.Size()) + sppointnum = ispiral_point[hi]; + + if (sppointnum) + { + */ + if (hi < ispiral_point.Size()) + { + int sppointnum = ispiral_point[hi]; + + MultiPointGeomInfo mgi; + + int ntrigs = geom.NOTrigsPerPoint(sppointnum); + for (int j = 0; j < ntrigs; j++) + { + PointGeomInfo gi; + gi.trignum = geom.TrigPerPoint(sppointnum, j+1); + mgi.AddPointGeomInfo (gi); + } + + // Einfuegen von ConePoint: Point bekommt alle + // Dreiecke (werden dann intern kopiert) + // Ein Segment zum ConePoint muss vorhanden sein !!! + + // meshing.AddPoint (mesh.Point(i), i, &mgi); + meshing.AddPoint (mesh[pi], pi, &mgi); + } + else + meshing.AddPoint (mesh[pi], pi); + } + + NgProfiler::StopTimer (timer1c); + NgProfiler::StartTimer (timer1d); + + /* + for (int i = 1; i <= mesh.GetNOpenSegments(); i++) + { + const Segment & seg = mesh.GetOpenSegment (i); + if (seg.si == fnr) + meshing.AddBoundaryElement (compress[seg[0]], compress[seg[1]], + seg.geominfo[0], seg.geominfo[1]); + } + */ + + + // FlatArray segs = opensegments[fnr]; + for (int hi = 0; hi < segs.Size(); hi++) + { + int i = segs[hi]; + const Segment & seg = mesh.GetOpenSegment (i); + meshing.AddBoundaryElement (compress[seg[0]], compress[seg[1]], + seg.geominfo[0], seg.geominfo[1]); + } + + + + NgProfiler::StopTimer (timer1d); + + NgProfiler::StopTimer (timer1); + + PrintMessage(3,"start meshing, trialcnt = ", retrynr); + + meshing.GenerateMesh (mesh, mparam, h, fnr); + + for (int i = 0; i < icompress.Size(); i++) + compress[icompress[i]] = 0; + + + extern void Render(); + Render(); + } + + // NgProfiler::Print(stdout); + + mesh.CalcSurfacesOfNode(); +} + + + +void STLSurfaceOptimization (STLGeometry & geom, + class Mesh & mesh, + MeshingParameters & meshparam) +{ + PrintFnStart("optimize STL Surface"); + + MeshOptimizeSTLSurface optmesh(geom); + + optmesh.SetFaceIndex (0); + optmesh.SetImproveEdges (0); + optmesh.SetMetricWeight (meshparam.elsizeweight); + + PrintMessage(5,"optimize string = ", meshparam.optimize2d, " elsizew = ", meshparam.elsizeweight); + + for (int i = 1; i <= meshparam.optsteps2d; i++) + for (size_t j = 1; j <= strlen(meshparam.optimize2d); j++) + { + if (multithread.terminate) + break; + + //(*testout) << "optimize, before, step = " << meshparam.optimize2d[j-1] << mesh.Point (3679) << endl; + + mesh.CalcSurfacesOfNode(); + switch (meshparam.optimize2d[j-1]) + { + case 's': + { + optmesh.EdgeSwapping (mesh, 0); + break; + } + case 'S': + { + optmesh.EdgeSwapping (mesh, 1); + break; + } + case 'm': + { + optmesh.ImproveMesh(mesh, mparam); + break; + } + case 'c': + { + optmesh.CombineImprove (mesh); + break; + } + } + //(*testout) << "optimize, after, step = " << meshparam.optimize2d[j-1] << mesh.Point (3679) << endl; + } + + geom.surfaceoptimized = 1; + + mesh.Compress(); + mesh.CalcSurfacesOfNode(); + + +} + + + +MeshingSTLSurface :: MeshingSTLSurface (STLGeometry & ageom, + const MeshingParameters & mp) + : Meshing2(mp, ageom.GetBoundingBox()), geom(ageom) +{ + ; +} + +void MeshingSTLSurface :: DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo, + const PointGeomInfo * geominfo2) +{ + transformationtrig = geominfo[0].trignum; + + geom.DefineTangentialPlane(p1, p2, transformationtrig); +} + +void MeshingSTLSurface :: TransformToPlain (const Point3d & locpoint, const MultiPointGeomInfo & gi, + Point2d & plainpoint, double h, int & zone) +{ + int trigs[10000]; + + if (gi.GetNPGI() >= 9999) + { + PrintError("In Transform to plane: increase size of trigs!!!"); + } + + for (int i = 1; i <= gi.GetNPGI(); i++) + trigs[i-1] = gi.GetPGI(i).trignum; + trigs[gi.GetNPGI()] = 0; + + // int trig = gi.trignum; + // (*testout) << "locpoint = " << locpoint; + + Point<2> hp2d; + geom.ToPlane (locpoint, trigs, hp2d, h, zone, 1); + plainpoint = hp2d; + + // geom.ToPlane (locpoint, NULL, plainpoint, h, zone, 1); + /* + (*testout) << " plainpoint = " << plainpoint + << " h = " << h + << endl; + */ +} + +/* +int MeshingSTLSurface :: ComputeLineGeoInfo (const Point3d & p1, const Point3d & p2, + int & geoinfosize, void *& geoinfo) +{ + static int geomtrig[2] = { 0, 0 }; + + Point3d hp; + hp = p1; + geomtrig[0] = geom.Project (hp); + + hp = p2; + geomtrig[1] = geom.Project (hp); + + geoinfosize = sizeof (geomtrig); + geoinfo = &geomtrig; + + if (geomtrig[0] == 0) + { + return 1; + } + return 0; +} +*/ + + +int MeshingSTLSurface :: ComputePointGeomInfo (const Point3d & p, PointGeomInfo & gi) +{ + // compute triangle of point, + // if non-unique: 0 + + Point<3> hp = p; + gi.trignum = geom.Project (hp); + + if (!gi.trignum) + { + return 1; + } + + return 0; +} + + +int MeshingSTLSurface :: +ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, + PointGeomInfo & pgi) +{ + for (int i = 1; i <= mpgi.GetNPGI(); i++) + if (geom.TrigIsInOC (mpgi.GetPGI(i).trignum, geom.meshchart)) + { + pgi = mpgi.GetPGI(i); + return 0; + } + /* + for (i = 0; i < mpgi.cnt; i++) + { + // (*testout) << "d" << endl; + if (geom.TrigIsInOC (mpgi.mgi[i].trignum, geom.meshchart)) + { + pgi = mpgi.mgi[i]; + return 0; + } + } + */ + PrintMessage(7,"INFORM: no gi on chart"); + pgi.trignum = 1; + return 1; +} + + + +int MeshingSTLSurface :: +IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, + int endpoint, const PointGeomInfo & gi) +{ + Vec3d baselinenormal = geom.meshtrignv; + + int lineendtrig = gi.trignum; + + + return geom.TrigIsInOC (lineendtrig, geom.meshchart); + + // Vec3d linenormal = geom.GetTriangleNormal (lineendtrig); + // return ( (baselinenormal * linenormal) > cos (30 * (M_PI/180)) ); +} + +void MeshingSTLSurface :: +GetChartBoundary (Array & points, + Array & points3d, + Array & lines, double h) const +{ + points.SetSize (0); + points3d.SetSize (0); + lines.SetSize (0); + geom.GetMeshChartBoundary (points, points3d, lines, h); +} + + + + +int MeshingSTLSurface :: TransformFromPlain (Point2d & plainpoint, + Point3d & locpoint, + PointGeomInfo & gi, + double h) +{ + //return 0, wenn alles OK + Point<3> hp3d; + int res = geom.FromPlane (plainpoint, hp3d, h); + locpoint = hp3d; + ComputePointGeomInfo (locpoint, gi); + return res; +} + + +int MeshingSTLSurface :: +BelongsToActiveChart (const Point3d & p, + const PointGeomInfo & gi) +{ + return (geom.TrigIsInOC(gi.trignum, geom.meshchart) != 0); +} + + + +double MeshingSTLSurface :: CalcLocalH (const Point3d & p, double gh) const +{ + return gh; +} + +double MeshingSTLSurface :: Area () const +{ + return geom.Area(); +} + + + + + + +MeshOptimizeSTLSurface :: MeshOptimizeSTLSurface (STLGeometry & ageom) + : MeshOptimize2d(), geom(ageom) +{ + ; +} + + +void MeshOptimizeSTLSurface :: SelectSurfaceOfPoint (const Point<3> & p, + const PointGeomInfo & gi) +{ + // (*testout) << "sel char: " << gi.trignum << endl; + + geom.SelectChartOfTriangle (gi.trignum); + // geom.SelectChartOfPoint (p); +} + + +void MeshOptimizeSTLSurface :: ProjectPoint (INDEX surfind, Point<3> & p) const +{ + if (!geom.Project (p)) + { + PrintMessage(7,"project failed"); + + if (!geom.ProjectOnWholeSurface(p)) + { + PrintMessage(7, "project on whole surface failed"); + } + } + + // geometry.GetSurface(surfind)->Project (p); +} + +void MeshOptimizeSTLSurface :: ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const +{ + /* + ProjectToEdge ( geometry.GetSurface(surfind), + geometry.GetSurface(surfind2), p); + */ +} + +int MeshOptimizeSTLSurface :: CalcPointGeomInfo(PointGeomInfo& gi, const Point<3> & p3) const +{ + Point<3> hp = p3; + gi.trignum = geom.Project (hp); + + if (gi.trignum) return 1; + + return 0; + +} + +void MeshOptimizeSTLSurface :: GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const +{ + n = geom.GetChartNormalVector(); +} + + + + + + + + + + +RefinementSTLGeometry :: RefinementSTLGeometry (const STLGeometry & ageom) + : Refinement(), geom(ageom) +{ + ; +} + +RefinementSTLGeometry :: ~RefinementSTLGeometry () +{ + ; +} + +void RefinementSTLGeometry :: +PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const +{ + newp = p1+secpoint*(p2-p1); + + /* + (*testout) << "surf-between: p1 = " << p1 << ", p2 = " << p2 + << ", gi = " << gi1 << " - " << gi2 << endl; + */ + + if (gi1.trignum > 0) + { + // ((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum); + + Point<3> np1 = newp; + Point<3> np2 = newp; + ((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum); + int tn1 = geom.Project (np1); + + ((STLGeometry&)geom).SelectChartOfTriangle (gi2.trignum); + int tn2 = geom.Project (np2); + + newgi.trignum = tn1; //urspruengliche version + newp = np1; //urspruengliche version + + if (!newgi.trignum) + { newgi.trignum = tn2; newp = np2; } + if (!newgi.trignum) newgi.trignum = gi1.trignum; + + /* + if (tn1 != 0 && tn2 != 0 && ((STLGeometry&)geom).GetAngle(tn1,tn2) < M_PI*0.05) { + newgi.trignum = tn1; + newp = np1; + } + else + { + newp = ((STLGeometry&)geom).PointBetween(p1, gi1.trignum, p2, gi2.trignum); + tn1 = ((STLGeometry&)geom).Project(newp); + newgi.trignum = tn1; + + if (!tn1) + { + newp = Center (p1, p2); + newgi.trignum = 0; + + } + } + */ + } + else + { + // (*testout) << "WARNING: PointBetween got geominfo = 0" << endl; + newp = p1+secpoint*(p2-p1); + newgi.trignum = 0; + } + + // (*testout) << "newp = " << newp << ", ngi = " << newgi << endl; +} + +void RefinementSTLGeometry :: +PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & gi1, + const EdgePointGeomInfo & gi2, + Point<3> & newp, EdgePointGeomInfo & newgi) const +{ + /* + (*testout) << "edge-between: p1 = " << p1 << ", p2 = " << p2 + << ", gi1,2 = " << gi1 << ", " << gi2 << endl; + */ + /* + newp = Center (p1, p2); + ((STLGeometry&)geom).SelectChartOfTriangle (gi1.trignum); + newgi.trignum = geom.Project (newp); + */ + int hi; + newgi.dist = (1.0-secpoint) * gi1.dist + secpoint*gi2.dist; + newgi.edgenr = gi1.edgenr; + + /* + (*testout) << "p1 = " << p1 << ", p2 = " << p2 << endl; + (*testout) << "refedge: " << gi1.edgenr + << " d1 = " << gi1.dist << ", d2 = " << gi2.dist << endl; + */ + newp = geom.GetLine (gi1.edgenr)->GetPointInDist (geom.GetPoints(), newgi.dist, hi); + + // (*testout) << "newp = " << newp << endl; +} + + +void RefinementSTLGeometry :: ProjectToSurface (Point<3> & p, int surfi) const +{ + cout << "RefinementSTLGeometry :: ProjectToSurface not implemented!" << endl; +}; + + +void RefinementSTLGeometry :: ProjectToSurface (Point<3> & p, int surfi, + PointGeomInfo & gi) const +{ + ((STLGeometry&)geom).SelectChartOfTriangle (gi.trignum); + gi.trignum = geom.Project (p); + // if (!gi.trignum) + // cout << "projectSTL failed" << endl; +}; + + +} diff --git a/libsrc/stlgeom/meshstlsurface.hpp b/libsrc/stlgeom/meshstlsurface.hpp new file mode 100644 index 00000000..4e678439 --- /dev/null +++ b/libsrc/stlgeom/meshstlsurface.hpp @@ -0,0 +1,121 @@ +#ifndef FILE_MESHSTLSURF +#define FILE_MESHSTLSURF + +/* *************************************************************************/ +/* File: meshstlsurf.hpp */ +/* Author: Johannes Gerstmayr, Joachim Schoeberl */ +/* Date: 01. Aug. 99 */ +/* *************************************************************************/ + +/* + +The interface between mesh generation and stl geometry + +*/ + + +/// +class MeshingSTLSurface : public Meshing2 +{ + /// + STLGeometry & geom; + /// + int transformationtrig; +public: + /// + MeshingSTLSurface (STLGeometry & ageom, const MeshingParameters & mp); + +protected: + /// + virtual void DefineTransformation (const Point3d & p1, const Point3d & p2, + const PointGeomInfo * geominfo1, + const PointGeomInfo * geominfo2); + /// + virtual void TransformToPlain (const Point3d & locpoint, const MultiPointGeomInfo & geominfo, + Point2d & plainpoint, double h, int & zone); + /// + virtual int TransformFromPlain (Point2d & plainpoint, + Point3d & locpoint, + PointGeomInfo & gi, + double h); + /// + virtual int BelongsToActiveChart (const Point3d & p, + const PointGeomInfo & gi); + + /// + virtual int ComputePointGeomInfo (const Point3d & p, PointGeomInfo & gi); + /// + virtual int ChooseChartPointGeomInfo (const MultiPointGeomInfo & mpgi, + PointGeomInfo & pgi); + + /// + virtual int IsLineVertexOnChart (const Point3d & p1, const Point3d & p2, + int endpoint, const PointGeomInfo & gi); + + virtual void GetChartBoundary (Array & points, + Array & poitns3d, + Array & lines, double h) const; + + /// + virtual double CalcLocalH (const Point3d & p, double gh) const; + + /// + virtual double Area () const; +}; + + + +/// +class MeshOptimizeSTLSurface : public MeshOptimize2d + { + /// + STLGeometry & geom; + +public: + /// + MeshOptimizeSTLSurface (STLGeometry & ageom); + + /// + virtual void SelectSurfaceOfPoint (const Point<3> & p, + const PointGeomInfo & gi); + /// + virtual void ProjectPoint (INDEX surfind, Point<3> & p) const; + /// + virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point<3> & p) const; + /// + virtual int CalcPointGeomInfo(PointGeomInfo& gi, const Point<3> & p3) const; + /// + virtual void GetNormalVector(INDEX surfind, const Point<3> & p, Vec<3> & n) const; +}; + + + + +class RefinementSTLGeometry : public Refinement +{ + const STLGeometry & geom; + +public: + RefinementSTLGeometry (const STLGeometry & ageom); + virtual ~RefinementSTLGeometry (); + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi, + const PointGeomInfo & gi1, + const PointGeomInfo & gi2, + Point<3> & newp, PointGeomInfo & newgi) const; + + virtual void PointBetween (const Point<3> & p1, const Point<3> & p2, double secpoint, + int surfi1, int surfi2, + const EdgePointGeomInfo & ap1, + const EdgePointGeomInfo & ap2, + Point<3> & newp, EdgePointGeomInfo & newgi) const; + + virtual void ProjectToSurface (Point<3> & p, int surfi) const; + virtual void ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi) const; +}; + + + +#endif + diff --git a/libsrc/stlgeom/stlgeom.cpp b/libsrc/stlgeom/stlgeom.cpp new file mode 100644 index 00000000..795a2713 --- /dev/null +++ b/libsrc/stlgeom/stlgeom.cpp @@ -0,0 +1,3580 @@ +#include + +#include "stlgeom.hpp" + +namespace netgen +{ + +//globalen searchtree fuer gesamte geometry aktivieren +int geomsearchtreeon = 0; + +int usechartnormal = 1; + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +void STLMeshing (STLGeometry & geom, + Mesh & mesh) +{ + geom.Clear(); + geom.BuildEdges(); + geom.MakeAtlas(mesh); + geom.CalcFaceNums(); + geom.AddFaceEdges(); + geom.LinkEdges(); + + mesh.ClearFaceDescriptors(); + for (int i = 1; i <= geom.GetNOFaces(); i++) + mesh.AddFaceDescriptor (FaceDescriptor (i, 1, 0, 0)); +} + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//+++++++++++++++++++ STL GEOMETRY ++++++++++++++++++++++++++++ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + STLGeometry :: STLGeometry() + /* + : edges(), edgesperpoint(), + normals(), externaledges(), + atlas(), chartmark(), + lines(), outerchartspertrig(), vicinity(), markedtrigs(), markedsegs(), + lineendpoints(), spiralpoints(), selectedmultiedge() + */ +{ + ref = NULL; + edgedata = new STLEdgeDataList(*this); + externaledges.SetSize(0); + Clear(); + meshchart = 0; // initialize all ?? JS + + if (geomsearchtreeon) + searchtree = new Box3dTree (GetBoundingBox().PMin() - Vec3d(1,1,1), + GetBoundingBox().PMax() + Vec3d(1,1,1)); + else + searchtree = NULL; + + status = STL_GOOD; + statustext = "Good Geometry"; + smoothedges = NULL; + area = -1; +} + +STLGeometry :: ~STLGeometry() +{ + delete edgedata; + delete ref; +} + +void STLGeometry :: Save (string filename) const +{ + const char * cfilename = filename.c_str(); + if (strlen(cfilename) < 4) + throw NgException ("illegal filename"); + + if (strlen(cfilename) > 3 && + strcmp (&cfilename[strlen(cfilename)-3], "stl") == 0) + { + STLTopology::Save (cfilename); + } + else if (strlen(cfilename) > 4 && + strcmp (&cfilename[strlen(cfilename)-4], "stlb") == 0) + { + SaveBinary (cfilename,"Binary STL Geometry"); + + } + else if (strlen(cfilename) > 4 && + strcmp (&cfilename[strlen(cfilename)-4], "stle") == 0) + { + SaveSTLE (cfilename); + } +} + + + +int STLGeometry :: GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend) +{ + return STLMeshingDummy (this, mesh, mparam, perfstepsstart, perfstepsend); +} + + +const Refinement & STLGeometry :: GetRefinement () const +{ + delete ref; + ref = new RefinementSTLGeometry(*this); + // ref -> Set2dOptimizer(new MeshOptimizeSTLSurface(*this)); ??? copied from CSG + return *ref; + +} + + + +void STLGeometry :: STLInfo(double* data) +{ + data[0] = GetNT(); + + Box<3> b = GetBoundingBox(); + data[1] = b.PMin()(0); + data[2] = b.PMax()(0); + data[3] = b.PMin()(1); + data[4] = b.PMax()(1); + data[5] = b.PMin()(2); + data[6] = b.PMax()(2); + + int i; + + int cons = 1; + for (i = 1; i <= GetNT(); i++) + { + if (NONeighbourTrigs(i) != 3) {cons = 0;} + } + data[7] = cons; +} + +void STLGeometry :: MarkNonSmoothNormals() +{ + + PrintFnStart("Mark Non-Smooth Normals"); + + int i,j; + + markedtrigs.SetSize(GetNT()); + + for (i = 1; i <= GetNT(); i++) + { + SetMarkedTrig(i, 0); + } + + double dirtyangle = stlparam.yangle/180.*M_PI; + + int cnt = 0; + int lp1,lp2; + for (i = 1; i <= GetNT(); i++) + { + for (j = 1; j <= NONeighbourTrigs(i); j++) + { + if (GetAngle(i, NeighbourTrig(i,j)) > dirtyangle) + { + GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), lp1, lp2); + if (!IsEdge(lp1,lp2)) + { + if (!IsMarkedTrig(i)) {SetMarkedTrig(i,1); cnt++;} + } + } + } + } + + PrintMessage(5,"marked ",cnt," non-smooth trig-normals"); + +} + +void STLGeometry :: SmoothNormals() +{ + multithread.terminate = 0; + + // UseExternalEdges(); + + BuildEdges(); + + + DenseMatrix m(3), hm(3); + Vector rhs(3), sol(3), hv(3), hv2(3); + + Vec<3> ri; + + double wnb = stldoctor.smoothnormalsweight; // neigbour normal weight + double wgeom = 1-wnb; // geometry normal weight + + + // minimize + // wgeom sum_T \sum ri \| ri^T (n - n_geom) \|^2 + // + wnb sum_SE \| ri x (n - n_nb) \|^2 + + int i, j, k, l; + int nt = GetNT(); + + PushStatusF("Smooth Normals"); + + //int testmode; + + for (i = 1; i <= nt; i++) + { + + SetThreadPercent( 100.0 * (double)i / (double)nt); + + const STLTriangle & trig = GetTriangle (i); + + m = 0; + rhs = 0; + + // normal of geometry: + Vec<3> ngeom = trig.GeomNormal(points); + ngeom.Normalize(); + + for (j = 1; j <= 3; j++) + { + int pi1 = trig.PNumMod (j); + int pi2 = trig.PNumMod (j+1); + + // edge vector + ri = GetPoint (pi2) - GetPoint (pi1); + + for (k = 0; k < 3; k++) + for (l = 0; l < 3; l++) + hm.Elem(k+1, l+1) = wgeom * ri(k) * ri(l); + + + for (k = 0; k < 3; k++) + hv(k) = ngeom(k); + + hm.Mult (hv, hv2); + /* + if (testmode) + (*testout) << "add vec " << hv2 << endl + << " add m " << hm << endl; + */ + rhs.Add (1, hv2); + m += hm; + + + int nbt = 0; + int fp1,fp2; + for (k = 1; k <= NONeighbourTrigs(i); k++) + { + trig.GetNeighbourPoints(GetTriangle(NeighbourTrig(i, k)),fp1,fp2); + if (fp1 == pi1 && fp2 == pi2) + { + nbt = NeighbourTrig(i, k); + } + } + + if (!nbt) + { + cerr << "ERROR: stlgeom::Smoothnormals, nbt = 0" << endl; + } + + // smoothed normal + Vec<3> nnb = GetTriangle(nbt).Normal(); // neighbour normal + nnb.Normalize(); + + if (!IsEdge(pi1,pi2)) + { + double lr2 = ri * ri; + for (k = 0; k < 3; k++) + { + for (l = 0; l < k; l++) + { + hm.Elem(k+1, l+1) = -wnb * ri(k) * ri(l); + hm.Elem(l+1, k+1) = -wnb * ri(k) * ri(l); + } + + hm.Elem(k+1, k+1) = wnb * (lr2 - ri(k) * ri(k)); + } + + for (k = 0; k < 3; k++) + hv(k) = nnb(k); + + hm.Mult (hv, hv2); + /* + if (testmode) + (*testout) << "add nb vec " << hv2 << endl + << " add nb m " << hm << endl; + */ + + rhs.Add (1, hv2); + m += hm; + } + } + + m.Solve (rhs, sol); + Vec3d newn(sol(0), sol(1), sol(2)); + newn /= (newn.Length() + 1e-24); + + GetTriangle(i).SetNormal(newn); + // setnormal (sol); + } + + /* + for (i = 1; i <= nt; i++) + SetMarkedTrig(i, 0); + + + + int crloop; + for (crloop = 1; crloop <= 3; crloop++) + { + + // find critical: + + Array critpairs; + for (i = 1; i <= nt; i++) + { + const STLTriangle & trig = GetTriangle (i); + + Vec3d ngeom = GetTriangleNormal (i); // trig.Normal(points); + ngeom /= (ngeom.Length() + 1e-24); + + for (j = 1; j <= 3; j++) + { + int pi1 = trig.PNumMod (j); + int pi2 = trig.PNumMod (j+1); + + int nbt = 0; + int fp1,fp2; + for (k = 1; k <= NONeighbourTrigs(i); k++) + { + trig.GetNeighbourPoints(GetTriangle(NeighbourTrig(i, k)),fp1,fp2); + if (fp1 == pi1 && fp2 == pi2) + { + nbt = NeighbourTrig(i, k); + } + } + + if (!nbt) + { + cerr << "ERROR: stlgeom::Smoothnormals, nbt = 0" << endl; + } + + Vec3d nnb = GetTriangleNormal(nbt); // neighbour normal + nnb /= (nnb.Length() + 1e-24); + + if (!IsEdge(pi1,pi2)) + { + if (Angle (nnb, ngeom) > 150 * M_PI/180) + { + SetMarkedTrig(i, 1); + SetMarkedTrig(nbt, 1); + critpairs.Append (INDEX_2 (i, nbt)); + } + } + + } + } + + if (!critpairs.Size()) + { + break; + } + + if (critpairs.Size()) + { + + Array friends; + double area1 = 0, area2 = 0; + + for (i = 1; i <= critpairs.Size(); i++) + { + int tnr1 = critpairs.Get(i).I1(); + int tnr2 = critpairs.Get(i).I2(); + (*testout) << "t1 = " << tnr1 << ", t2 = " << tnr2 + << " angle = " << Angle (GetTriangleNormal (tnr1), + GetTriangleNormal (tnr2)) + << endl; + + // who has more friends ? + int side; + area1 = 0; + area2 = 0; + for (side = 1; side <= 2; side++) + { + friends.SetSize (0); + friends.Append ( (side == 1) ? tnr1 : tnr2); + + for (j = 1; j <= 3; j++) + { + int fsize = friends.Size(); + for (k = 1; k <= fsize; k++) + { + int testtnr = friends.Get(k); + Vec3d ntt = GetTriangleNormal(testtnr); + ntt /= (ntt.Length() + 1e-24); + + for (l = 1; l <= NONeighbourTrigs(testtnr); l++) + { + int testnbnr = NeighbourTrig(testtnr, l); + Vec3d nbt = GetTriangleNormal(testnbnr); + nbt /= (nbt.Length() + 1e-24); + + if (Angle (nbt, ntt) < 15 * M_PI/180) + { + int ii; + int found = 0; + for (ii = 1; ii <= friends.Size(); ii++) + { + if (friends.Get(ii) == testnbnr) + { + found = 1; + break; + } + } + if (!found) + friends.Append (testnbnr); + } + } + } + } + + // compute area: + for (k = 1; k <= friends.Size(); k++) + { + double area = + GetTriangle (friends.Get(k)).Area(points); + + if (side == 1) + area1 += area; + else + area2 += area; + } + + } + + (*testout) << "area1 = " << area1 << " area2 = " << area2 << endl; + if (area1 < 0.1 * area2) + { + Vec3d n = GetTriangleNormal (tnr1); + n *= -1; + SetTriangleNormal(tnr1, n); + } + if (area2 < 0.1 * area1) + { + Vec3d n = GetTriangleNormal (tnr2); + n *= -1; + SetTriangleNormal(tnr2, n); + } + } + } + } + */ + + calcedgedataanglesnew = 1; + PopStatus(); +} + + +int STLGeometry :: AddEdge(int ap1, int ap2) +{ + STLEdge e(ap1,ap2); + e.SetLeftTrig(GetLeftTrig(ap1,ap2)); + e.SetRightTrig(GetRightTrig(ap1,ap2)); + return edges.Append(e); +} + +void STLGeometry :: STLDoctorConfirmEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CONFIRMED); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CONFIRMED); + } + } + } +} + +void STLGeometry :: STLDoctorCandidateEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CANDIDATE); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus (ED_CANDIDATE); + } + } + } +} + +void STLGeometry :: STLDoctorExcludeEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_EXCLUDED); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_EXCLUDED); + } + } + } +} + +void STLGeometry :: STLDoctorUndefinedEdge() +{ + StoreEdgeData(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT() && GetNodeOfSelTrig()) + { + if (stldoctor.selectmode == 1) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_UNDEFINED); + } + else if (stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + int i; + for (i = 1; i <= selectedmultiedge.Size(); i++) + { + int ap1 = selectedmultiedge.Get(i).i1; + int ap2 = selectedmultiedge.Get(i).i2; + edgedata->Elem(edgedata->GetEdgeNum(ap1,ap2)).SetStatus(ED_UNDEFINED); + } + } + } +} + +void STLGeometry :: STLDoctorSetAllUndefinedEdges() +{ + edgedata->ResetAll(); +} + +void STLGeometry :: STLDoctorEraseCandidateEdges() +{ + StoreEdgeData(); + edgedata->ChangeStatus(ED_CANDIDATE, ED_UNDEFINED); +} + +void STLGeometry :: STLDoctorConfirmCandidateEdges() +{ + StoreEdgeData(); + edgedata->ChangeStatus(ED_CANDIDATE, ED_CONFIRMED); +} + +void STLGeometry :: STLDoctorConfirmedToCandidateEdges() +{ + StoreEdgeData(); + edgedata->ChangeStatus(ED_CONFIRMED, ED_CANDIDATE); +} + +void STLGeometry :: STLDoctorDirtyEdgesToCandidates() +{ + StoreEdgeData(); +} + +void STLGeometry :: STLDoctorLongLinesToCandidates() +{ + StoreEdgeData(); +} + +twoint STLGeometry :: GetNearestSelectedDefinedEdge() +{ + Point<3> pestimate = Center(GetTriangle(GetSelectTrig()).center, + GetPoint(GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()))); + //Point3d pestimate = GetTriangle(GetSelectTrig()).center; + + int i, j, en; + Array vic; + GetVicinity(GetSelectTrig(),4,vic); + + + twoint fedg; + fedg.i1 = 0; + fedg.i2 = 0; + double mindist = 1E50; + double dist; + Point<3> p; + + for (i = 1; i <= vic.Size(); i++) + { + const STLTriangle& t = GetTriangle(vic.Get(i)); + for (j = 1; j <= 3; j++) + { + en = edgedata->GetEdgeNum(t.PNum(j),t.PNumMod(j+1)); + if (edgedata->Get(en).GetStatus() != ED_UNDEFINED) + { + p = pestimate; + dist = GetDistFromLine(GetPoint(t.PNum(j)),GetPoint(t.PNumMod(j+1)),p); + if (dist < mindist) + { + mindist = dist; + fedg.i1 = t.PNum(j); + fedg.i2 = t.PNumMod(j+1); + } + } + } + } + return fedg; +} + +void STLGeometry :: BuildSelectedMultiEdge(twoint ep) +{ + if (edgedata->Size() == 0 || + !GetEPPSize()) + { + return; + } + + selectedmultiedge.SetSize(0); + int tenum = GetTopEdgeNum (ep.i1, ep.i2); + + if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED) + { + twoint epnew = GetNearestSelectedDefinedEdge(); + if (epnew.i1) + { + ep = epnew; + tenum = GetTopEdgeNum (ep.i1, ep.i2); + } + } + + selectedmultiedge.Append(twoint(ep)); + + if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED) + { + return; + } + + edgedata->BuildLineWithEdge(ep.i1,ep.i2,selectedmultiedge); +} + +void STLGeometry :: BuildSelectedEdge(twoint ep) +{ + if (edgedata->Size() == 0 || + !GetEPPSize()) + { + return; + } + + selectedmultiedge.SetSize(0); + + selectedmultiedge.Append(twoint(ep)); +} + +void STLGeometry :: BuildSelectedCluster(twoint ep) +{ + if (edgedata->Size() == 0 || + !GetEPPSize()) + { + return; + } + + selectedmultiedge.SetSize(0); + + int tenum = GetTopEdgeNum (ep.i1, ep.i2); + + if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED) + { + twoint epnew = GetNearestSelectedDefinedEdge(); + if (epnew.i1) + { + ep = epnew; + tenum = GetTopEdgeNum (ep.i1, ep.i2); + } + } + + selectedmultiedge.Append(twoint(ep)); + + if (edgedata->Get(tenum).GetStatus() == ED_UNDEFINED) + { + return; + } + + edgedata->BuildClusterWithEdge(ep.i1,ep.i2,selectedmultiedge); +} + +void STLGeometry :: ImportEdges() +{ + StoreEdgeData(); + + PrintMessage(5, "import edges from file 'edges.ng'"); + ifstream fin("edges.ng"); + + int ne; + fin >> ne; + + Array > eps; + + int i; + Point<3> p; + for (i = 1; i <= 2*ne; i++) + { + fin >> p(0); + fin >> p(1); + fin >> p(2); + eps.Append(p); + } + AddEdges(eps); +} + +void STLGeometry :: AddEdges(const Array >& eps) +{ + int i; + int ne = eps.Size()/2; + + Array epsi; + Box<3> bb = GetBoundingBox(); + bb.Increase(1); + + Point3dTree ptree (bb.PMin(), + bb.PMax()); + Array pintersect; + + double gtol = GetBoundingBox().Diam()/1.E10; + Point<3> p; + + for (i = 1; i <= GetNP(); i++) + { + p = GetPoint(i); + ptree.Insert (p, i); + } + + int error = 0; + for (i = 1; i <= 2*ne; i++) + { + p = eps.Get(i); + Point3d pmin = p - Vec3d (gtol, gtol, gtol); + Point3d pmax = p + Vec3d (gtol, gtol, gtol); + + ptree.GetIntersecting (pmin, pmax, pintersect); + if (pintersect.Size() > 1) + { + PrintError("Found too much points in epsilon-dist"); + error = 1; + } + else if (pintersect.Size() == 0) + { + error = 1; + PrintError("edgepoint does not exist!"); + PrintMessage(5,"p=",Point3d(eps.Get(i))); + } + else + { + epsi.Append(pintersect.Get(1)); + } + } + + if (error) return; + + int en; + for (i = 1; i <= ne; i++) + { + if (epsi.Get(2*i-1) == epsi.Get(2*i)) {PrintError("Edge with zero length!");} + else + { + en = edgedata->GetEdgeNum(epsi.Get(2*i-1),epsi.Get(2*i)); + edgedata->Elem(en).SetStatus (ED_CONFIRMED); + } + } + +} + + + +void STLGeometry :: ImportExternalEdges(const char * filename) +{ + //AVL edges!!!!!! + + ifstream inf (filename); + char ch; + //int cnt = 0; + int records, units, i, j; + PrintFnStart("Import edges from ",filename); + + const int flen=30; + char filter[flen+1]; + filter[flen] = 0; + char buf[20]; + + Array importpoints; + Array importlines; + Array importpnums; + + while (inf.good()) + { + inf.get(ch); + // (*testout) << cnt << ": " << ch << endl; + + for (i = 0; i < flen; i++) + filter[i] = filter[i+1]; + filter[flen-1] = ch; + // (*testout) << filter << endl; + + if (strcmp (filter+flen-7, "RECORDS") == 0) + { + inf.get(ch); // '=' + inf >> records; + } + if (strcmp (filter+flen-5, "UNITS") == 0) + { + inf.get(ch); // '=' + inf >> units; + } + + if (strcmp (filter+flen-17, "EDGE NODE NUMBERS") == 0) + { + int nodenr; + importlines.SetSize (units); + for (i = 1; i <= units; i++) + { + inf >> nodenr; + importlines.Elem(i) = nodenr; + // (*testout) << nodenr << endl; + } + } + + if (strcmp (filter+flen-23, "EDGE POINT COORD IN DIR") == 0) + { + int coord; + + inf >> coord; + + importpoints.SetSize (units); + + inf >> ch; + inf.putback (ch); + + for (i = 1; i <= units; i++) + { + for (j = 0; j < 12; j++) + inf.get (buf[j]); + buf[12] = 0; + + importpoints.Elem(i).X(coord) = 1000 * atof (buf); + } + } + } + + /* + (*testout) << "lines: " << endl; + for (i = 1; i <= importlines.Size(); i++) + (*testout) << importlines.Get(i) << endl; + (*testout) << "points: " << endl; + for (i = 1; i <= importpoints.Size(); i++) + (*testout) << importpoints.Get(i) << endl; + */ + + + + importpnums.SetSize (importpoints.Size()); + + + Box3d bb (GetBoundingBox().PMin() + Vec3d (-1,-1,-1), + GetBoundingBox().PMax() + Vec3d (1, 1, 1)); + + Point3dTree ptree (bb.PMin(), + bb.PMax()); + + + PrintMessage(7,"stl - bb: ",bb.PMin(), " - ", bb.PMax()); + + Box3d ebb; + ebb.SetPoint (importpoints.Get(1)); + for (i = 1; i <= importpoints.Size(); i++) + ebb.AddPoint (importpoints.Get(i)); + PrintMessage(7,"edgep - bb: ", ebb.PMin(), " - ", ebb.PMax()); + + Array pintersect; + + double gtol = GetBoundingBox().Diam()/1.E6; + + for (i = 1; i <= GetNP(); i++) + { + Point3d p = GetPoint(i); + // (*testout) << "stlpt: " << p << endl; + ptree.Insert (p, i); + } + + + for (i = 1; i <= importpoints.Size(); i++) + { + Point3d p = importpoints.Get(i); + Point3d pmin = p - Vec3d (gtol, gtol, gtol); + Point3d pmax = p + Vec3d (gtol, gtol, gtol); + + ptree.GetIntersecting (pmin, pmax, pintersect); + if (pintersect.Size() > 1) + { + importpnums.Elem(i) = 0; + PrintError("Found too many points in epsilon-dist"); + } + else if (pintersect.Size() == 0) + { + importpnums.Elem(i) = 0; + PrintError("Edgepoint does not exist!"); + } + else + { + importpnums.Elem(i) = pintersect.Get(1); + } + } + + // if (!error) + { + PrintMessage(7,"found all edge points in stl file"); + + + StoreEdgeData(); + + int oldp = 0; + + for (i = 1; i <= importlines.Size(); i++) + { + int newp = importlines.Get(i); + if (!importpnums.Get(abs(newp))) + newp = 0; + + if (oldp && newp) + { + int en = edgedata->GetEdgeNum(importpnums.Get(oldp), + importpnums.Get(abs(newp))); + edgedata->Elem(en).SetStatus (ED_CONFIRMED); + } + + if (newp < 0) + oldp = 0; + else + oldp = newp; + } + } + + +} + + + +void STLGeometry :: ExportEdges() +{ + PrintFnStart("Save edges to file 'edges.ng'"); + + ofstream fout("edges.ng"); + fout.precision(16); + + int n = edgedata->GetNConfEdges(); + + fout << n << endl; + + int i; + for (i = 1; i <= edgedata->Size(); i++) + { + if (edgedata->Get(i).GetStatus() == ED_CONFIRMED) + { + const STLTopEdge & e = edgedata->Get(i); + fout << GetPoint(e.PNum(1))(0) << " " << GetPoint(e.PNum(1))(1) << " " << GetPoint(e.PNum(1))(2) << endl; + fout << GetPoint(e.PNum(2))(0) << " " << GetPoint(e.PNum(2))(1) << " " << GetPoint(e.PNum(2))(2) << endl; + } + } + +} + +void STLGeometry :: LoadEdgeData(const char* file) +{ + StoreEdgeData(); + + PrintFnStart("Load edges from file '", file, "'"); + ifstream fin(file); + + edgedata->Read(fin); + + // calcedgedataanglesnew = 1; +} + +void STLGeometry :: SaveEdgeData(const char* file) +{ + PrintFnStart("save edges to file '", file, "'"); + ofstream fout(file); + + edgedata->Write(fout); +} + + + + + + + +/* +void STLGeometry :: SaveExternalEdges() +{ + ofstream fout("externaledgesp3.ng"); + fout.precision(16); + + int n = NOExternalEdges(); + fout << n << endl; + + int i; + for (i = 1; i <= n; i++) + { + twoint e = GetExternalEdge(i); + fout << GetPoint(e.i1)(0) << " " << GetPoint(e.i1)(1) << " " << GetPoint(e.i1)(2) << endl; + fout << GetPoint(e.i2)(0) << " " << GetPoint(e.i2)(1) << " " << GetPoint(e.i2)(2) << endl; + } + +} +*/ +void STLGeometry :: StoreExternalEdges() +{ + storedexternaledges.SetSize(0); + undoexternaledges = 1; + int i; + for (i = 1; i <= externaledges.Size(); i++) + { + storedexternaledges.Append(externaledges.Get(i)); + } + +} + +void STLGeometry :: UndoExternalEdges() +{ + if (!undoexternaledges) + { + PrintMessage(1, "undo not further possible!"); + return; + } + RestoreExternalEdges(); + undoexternaledges = 0; +} + +void STLGeometry :: RestoreExternalEdges() +{ + externaledges.SetSize(0); + int i; + for (i = 1; i <= storedexternaledges.Size(); i++) + { + externaledges.Append(storedexternaledges.Get(i)); + } + +} + + +void STLGeometry :: AddExternalEdgeAtSelected() +{ + StoreExternalEdges(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } +} + +void STLGeometry :: AddClosedLinesToExternalEdges() +{ + StoreExternalEdges(); + + int i, j; + for (i = 1; i <= GetNLines(); i++) + { + STLLine* l = GetLine(i); + if (l->StartP() == l->EndP()) + { + for (j = 1; j < l->NP(); j++) + { + int ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } + } + } +} + +void STLGeometry :: AddLongLinesToExternalEdges() +{ + StoreExternalEdges(); + + double diamfact = stldoctor.dirtytrigfact; + double diam = GetBoundingBox().Diam(); + + int i, j; + for (i = 1; i <= GetNLines(); i++) + { + STLLine* l = GetLine(i); + if (l->GetLength(points) >= diamfact*diam) + { + for (j = 1; j < l->NP(); j++) + { + int ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } + } + } +} + +void STLGeometry :: AddAllNotSingleLinesToExternalEdges() +{ + StoreExternalEdges(); + + int i, j; + for (i = 1; i <= GetNLines(); i++) + { + STLLine* l = GetLine(i); + if (GetNEPP(l->StartP()) > 1 || GetNEPP(l->EndP()) > 1) + { + for (j = 1; j < l->NP(); j++) + { + int ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + } + } + } +} + +void STLGeometry :: DeleteDirtyExternalEdges() +{ + //delete single triangle edges and single edge-lines in clusters" + StoreExternalEdges(); + + int i, j; + for (i = 1; i <= GetNLines(); i++) + { + STLLine* l = GetLine(i); + if (l->NP() <= 3 || (l->StartP() == l->EndP() && l->NP() == 4)) + { + for (j = 1; j < l->NP(); j++) + { + int ap1 = l->PNum(j); + int ap2 = l->PNum(j+1); + + if (IsExternalEdge(ap1,ap2)) {DeleteExternalEdge(ap1,ap2);} + } + } + } +} + +void STLGeometry :: AddExternalEdgesFromGeomLine() +{ + StoreExternalEdges(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + + if (IsEdge(ap1,ap2)) + { + int edgenum = IsEdgeNum(ap1,ap2); + if (!IsExternalEdge(ap1,ap2)) {AddExternalEdge(ap1,ap2);} + + int noend = 1; + int startp = ap1; + int laste = edgenum; + int np1, np2; + while (noend) + { + if (GetNEPP(startp) == 2) + { + if (GetEdgePP(startp,1) != laste) {laste = GetEdgePP(startp,1);} + else {laste = GetEdgePP(startp,2);} + np1 = GetEdge(laste).PNum(1); + np2 = GetEdge(laste).PNum(2); + + if (!IsExternalEdge(np1, np2)) {AddExternalEdge(np1, np2);} + else {noend = 0;} + if (np1 != startp) {startp = np1;} + else {startp = np2;} + } + else {noend = 0;} + } + + startp = ap2; + laste = edgenum; + noend = 1; + while (noend) + { + if (GetNEPP(startp) == 2) + { + if (GetEdgePP(startp,1) != laste) {laste = GetEdgePP(startp,1);} + else {laste = GetEdgePP(startp,2);} + np1 = GetEdge(laste).PNum(1); + np2 = GetEdge(laste).PNum(2); + + if (!IsExternalEdge(np1, np2)) {AddExternalEdge(np1, np2);} + else {noend = 0;} + if (np1 != startp) {startp = np1;} + else {startp = np2;} + } + else {noend = 0;} + } + + } + + } + +} + +void STLGeometry :: ClearEdges() +{ + edgesfound = 0; + edges.SetSize(0); + //edgedata->SetSize(0); + // externaledges.SetSize(0); + edgesperpoint.SetSize(0); + undoexternaledges = 0; + +} + +void STLGeometry :: STLDoctorBuildEdges() +{ + // if (!trigsconverted) {return;} + ClearEdges(); + + meshlines.SetSize(0); + FindEdgesFromAngles(); +} + +void STLGeometry :: DeleteExternalEdgeAtSelected() +{ + StoreExternalEdges(); + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) + { + int ap1 = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + int ap2 = GetTriangle(GetSelectTrig()).PNumMod(GetNodeOfSelTrig()+1); + if (IsExternalEdge(ap1,ap2)) {DeleteExternalEdge(ap1,ap2);} + } +} + +void STLGeometry :: DeleteExternalEdgeInVicinity() +{ + StoreExternalEdges(); + if (!stldoctor.showvicinity || vicinity.Size() != GetNT()) {return;} + + int i, j, ap1, ap2; + + for (i = 1; i <= GetNT(); i++) + { + if (vicinity.Elem(i)) + { + for (j = 1; j <= 3; j++) + { + ap1 = GetTriangle(i).PNum(j); + ap2 = GetTriangle(i).PNumMod(j+1); + + if (IsExternalEdge(ap1,ap2)) + { + DeleteExternalEdge(ap1,ap2); + } + } + } + } +} + +void STLGeometry :: BuildExternalEdgesFromEdges() +{ + StoreExternalEdges(); + + if (GetNE() == 0) {PrintWarning("Edges possibly not generated!");} + + int i; + externaledges.SetSize(0); + + for (i = 1; i <= GetNE(); i++) + { + STLEdge e = GetEdge(i); + AddExternalEdge(e.PNum(1), e.PNum(2)); + } + +} + + +void STLGeometry :: AddExternalEdge(int ap1, int ap2) +{ + externaledges.Append(twoint(ap1,ap2)); +} + +void STLGeometry :: DeleteExternalEdge(int ap1, int ap2) +{ + + int i; + int found = 0; + for (i = 1; i <= NOExternalEdges(); i++) + { + if ((GetExternalEdge(i).i1 == ap1 && GetExternalEdge(i).i2 == ap2) || + (GetExternalEdge(i).i1 == ap2 && GetExternalEdge(i).i2 == ap1)) {found = 1;}; + if (found && i < NOExternalEdges()) + { + externaledges.Elem(i) = externaledges.Get(i+1); + } + } + if (!found) {PrintWarning("edge not found");} + else + { + externaledges.SetSize(externaledges.Size()-1); + } + +} + +int STLGeometry :: IsExternalEdge(int ap1, int ap2) +{ + int i; + for (i = 1; i <= NOExternalEdges(); i++) + { + if ((GetExternalEdge(i).i1 == ap1 && GetExternalEdge(i).i2 == ap2) || + (GetExternalEdge(i).i1 == ap2 && GetExternalEdge(i).i2 == ap1)) {return 1;}; + } + return 0; +} + +void STLGeometry :: DestroyDirtyTrigs() +{ + + PrintFnStart("Destroy dirty triangles"); + PrintMessage(5,"original number of triangles=", GetNT()); + + //destroy every triangle with other than 3 neighbours; + int changed = 1; + int i, j, k; + while (changed) + { + changed = 0; + Clear(); + + for (i = 1; i <= GetNT(); i++) + { + int dirty = NONeighbourTrigs(i) < 3; + + for (j = 1; j <= 3; j++) + { + int pnum = GetTriangle(i).PNum(j); + /* + if (pnum == 1546) + { + // for (k = 1; k <= NOTrigsPerPoint(pnum); k++) + } + */ + if (NOTrigsPerPoint(pnum) <= 2) + dirty = 1; + } + + int pi1 = GetTriangle(i).PNum(1); + int pi2 = GetTriangle(i).PNum(2); + int pi3 = GetTriangle(i).PNum(3); + if (pi1 == pi2 || pi1 == pi3 || pi2 == pi3) + { + PrintMessage(5,"triangle with Volume 0: ", i, " nodes: ", pi1, ", ", pi2, ", ", pi3); + dirty = 1; + } + + if (dirty) + { + for (k = i+1; k <= GetNT(); k++) + { + trias.Elem(k-1) = trias.Get(k); + // readtrias: not longer permanent, JS + // readtrias.Elem(k-1) = readtrias.Get(k); + } + int size = GetNT(); + trias.SetSize(size-1); + // readtrias.SetSize(size-1); + changed = 1; + break; + } + } + } + + FindNeighbourTrigs(); + PrintMessage(5,"final number of triangles=", GetNT()); +} + +void STLGeometry :: CalcNormalsFromGeometry() +{ + int i; + for (i = 1; i <= GetNT(); i++) + { + const STLTriangle & tr = GetTriangle(i); + const Point3d& ap1 = GetPoint(tr.PNum(1)); + const Point3d& ap2 = GetPoint(tr.PNum(2)); + const Point3d& ap3 = GetPoint(tr.PNum(3)); + + Vec3d normal = Cross (ap2-ap1, ap3-ap1); + + if (normal.Length() != 0) + { + normal /= (normal.Length()); + } + GetTriangle(i).SetNormal(normal); + } + PrintMessage(5,"Normals calculated from geometry!!!"); + + calcedgedataanglesnew = 1; +} + +void STLGeometry :: SetSelectTrig(int trig) +{ + stldoctor.selecttrig = trig; +} + +int STLGeometry :: GetSelectTrig() const +{ + return stldoctor.selecttrig; +} + +void STLGeometry :: SetNodeOfSelTrig(int n) +{ + stldoctor.nodeofseltrig = n; +} + +int STLGeometry :: GetNodeOfSelTrig() const +{ + return stldoctor.nodeofseltrig; +} + +void STLGeometry :: MoveSelectedPointToMiddle() +{ + if (GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) + { + int p = GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()); + Point<3> pm(0.,0.,0.); //Middlevector; + Point<3> p0(0.,0.,0.); + PrintMessage(5,"original point=", Point3d(GetPoint(p))); + + int i; + int cnt = 0; + for (i = 1; i <= trigsperpoint.EntrySize(p); i++) + { + const STLTriangle& tr = GetTriangle(trigsperpoint.Get(p,i)); + int j; + for (j = 1; j <= 3; j++) + { + if (tr.PNum(j) != p) + { + cnt++; + pm(0) += GetPoint(tr.PNum(j))(0); + pm(1) += GetPoint(tr.PNum(j))(1); + pm(2) += GetPoint(tr.PNum(j))(2); + } + } + } + + Point<3> origp = GetPoint(p); + double fact = 0.2; + + SetPoint(p, p0 + fact*(1./(double)cnt)*(pm-p0)+(1.-fact)*(origp-p0)); + + PrintMessage(5,"middle point=", Point3d (GetPoint(p))); + + PrintMessage(5,"moved point ", Point3d (p)); + + } +} + +void STLGeometry :: PrintSelectInfo() +{ + + //int trig = GetSelectTrig(); + //int p = GetTriangle(trig).PNum(GetNodeOfSelTrig()); + + PrintMessage(1,"touch triangle ", GetSelectTrig() + , ", local node ", GetNodeOfSelTrig() + , " (=", GetTriangle(GetSelectTrig()).PNum(GetNodeOfSelTrig()), ")"); + if (AtlasMade() && GetSelectTrig() >= 1 && GetSelectTrig() <= GetNT()) + { + PrintMessage(1," chartnum=",GetChartNr(GetSelectTrig())); + /* + PointBetween(Center(Center(GetPoint(GetTriangle(270).PNum(1)), + GetPoint(GetTriangle(270).PNum(2))), + GetPoint(GetTriangle(270).PNum(3))),270, + Center(Center(GetPoint(GetTriangle(trig).PNum(1)), + GetPoint(GetTriangle(trig).PNum(2))), + GetPoint(GetTriangle(trig).PNum(3))),trig); + */ + //PointBetween(Point3d(5.7818, 7.52768, 4.14879),260,Point3d(6.80292, 6.55392, 4.70184),233); + } +} + +void STLGeometry :: ShowSelectedTrigChartnum() +{ + int st = GetSelectTrig(); + + if (st >= 1 && st <= GetNT() && AtlasMade()) + PrintMessage(1,"selected trig ", st, " has chartnumber ", GetChartNr(st)); +} + +void STLGeometry :: ShowSelectedTrigCoords() +{ + int st = GetSelectTrig(); + + /* + //testing!!!! + Array trigs; + GetSortedTrianglesAroundPoint(GetTriangle(st).PNum(GetNodeOfSelTrig()),st,trigs); + */ + + if (st >= 1 && st <= GetNT()) + { + PrintMessage(1, "coordinates of selected trig ", st, ":"); + PrintMessage(1, " p1 = ", GetTriangle(st).PNum(1), " = ", + Point3d (GetPoint(GetTriangle(st).PNum(1)))); + PrintMessage(1, " p2 = ", GetTriangle(st).PNum(2), " = ", + Point3d (GetPoint(GetTriangle(st).PNum(2)))); + PrintMessage(1, " p3 = ", GetTriangle(st).PNum(3), " = ", + Point3d (GetPoint(GetTriangle(st).PNum(3)))); + } +} + +void STLGeometry :: LoadMarkedTrigs() +{ + PrintFnStart("load marked trigs from file 'markedtrigs.ng'"); + ifstream fin("markedtrigs.ng"); + + int n; + fin >> n; + if (n != GetNT() || n == 0) {PrintError("Not a suitable marked-trig-file!"); return;} + + int i, m; + for (i = 1; i <= n; i++) + { + fin >> m; + SetMarkedTrig(i, m); + } + + fin >> n; + if (n != 0) + { + + Point<3> ap1, ap2; + for (i = 1; i <= n; i++) + { + fin >> ap1(0); fin >> ap1(1); fin >> ap1(2); + fin >> ap2(0); fin >> ap2(1); fin >> ap2(2); + AddMarkedSeg(ap1,ap2); + } + } +} + +void STLGeometry :: SaveMarkedTrigs() +{ + PrintFnStart("save marked trigs to file 'markedtrigs.ng'"); + ofstream fout("markedtrigs.ng"); + + int n = GetNT(); + fout << n << endl; + + int i; + for (i = 1; i <= n; i++) + { + fout << IsMarkedTrig(i) << "\n"; + } + + n = GetNMarkedSegs(); + fout << n << endl; + + Point<3> ap1,ap2; + for (i = 1; i <= n; i++) + { + GetMarkedSeg(i,ap1,ap2); + fout << ap1(0) << " " << ap1(1) << " " << ap1(2) << " "; + fout << ap2(0) << " " << ap2(1) << " " << ap2(2) << " " << "\n"; + } + +} + +void STLGeometry :: NeighbourAnglesOfSelectedTrig() +{ + int st = GetSelectTrig(); + + if (st >= 1 && st <= GetNT()) + { + int i; + PrintMessage(1,"Angle to triangle ", st, ":"); + for (i = 1; i <= NONeighbourTrigs(st); i++) + { + PrintMessage(1," triangle ", NeighbourTrig(st,i), ": angle = ", + 180./M_PI*GetAngle(st, NeighbourTrig(st,i)), "°", + ", calculated = ", 180./M_PI*Angle(GetTriangle(st).GeomNormal(points), + GetTriangle(NeighbourTrig(st,i)).GeomNormal(points)), "°"); + } + } +} + +void STLGeometry :: GetVicinity(int starttrig, int size, Array& vic) +{ + if (starttrig == 0 || starttrig > GetNT()) {return;} + + Array vicarray; + vicarray.SetSize(GetNT()); + + int i; + for (i = 1; i <= vicarray.Size(); i++) + { + vicarray.Elem(i) = 0; + } + + vicarray.Elem(starttrig) = 1; + + int j = 0,k; + + Array list1; + list1.SetSize(0); + Array list2; + list2.SetSize(0); + list1.Append(starttrig); + + while (j < size) + { + j++; + for (i = 1; i <= list1.Size(); i++) + { + for (k = 1; k <= NONeighbourTrigs(i); k++) + { + int nbtrig = NeighbourTrig(list1.Get(i),k); + if (nbtrig && vicarray.Get(nbtrig) == 0) + { + list2.Append(nbtrig); + vicarray.Elem(nbtrig) = 1; + } + } + } + list1.SetSize(0); + for (i = 1; i <= list2.Size(); i++) + { + list1.Append(list2.Get(i)); + } + list2.SetSize(0); + } + + vic.SetSize(0); + for (i = 1; i <= vicarray.Size(); i++) + { + if (vicarray.Get(i)) {vic.Append(i);} + } +} + +void STLGeometry :: CalcVicinity(int starttrig) +{ + if (starttrig == 0 || starttrig > GetNT()) {return;} + + vicinity.SetSize(GetNT()); + + if (!stldoctor.showvicinity) {return;} + + int i; + for (i = 1; i <= vicinity.Size(); i++) + { + vicinity.Elem(i) = 0; + } + + vicinity.Elem(starttrig) = 1; + + int j = 0,k; + + Array list1; + list1.SetSize(0); + Array list2; + list2.SetSize(0); + list1.Append(starttrig); + + // int cnt = 1; + while (j < stldoctor.vicinity) + { + j++; + for (i = 1; i <= list1.Size(); i++) + { + for (k = 1; k <= NONeighbourTrigs(i); k++) + { + int nbtrig = NeighbourTrig(list1.Get(i),k); + if (nbtrig && vicinity.Get(nbtrig) == 0) + { + list2.Append(nbtrig); + vicinity.Elem(nbtrig) = 1; + //cnt++; + } + } + } + list1.SetSize(0); + for (i = 1; i <= list2.Size(); i++) + { + list1.Append(list2.Get(i)); + } + list2.SetSize(0); + } + +} + +int STLGeometry :: Vicinity(int trig) const +{ + if (trig <= vicinity.Size() && trig >=1) + { + return vicinity.Get(trig); + } + else {PrintSysError("In STLGeometry::Vicinity");} + return 0; +} + +void STLGeometry :: InitMarkedTrigs() +{ + markedtrigs.SetSize(GetNT()); + int i; + for (i = 1; i <= GetNT(); i++) + { + SetMarkedTrig(i, 0); + } +} + +void STLGeometry :: MarkDirtyTrigs() +{ + PrintFnStart("mark dirty trigs"); + int i,j; + + markedtrigs.SetSize(GetNT()); + + for (i = 1; i <= GetNT(); i++) + { + SetMarkedTrig(i, 0); + } + + int found; + double dirtyangle = stlparam.yangle/2./180.*M_PI; + int cnt = 0; + for (i = 1; i <= GetNT(); i++) + { + found = 0; + for (j = 1; j <= NONeighbourTrigs(i); j++) + { + if (GetAngle(i, NeighbourTrig(i,j)) > dirtyangle) + { + found++; + } + } + if (found && GetTriangle(i).MinHeight(points) < + stldoctor.dirtytrigfact*GetTriangle(i).MaxLength(points)) + { + SetMarkedTrig(i, 1); cnt++; + } + /* + else if (found == 3) + { + SetMarkedTrig(i, 1); cnt++; + } + */ + } + + PrintMessage(1, "marked ", cnt, " dirty trigs"); +} + + +void STLGeometry :: MarkTopErrorTrigs() +{ + int cnt = 0; + markedtrigs.SetSize(GetNT()); + for (int i = 1; i <= GetNT(); i++) + { + const STLTriangle & trig = GetTriangle(i); + + SetMarkedTrig(i, trig.flags.toperror); + if (trig.flags.toperror) cnt++; + } + PrintMessage(1,"marked ", cnt, " inconsistent triangles"); +} + + + +double STLGeometry :: CalcTrigBadness(int i) +{ + int j; + double maxbadness = 0; + int ap1, ap2; + for (j = 1; j <= NONeighbourTrigs(i); j++) + { + GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), ap1, ap2); + + if (!IsEdge(ap1,ap2) && GetGeomAngle(i, NeighbourTrig(i,j)) > maxbadness) + { + maxbadness = GetGeomAngle(i, NeighbourTrig(i,j)); + } + } + return maxbadness; + +} + +void STLGeometry :: GeomSmoothRevertedTrigs() +{ + //double revertedangle = stldoctor.smoothangle/180.*M_PI; + double fact = stldoctor.dirtytrigfact; + + MarkRevertedTrigs(); + + int i, j, k, l, p; + + for (i = 1; i <= GetNT(); i++) + { + if (IsMarkedTrig(i)) + { + for (j = 1; j <= 3; j++) + { + double origbadness = CalcTrigBadness(i); + + p = GetTriangle(i).PNum(j); + Point<3> pm(0.,0.,0.); //Middlevector; + Point<3> p0(0.,0.,0.); + + int cnt = 0; + + for (k = 1; k <= trigsperpoint.EntrySize(p); k++) + { + const STLTriangle& tr = GetTriangle(trigsperpoint.Get(p,k)); + for (l = 1; l <= 3; l++) + { + if (tr.PNum(l) != p) + { + cnt++; + pm(0) += GetPoint(tr.PNum(l))(0); + pm(1) += GetPoint(tr.PNum(l))(1); + pm(2) += GetPoint(tr.PNum(l))(2); + } + } + } + Point3d origp = GetPoint(p); + Point3d newp = p0 + fact*(1./(double)cnt)*(pm-p0)+(1.-fact)*(origp-p0); + + SetPoint(p, newp); + + if (CalcTrigBadness(i) > 0.9*origbadness) {SetPoint(p,origp); PrintDot('f');} + else {PrintDot('s');} + } + } + } + MarkRevertedTrigs(); +} + +void STLGeometry :: MarkRevertedTrigs() +{ + int i,j; + if (edgesperpoint.Size() != GetNP()) {BuildEdges();} + + PrintFnStart("mark reverted trigs"); + + InitMarkedTrigs(); + + int found; + double revertedangle = stldoctor.smoothangle/180.*M_PI; + + int cnt = 0; + int ap1, ap2; + for (i = 1; i <= GetNT(); i++) + { + found = 0; + for (j = 1; j <= NONeighbourTrigs(i); j++) + { + GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)), ap1, ap2); + + if (!IsEdge(ap1,ap2)) + { + if (GetGeomAngle(i, NeighbourTrig(i,j)) > revertedangle) + { + found = 1; + break; + } + } + } + + if (found) + { + SetMarkedTrig(i, 1); cnt++; + } + + } + + PrintMessage(5, "found ", cnt, " reverted trigs"); + + +} + +void STLGeometry :: SmoothDirtyTrigs() +{ + PrintFnStart("smooth dirty trigs"); + + MarkDirtyTrigs(); + + int i,j; + int changed = 1; + int ap1, ap2; + + while (changed) + { + changed = 0; + for (i = 1; i <= GetNT(); i++) + { + if (IsMarkedTrig(i)) + { + int foundtrig = 0; + double maxlen = 0; + // JS: darf normalvector nicht ueber kurze Seite erben + maxlen = GetTriangle(i).MaxLength(GetPoints()) / 2.1; //JG: bei flachem dreieck auch kurze Seite + + for (j = 1; j <= NONeighbourTrigs(i); j++) + { + if (!IsMarkedTrig(NeighbourTrig(i,j))) + { + GetTriangle(i).GetNeighbourPoints(GetTriangle(NeighbourTrig(i,j)),ap1,ap2); + if (Dist(GetPoint(ap1),GetPoint(ap2)) >= maxlen) + { + foundtrig = NeighbourTrig(i,j); + maxlen = Dist(GetPoint(ap1),GetPoint(ap2)); + } + } + } + if (foundtrig) + { + GetTriangle(i).SetNormal(GetTriangle(foundtrig).Normal()); + changed = 1; + SetMarkedTrig(i,0); + } + } + } + } + + calcedgedataanglesnew = 1; + + + MarkDirtyTrigs(); + + int cnt = 0; + for (i = 1; i <= GetNT(); i++) + { + if (IsMarkedTrig(i)) {cnt++;} + } + + PrintMessage(5,"NO marked dirty trigs=", cnt); + +} + +int STLGeometry :: IsMarkedTrig(int trig) const +{ + if (trig <= markedtrigs.Size() && trig >=1) + { + return markedtrigs.Get(trig); + } + else {PrintSysError("In STLGeometry::IsMarkedTrig");} + + return 0; +} + +void STLGeometry :: SetMarkedTrig(int trig, int num) +{ + if (trig <= markedtrigs.Size() && trig >=1) + { + markedtrigs.Elem(trig) = num; + } + else {PrintSysError("In STLGeometry::SetMarkedTrig");} +} + +void STLGeometry :: Clear() +{ + PrintFnStart("Clear"); + + surfacemeshed = 0; + surfaceoptimized = 0; + volumemeshed = 0; + + selectedmultiedge.SetSize(0); + meshlines.SetSize(0); + // neighbourtrigs.SetSize(0); + outerchartspertrig.SetSize(0); + atlas.SetSize(0); + ClearMarkedSegs(); + ClearSpiralPoints(); + ClearLineEndPoints(); + + SetSelectTrig(0); + SetNodeOfSelTrig(1); + facecnt = 0; + + SetThreadPercent(100.); + + ClearEdges(); +} + +double STLGeometry :: Area() +{ + if (area >= 0) return area; + area = 0; + for (int i = 1; i <= GetNT(); i++) + area += GetTriangle(i).Area(points); + return area; +} + +double STLGeometry :: GetAngle(int t1, int t2) +{ + return Angle(GetTriangle(t1).Normal(),GetTriangle(t2).Normal()); +} + +double STLGeometry :: GetGeomAngle(int t1, int t2) +{ + Vec3d n1 = GetTriangle(t1).GeomNormal(points); + Vec3d n2 = GetTriangle(t2).GeomNormal(points); + return Angle(n1,n2); +} + + +void STLGeometry :: InitSTLGeometry(const Array & readtrias) +{ + PrintFnStart("Init STL Geometry"); + STLTopology::InitSTLGeometry(readtrias); + + int i, k; + + //const double geometry_tol_fact = 1E8; //distances lower than max_box_size/tol are ignored + + int np = GetNP(); + PrintMessage(5,"NO points= ", GetNP()); + normals.SetSize(GetNP()); + Array normal_cnt(GetNP()); // counts number of added normals in a point + + for (i = 1; i <= np; i++) + { + normal_cnt.Elem(i) = 0; + normals.Elem(i) = Vec3d (0,0,0); + } + + for(i = 1; i <= GetNT(); i++) + { + // STLReadTriangle t = GetReadTriangle(i); + // STLTriangle st; + + Vec<3> n = GetTriangle(i).Normal (); + + for (k = 1; k <= 3; k++) + { + int pi = GetTriangle(i).PNum(k); + + normal_cnt.Elem(pi)++; + SetNormal(pi, GetNormal(pi) + n); + } + } + + //normalize the normals + for (i = 1; i <= GetNP(); i++) + { + SetNormal(i,1./(double)normal_cnt.Get(i)*GetNormal(i)); + } + + trigsconverted = 1; + + vicinity.SetSize(GetNT()); + markedtrigs.SetSize(GetNT()); + for (i = 1; i <= GetNT(); i++) + { + markedtrigs.Elem(i) = 0; + vicinity.Elem(i) = 1; + } + + ha_points.SetSize(GetNP()); + for (i = 1; i <= GetNP(); i++) + ha_points.Elem(i) = 0; + + calcedgedataanglesnew = 0; + edgedatastored = 0; + edgedata->Clear(); + + + if (GetStatus() == STL_ERROR) return; + + CalcEdgeData(); + CalcEdgeDataAngles(); + + ClearLineEndPoints(); + + CheckGeometryOverlapping(); +} + +void STLGeometry :: TopologyChanged() +{ + calcedgedataanglesnew = 1; +} + +int STLGeometry :: CheckGeometryOverlapping() +{ + PrintMessageCR(3,"Check overlapping geometry ..."); + + Box<3> geombox = GetBoundingBox(); + Point<3> pmin = geombox.PMin(); + Point<3> pmax = geombox.PMax(); + + Box3dTree setree(pmin, pmax); + + int oltrigs = 0; + markedtrigs.SetSize(GetNT()); + + for (int i = 1; i <= GetNT(); i++) + SetMarkedTrig(i, 0); + + for (int i = 1; i <= GetNT(); i++) + { + const STLTriangle & tri = GetTriangle(i); + + Point<3> tpmin = tri.box.PMin(); + Point<3> tpmax = tri.box.PMax(); + Vec<3> diag = tpmax - tpmin; + + tpmax = tpmax + 0.001 * diag; + tpmin = tpmin - 0.001 * diag; + + setree.Insert (tpmin, tpmax, i); + } + + +#pragma omp parallel + { + Array inters; + +#pragma omp for + for (int i = 1; i <= GetNT(); i++) + { + const STLTriangle & tri = GetTriangle(i); + + Point<3> tpmin = tri.box.PMin(); + Point<3> tpmax = tri.box.PMax(); + + setree.GetIntersecting (tpmin, tpmax, inters); + + for (int j = 1; j <= inters.Size(); j++) + { + const STLTriangle & tri2 = GetTriangle(inters.Get(j)); + + const Point<3> *trip1[3], *trip2[3]; + Point<3> hptri1[3], hptri2[3]; + /* + for (k = 1; k <= 3; k++) + { + trip1[k-1] = &GetPoint (tri.PNum(k)); + trip2[k-1] = &GetPoint (tri2.PNum(k)); + } + */ + + for (int k = 0; k < 3; k++) + { + hptri1[k] = GetPoint (tri[k]); + hptri2[k] = GetPoint (tri2[k]); + trip1[k] = &hptri1[k]; + trip2[k] = &hptri2[k]; + } + + if (IntersectTriangleTriangle (&trip1[0], &trip2[0])) + { +#pragma omp critical + { + oltrigs++; + PrintMessage(5,"Intersecting Triangles: trig ",i," with ",inters.Get(j),"!"); + SetMarkedTrig(i, 1); + SetMarkedTrig(inters.Get(j), 1); + } + } + } + } + } + PrintMessage(3,"Check overlapping geometry ... ", oltrigs, " triangles overlap"); + return oltrigs; +} + +/* +void STLGeometry :: InitSTLGeometry() +{ + STLTopology::InitSTLGeometry(); + + int i, j, k; + + const double geometry_tol_fact = 1E8; //distances lower than max_box_size/tol are ignored + + + trias.SetSize(0); + points.SetSize(0); + normals.SetSize(0); + + Array normal_cnt; // counts number of added normals in a point + + Box3d bb (GetBoundingBox().PMin() + Vec3d (-1,-1,-1), + GetBoundingBox().PMax() + Vec3d (1, 1, 1)); + + Point3dTree pointtree (bb.PMin(), + bb.PMax()); + Array pintersect; + + double gtol = GetBoundingBox().CalcDiam()/geometry_tol_fact; + + for(i = 1; i <= GetReadNT(); i++) + { + //if (i%500==499) {(*mycout) << (double)i/(double)GetReadNT()*100. << "%" << endl;} + + STLReadTriangle t = GetReadTriangle(i); + STLTriangle st; + Vec3d n = t.normal; + + for (k = 0; k < 3; k++) + { + Point3d p = t.pts[k]; + + Point3d pmin = p - Vec3d (gtol, gtol, gtol); + Point3d pmax = p + Vec3d (gtol, gtol, gtol); + + pointtree.GetIntersecting (pmin, pmax, pintersect); + + if (pintersect.Size() > 1) + (*mycout) << "found too much " << char(7) << endl; + int foundpos = 0; + if (pintersect.Size()) + foundpos = pintersect.Get(1); + + if (foundpos) + { + normal_cnt[foundpos]++; + SetNormal(foundpos,GetNormal(foundpos)+n); + // (*testout) << "found p " << p << endl; + } + else + { + foundpos = AddPoint(p); + AddNormal(n); + normal_cnt.Append(1); + + pointtree.Insert (p, foundpos); + } + //(*mycout) << "foundpos=" << foundpos << endl; + st.pts[k] = foundpos; + } + + if ( (st.pts[0] == st.pts[1]) || + (st.pts[0] == st.pts[2]) || + (st.pts[1] == st.pts[2]) ) + { + (*mycout) << "ERROR: STL Triangle degenerated" << endl; + } + else + { + // do not add ? js + AddTriangle(st); + } + //(*mycout) << "TRIG" << i << " = " << st << endl; + + } + //normal the normals + for (i = 1; i <= GetNP(); i++) + { + SetNormal(i,1./(double)normal_cnt[i]*GetNormal(i)); + } + + trigsconverted = 1; + + vicinity.SetSize(GetNT()); + markedtrigs.SetSize(GetNT()); + for (i = 1; i <= GetNT(); i++) + { + markedtrigs.Elem(i) = 0; + vicinity.Elem(i) = 1; + } + + ha_points.SetSize(GetNP()); + for (i = 1; i <= GetNP(); i++) + ha_points.Elem(i) = 0; + + calcedgedataanglesnew = 0; + edgedatastored = 0; + edgedata->Clear(); + + CalcEdgeData(); + CalcEdgeDataAngles(); + + ClearLineEndPoints(); + + (*mycout) << "done" << endl; +} +*/ + + + +void STLGeometry :: SetLineEndPoint(int pn) +{ + if (pn <1 || pn > lineendpoints.Size()) {PrintSysError("Illegal pnum in SetLineEndPoint!!!"); return; } + lineendpoints.Elem(pn) = 1; +} + +int STLGeometry :: IsLineEndPoint(int pn) +{ + // return 0; + if (pn <1 || pn > lineendpoints.Size()) + {PrintSysError("Illegal pnum in IsLineEndPoint!!!"); return 0;} + return lineendpoints.Get(pn); +} + +void STLGeometry :: ClearLineEndPoints() +{ + lineendpoints.SetSize(GetNP()); + int i; + for (i = 1; i <= GetNP(); i++) + { + lineendpoints.Elem(i) = 0; + } +} + +int STLGeometry :: IsEdge(int ap1, int ap2) +{ + int i,j; + for (i = 1; i <= GetNEPP(ap1); i++) + { + for (j = 1; j <= GetNEPP(ap2); j++) + { + if (GetEdgePP(ap1,i) == GetEdgePP(ap2,j)) {return 1;} + } + } + return 0; +} + +int STLGeometry :: IsEdgeNum(int ap1, int ap2) +{ + int i,j; + for (i = 1; i <= GetNEPP(ap1); i++) + { + for (j = 1; j <= GetNEPP(ap2); j++) + { + if (GetEdgePP(ap1,i) == GetEdgePP(ap2,j)) {return GetEdgePP(ap1,i);} + } + } + return 0; +} + + +void STLGeometry :: BuildEdges() +{ + //PrintFnStart("build edges"); + edges.SetSize(0); + meshlines.SetSize(0); + FindEdgesFromAngles(); +} + +void STLGeometry :: UseExternalEdges() +{ + for (int i = 1; i <= NOExternalEdges(); i++) + AddEdge(GetExternalEdge(i).i1,GetExternalEdge(i).i2); + //BuildEdgesPerPointy(); +} + +void STLGeometry :: UndoEdgeChange() +{ + if (edgedatastored) + { + RestoreEdgeData(); + } + else + { + PrintWarning("no edge undo possible"); + } +} + + +void STLGeometry :: StoreEdgeData() +{ + // edgedata_store = *edgedata; + + edgedata->Store(); + edgedatastored = 1; + + // put stlgeom-edgedata to stltopology edgedata + /* + int i; + for (i = 1; i <= GetNTE(); i++) + { + const STLTopEdge & topedge = GetTopEdge (i); + int ednum = edgedata->GetEdgeNum (topedge.PNum(1), + topedge.PNum(2)); + topedges.Elem(i).SetStatus (edgedata->Get (ednum).status); + } + */ +} + +void STLGeometry :: RestoreEdgeData() +{ + // *edgedata = edgedata_store; + edgedata->Restore(); + edgedatastored=0; +} + + +void STLGeometry :: CalcEdgeData() +{ + PushStatus("Calc Edge Data"); + + int np1, np2; + + int ecnt = 0; + edgedata->SetSize(GetNT()/2*3); + + for (int i = 1; i <= GetNT(); i++) + { + SetThreadPercent((double)i/(double)GetNT()*100.); + + const STLTriangle & t1 = GetTriangle(i); + + for (int j = 1; j <= NONeighbourTrigs(i); j++) + { + int nbti = NeighbourTrig(i,j); + if (nbti > i) + { + const STLTriangle & t2 = GetTriangle(nbti); + + if (t1.IsNeighbourFrom(t2)) + { + ecnt++; if (ecnt > edgedata->Size()) {PrintError("In Calc edge data, illegal geometry");} + + t1.GetNeighbourPoints(t2,np1,np2); + + /* ang = GetAngle(i,nbti); + if (ang < -M_PI) {ang += 2*M_PI;}*/ + + + // edgedata->Add(STLEdgeData(0, np1, np2, i, nbti),ecnt); + edgedata->Elem(ecnt).SetStatus(ED_UNDEFINED); + + // edgedata->Elem(ecnt).top = this; + // edgedata->Elem(ecnt).topedgenr = GetTopEdgeNum (np1, np2); + } + } + } + } + + //BuildEdgesPerPoint(); + PopStatus(); +} + +void STLGeometry :: CalcEdgeDataAngles() +{ + PrintMessageCR (5,"calc edge data angles ... "); + + for (int i = 1; i <= GetNTE(); i++) + { + STLTopEdge & edge = GetTopEdge (i); + double cosang = + GetTriangle(edge.TrigNum(1)).Normal() * + GetTriangle(edge.TrigNum(2)).Normal(); + edge.SetCosAngle (cosang); + } + + for (int i = 1; i <= edgedata->Size(); i++) + { + /* + const STLEdgeData& e = edgedata->Get(i); + ang = GetAngle(e.lt,e.rt); + if (ang < -M_PI) {ang += 2*M_PI;} + edgedata->Elem(i).angle = fabs(ang); + */ + } + PrintMessage (5,"calc edge data angles ... done"); +} + +void STLGeometry :: FindEdgesFromAngles() +{ + // PrintFnStart("find edges from angles"); + + double min_edge_angle = stlparam.yangle/180.*M_PI; + double cont_min_edge_angle = stlparam.contyangle/180.*M_PI; + + double cos_min_edge_angle = cos (min_edge_angle); + double cos_cont_min_edge_angle = cos (cont_min_edge_angle); + + if (calcedgedataanglesnew) {CalcEdgeDataAngles(); calcedgedataanglesnew = 0;} + + for (int i = 1; i <= edgedata->Size(); i++) + { + STLTopEdge & sed = edgedata->Elem(i); + if (sed.GetStatus() == ED_CANDIDATE || + sed.GetStatus() == ED_UNDEFINED) + { + if (sed.CosAngle() <= cos_min_edge_angle) + { + sed.SetStatus (ED_CANDIDATE); + } + else + { + sed.SetStatus(ED_UNDEFINED); + } + } + } + + if (stlparam.contyangle < stlparam.yangle) + { + int changed = 1; + int its = 0; + while (changed && stlparam.contyangle < stlparam.yangle) + { + its++; + //(*mycout) << "." << flush; + changed = 0; + for (int i = 1; i <= edgedata->Size(); i++) + { + STLTopEdge & sed = edgedata->Elem(i); + if (sed.CosAngle() <= cos_cont_min_edge_angle + && sed.GetStatus() == ED_UNDEFINED && + (edgedata->GetNConfCandEPP(sed.PNum(1)) == 1 || + edgedata->GetNConfCandEPP(sed.PNum(2)) == 1)) + { + changed = 1; + sed.SetStatus (ED_CANDIDATE); + } + } + } + } + + int confcand = 0; + if (edgedata->GetNConfEdges() == 0) + { + confcand = 1; + } + + for (int i = 1; i <= edgedata->Size(); i++) + { + STLTopEdge & sed = edgedata->Elem(i); + if (sed.GetStatus() == ED_CONFIRMED || + (sed.GetStatus() == ED_CANDIDATE && confcand)) + { + STLEdge se(sed.PNum(1),sed.PNum(2)); + se.SetLeftTrig(sed.TrigNum(1)); + se.SetRightTrig(sed.TrigNum(2)); + AddEdge(se); + } + } + BuildEdgesPerPoint(); + + + + //(*mycout) << "its for continued angle = " << its << endl; + PrintMessage(5,"built ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); + +} + +/* +void STLGeometry :: FindEdgesFromAngles() +{ + double yangle = stlparam.yangle; + char * savetask = multithread.task; + multithread.task = "find edges"; + + const double min_edge_angle = yangle/180.*M_PI; + + int np1, np2; + double ang; + int i; + + //(*mycout) << "area=" << Area() << endl; + + for (i = 1; i <= GetNT(); i++) + { + multithread.percent = (double)i/(double)GetReadNT()*100.; + + const STLTriangle & t1 = GetTriangle(i); + //NeighbourTrigs(nt,i); + + for (int j = 1; j <= NONeighbourTrigs(i); j++) + { + int nbti = NeighbourTrig(i,j); + if (nbti > i) + { + const STLTriangle & t2 = GetTriangle(nbti); + + if (t1.IsNeighbourFrom(t2)) + { + ang = GetAngle(i,nbti); + if (ang < -M_PI*0.5) {ang += 2*M_PI;} + + t1.GetNeighbourPoints(t2,np1,np2); + + if (fabs(ang) >= min_edge_angle) + { + STLEdge se(np1,np2); + se.SetLeftTrig(i); + se.SetRightTrig(nbti); + AddEdge(se); + } + } + } + } + } + + (*mycout) << "added " << GetNE() << " edges" << endl; + + //BuildEdgesPerPoint(); + + multithread.percent = 100.; + multithread.task = savetask; + +} +*/ +void STLGeometry :: BuildEdgesPerPoint() +{ + //cout << "*** build edges per point" << endl; + edgesperpoint.SetSize(GetNP()); + + //add edges to points + for (int i = 1; i <= GetNE(); i++) + { + //(*mycout) << "EDGE " << GetEdge(i).PNum(1) << " - " << GetEdge(i).PNum(2) << endl; + for (int j = 1; j <= 2; j++) + { + AddEdgePP(GetEdge(i).PNum(j),i); + } + } +} + +void STLGeometry :: AddFaceEdges() +{ + PrintFnStart("Add starting edges for faces"); + + //für Kugel eine STLLine hinzufügen (Vorteil: verfeinerbar, unabhängig von Auflösung der Geometrie!!!): + //Grenze von 1. gefundener chart + + Array edgecnt; + Array chartindex; + edgecnt.SetSize(GetNOFaces()); + chartindex.SetSize(GetNOFaces()); + + for (int i = 1; i <= GetNOFaces(); i++) + { + edgecnt.Elem(i) = 0; + chartindex.Elem(i) = 0; + } + + for (int i = 1; i <= GetNT(); i++) + { + int fn = GetTriangle(i).GetFaceNum(); + if (!chartindex.Get(fn)) {chartindex.Elem(fn) = GetChartNr(i);} + for (int j = 1; j <= 3; j++) + { + edgecnt.Elem(fn) += GetNEPP(GetTriangle(i).PNum(j)); + } + } + + for (int i = 1; i <= GetNOFaces(); i++) + { + if (!edgecnt.Get(i)) {PrintMessage(5,"Face", i, " has no edge!");} + } + + int changed = 0; + int ap1, ap2; + for (int i = 1; i <= GetNOFaces(); i++) + { + if (!edgecnt.Get(i)) + { + const STLChart& c = GetChart(chartindex.Get(i)); + // bool foundone = false; + int longest_ap1, longest_ap2 = -1; + double maxlen = -1; + for (int j = 1; j <= c.GetNChartT(); j++) + { + const STLTriangle& t1 = GetTriangle(c.GetChartTrig(j)); + for (int k = 1; k <= 3; k++) + { + int nt = NeighbourTrig(c.GetChartTrig(j),k); + if (GetChartNr(nt) != chartindex.Get(i)) + { + t1.GetNeighbourPoints(GetTriangle(nt),ap1,ap2); + // AddEdge(ap1,ap2); + double len = Dist(GetPoint(ap1), GetPoint(ap2)); + if (len > maxlen) + { + maxlen = len; + longest_ap1 = ap1; + longest_ap2 = ap2; + } + changed = 1; + } + } + } + if (maxlen > 0) + AddEdge(longest_ap1,longest_ap2); + } + + } + + if (changed) BuildEdgesPerPoint(); + +} + +void STLGeometry :: LinkEdges() +{ + PushStatusF("Link Edges"); + PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); + + int i; + + lines.SetSize(0); + int starte(0); + int edgecnt = 0; + int found; + int rev(0); //indicates, that edge is inserted reverse + + //worked edges + Array we(GetNE()); + + //setlineendpoints; wenn 180°, dann keine endpunkte + //nur punkte mit 2 edges kommen in frage, da bei mehr oder weniger punkten ohnehin ein meshpoint hinkommt + + Vec3d v1,v2; + double cos_eca = cos(stlparam.edgecornerangle/180.*M_PI); + int ecnt = 0; + int lp1, lp2; + if (stlparam.edgecornerangle < 180) + { + for (i = 1; i <= GetNP(); i++) + { + if (GetNEPP(i) == 2) + { + if (GetEdge(GetEdgePP(i,1)).PNum(2) == GetEdge(GetEdgePP(i,2)).PNum(1) || + GetEdge(GetEdgePP(i,1)).PNum(1) == GetEdge(GetEdgePP(i,2)).PNum(2)) + { + lp1 = 1; lp2 = 2; + } + else + { + lp1 = 2; lp2 = 1; + } + + v1 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,1)).PNum(1)), + GetPoint(GetEdge(GetEdgePP(i,1)).PNum(2))); + v2 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp1)), + GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp2))); + if ((v1*v2)/sqrt(v1.Length2()*v2.Length2()) < cos_eca) + { + //(*testout) << "add edgepoint " << i << endl; + SetLineEndPoint(i); + ecnt++; + } + } + } + } + PrintMessage(5, "added ", ecnt, " mesh_points due to edge corner angle (", + stlparam.edgecornerangle, " degree)"); + + for (i = 1; i <= GetNE(); i++) {we.Elem(i) = 0;} + + while(edgecnt < GetNE()) + { + SetThreadPercent((double)edgecnt/(double)GetNE()*100.); + + STLLine* line = new STLLine(this); + + //find start edge + int j = 1; + found = 0; + //try second time, if only rings are left!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + int second = 0; + + //find a starting edge at point with 1 or more than 2 edges or at lineendpoint + while (!found && j<=GetNE()) + { + if (!we.Get(j)) + { + if (GetNEPP(GetEdge(j).PNum(1)) != 2 || IsLineEndPoint(GetEdge(j).PNum(1))) + { + starte = j; + found = 1; + rev = 0; + } + else + if (GetNEPP(GetEdge(j).PNum(2)) != 2 || IsLineEndPoint(GetEdge(j).PNum(2))) + { + starte = j; + found = 1; + rev = 1; + } + else if (second) + { + starte = j; + found = 1; + rev = 0; //0 or 1 are possible + } + } + j++; + if (!second && j == GetNE()) {second = 1; j = 1;} + } + + if (!found) {PrintSysError("No starting edge found, edgecnt=", edgecnt, ", GETNE=", GetNE());} + + line->AddPoint(GetEdge(starte).PNum(1+rev)); + line->AddPoint(GetEdge(starte).PNum(2-rev)); + if (!rev) + { + line->AddLeftTrig(GetEdge(starte).LeftTrig()); + line->AddRightTrig(GetEdge(starte).RightTrig()); + } + else + { + line->AddLeftTrig(GetEdge(starte).RightTrig()); + line->AddRightTrig(GetEdge(starte).LeftTrig()); + } + edgecnt++; we.Elem(starte) = 1; + + //add segments to line as long as segments other than starting edge are found or lineendpoint is reached + found = 1; + int other; + while(found) + { + found = 0; + int fp = GetEdge(starte).PNum(2-rev); + if (GetNEPP(fp) == 2 && !IsLineEndPoint(fp)) + { + //find the "other" edge of point fp + other = 0; + if (GetEdgePP(fp,1) == starte) {other = 1;} + + starte = GetEdgePP(fp,1+other); + + //falls ring -> aufhoeren !!!!!!!!!!! + if (!we.Elem(starte)) + { + found = 1; + rev = 0; + if (GetEdge(starte).PNum(2) == fp) {rev = 1;} + else if (GetEdge(starte).PNum(1) != fp) {PrintSysError("In Link Edges!");} + + line->AddPoint(GetEdge(starte).PNum(2-rev)); + if (!rev) + { + line->AddLeftTrig(GetEdge(starte).LeftTrig()); + line->AddRightTrig(GetEdge(starte).RightTrig()); + } + else + { + line->AddLeftTrig(GetEdge(starte).RightTrig()); + line->AddRightTrig(GetEdge(starte).LeftTrig()); + } + edgecnt++; we.Elem(starte) = 1; + } + } + } + AddLine(line); + } + PrintMessage(5,"number of lines generated = ", GetNLines()); + + //check, which lines must have at least one midpoint + INDEX_2_HASHTABLE lineht(GetNLines()+1); + + for (i = 1; i <= GetNLines(); i++) + { + if (GetLine(i)->StartP() == GetLine(i)->EndP()) + { + GetLine(i)->DoSplit(); + } + } + + for (i = 1; i <= GetNLines(); i++) + { + INDEX_2 lineep (GetLine(i)->StartP(),GetLine(i)->EndP()); + lineep.Sort(); + + if (lineht.Used (lineep)) + { + GetLine(i)->DoSplit(); + int other = lineht.Get(lineep); + GetLine(other)->DoSplit(); + } + else + { + lineht.Set (lineep, i); + } + } + + for (i = 1; i <= GetNLines(); i++) + { + STLLine* line = GetLine(i); + for (int ii = 1; ii <= line->GetNS(); ii++) + { + int ap1, ap2; + line->GetSeg(ii,ap1,ap2); + // (*mycout) << "SEG " << p1 << " - " << p2 << endl; + } + } + + PopStatus(); +} + +int STLGeometry :: GetNOBodys() +{ + int markedtrigs1 = 0; + int starttrig = 1; + int i, k, nnt; + int bodycnt = 0; + + Array bodynum(GetNT()); + + for (i = 1; i <= GetNT(); i++) + bodynum.Elem(i)=0; + + + while (markedtrigs1 < GetNT()) + { + for (i = starttrig; i <= GetNT(); i++) + { + if (!bodynum.Get(i)) + { + starttrig = i; + break; + } + } + //add all triangles around starttriangle, which is reachable without going over an edge + Array todolist; + Array nextlist; + bodycnt++; + markedtrigs1++; + bodynum.Elem(starttrig) = bodycnt; + todolist.Append(starttrig); + + while(todolist.Size()) + { + for (i = 1; i <= todolist.Size(); i++) + { + //const STLTriangle& tt = GetTriangle(todolist.Get(i)); + for (k = 1; k <= NONeighbourTrigs(todolist.Get(i)); k++) + { + nnt = NeighbourTrig(todolist.Get(i),k); + if (!bodynum.Get(nnt)) + { + nextlist.Append(nnt); + bodynum.Elem(nnt) = bodycnt; + markedtrigs1++; + } + } + } + + todolist.SetSize(0); + for (i = 1; i <= nextlist.Size(); i++) + { + todolist.Append(nextlist.Get(i)); + } + nextlist.SetSize(0); + } + } + PrintMessage(3, "Geometry has ", bodycnt, " separated bodys"); + + return bodycnt; +} + +void STLGeometry :: CalcFaceNums() +{ + int markedtrigs1 = 0; + int starttrig(0); + int laststarttrig = 1; + int i, k, nnt; + facecnt = 0; + + + for (i = 1; i <= GetNT(); i++) + GetTriangle(i).SetFaceNum(0); + + + while (markedtrigs1 < GetNT()) + { + for (i = laststarttrig; i <= GetNT(); i++) + { + if (!GetTriangle(i).GetFaceNum()) + { + starttrig = i; + laststarttrig = i; + break; + } + } + //add all triangles around starttriangle, which is reachable without going over an edge + Array todolist; + Array nextlist; + facecnt++; + markedtrigs1++; + GetTriangle(starttrig).SetFaceNum(facecnt); + todolist.Append(starttrig); + int ap1, ap2; + + while(todolist.Size()) + { + for (i = 1; i <= todolist.Size(); i++) + { + const STLTriangle& tt = GetTriangle(todolist.Get(i)); + for (k = 1; k <= NONeighbourTrigs(todolist.Get(i)); k++) + { + nnt = NeighbourTrig(todolist.Get(i),k); + STLTriangle& nt = GetTriangle(nnt); + if (!nt.GetFaceNum()) + { + tt.GetNeighbourPoints(nt,ap1,ap2); + if (!IsEdge(ap1,ap2)) + { + nextlist.Append(nnt); + nt.SetFaceNum(facecnt); + markedtrigs1++; + } + } + } + } + + todolist.SetSize(0); + for (i = 1; i <= nextlist.Size(); i++) + { + todolist.Append(nextlist.Get(i)); + } + nextlist.SetSize(0); + } + } + GetNOBodys(); + PrintMessage(3,"generated ", facecnt, " faces"); +} + +void STLGeometry :: ClearSpiralPoints() +{ + spiralpoints.SetSize(GetNP()); + int i; + for (i = 1; i <= spiralpoints.Size(); i++) + { + spiralpoints.Elem(i) = 0; + } +} + + +void STLGeometry :: BuildSmoothEdges () +{ + if (smoothedges) delete smoothedges; + + smoothedges = new INDEX_2_HASHTABLE (GetNE()/10 + 1); + + + // Jack: Ok ? + // UseExternalEdges(); + + PushStatusF("Build Smooth Edges"); + + int nt = GetNT(); + Vec3d ng1, ng2; + + for (int i = 1; i <= nt; i++) + { + if (multithread.terminate) + {PopStatus();return;} + + SetThreadPercent(100.0 * (double)i / (double)nt); + + const STLTriangle & trig = GetTriangle (i); + + ng1 = trig.GeomNormal(points); + ng1 /= (ng1.Length() + 1e-24); + + for (int j = 1; j <= 3; j++) + { + int nbt = NeighbourTrig (i, j); + + ng2 = GetTriangle(nbt).GeomNormal(points); + ng2 /= (ng2.Length() + 1e-24); + + int pi1, pi2; + trig.GetNeighbourPoints(GetTriangle(nbt), pi1, pi2); + + if (!IsEdge(pi1,pi2)) + { + if (ng1 * ng2 < 0) + { + PrintMessage(7,"smoothedge found"); + INDEX_2 i2(pi1, pi2); + i2.Sort(); + smoothedges->Set (i2, 1); + } + } + } + } + PopStatus(); +} + + + + + +int STLGeometry :: IsSmoothEdge (int pi1, int pi2) const +{ + if (!smoothedges) + return 0; + INDEX_2 i2(pi1, pi2); + i2.Sort(); + return smoothedges->Used (i2); +} + + + +/* +//function is not used now +int IsInArray(int n, const Array& ia) +{ + int i; + for (i = 1; i <= ia.Size(); i++) + { + if (ia.Get(i) == n) {return 1;} + } + return 0; +} +*/ + +void STLGeometry :: AddConeAndSpiralEdges() +{ + PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); + + PrintFnStart("AddConeAndSpiralEdges"); + + int i,j,k,n; + // int changed = 0; + + //check edges, where inner chart and no outer chart come together without an edge + int np1, np2, nt; + int cnt = 0; + + for (i = 1; i <= GetNOCharts(); i++) + { + STLChart& chart = GetChart(i); + for (j = 1; j <= chart.GetNChartT(); j++) + { + int t = chart.GetChartTrig(j); + const STLTriangle& tt = GetTriangle(t); + + for (k = 1; k <= 3; k++) + { + nt = NeighbourTrig(t,k); + if (GetChartNr(nt) != i && !TrigIsInOC(nt,i)) + { + tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); + if (!IsEdge(np1,np2)) + { + STLEdge se(np1,np2); + se.SetLeftTrig(t); + se.SetRightTrig(nt); + int edgenum = AddEdge(se); + AddEdgePP(np1,edgenum); + AddEdgePP(np2,edgenum); + //changed = 1; + PrintWarning("Found a spiral like structure: chart=", i, + ", trig=", t, ", p1=", np1, ", p2=", np2); + cnt++; + } + } + } + } + + } + + PrintMessage(5, "found ", cnt, " spiral like structures"); + PrintMessage(5, "added ", cnt, " edges due to spiral like structures"); + + cnt = 0; + int edgecnt = 0; + + Array trigsaroundp; + Array chartpointchecked; //gets number of chart, if in this chart already checked + chartpointchecked.SetSize(GetNP()); + + for (i = 1; i <= GetNP(); i++) + { + chartpointchecked.Elem(i) = 0; + } + + int onoc, notonoc, tpp, pn; + int ap1, ap2, tn1, tn2, l, problem; + + if (!stldoctor.conecheck) {PrintWarning("++++++++++++ \ncone checking deactivated by user!!!!!\n+++++++++++++++"); return ;} + + PushStatus("Find Critical Points"); + + int addedges = 0; + + for (i = 1; i <= GetNOCharts(); i++) + { + SetThreadPercent((double)i/(double)GetNOCharts()*100.); + if (multithread.terminate) + {PopStatus();return;} + + STLChart& chart = GetChart(i); + for (j = 1; j <= chart.GetNChartT(); j++) + { + int t = chart.GetChartTrig(j); + const STLTriangle& tt = GetTriangle(t); + + for (k = 1; k <= 3; k++) + { + pn = tt.PNum(k); + if (chartpointchecked.Get(pn) == i) + {continue;} + + int checkpoint = 0; + for (n = 1; n <= trigsperpoint.EntrySize(pn); n++) + { + if (trigsperpoint.Get(pn,n) != t && + GetChartNr(trigsperpoint.Get(pn,n)) != i && + !TrigIsInOC(trigsperpoint.Get(pn,n),i)) {checkpoint = 1;}; + } + if (checkpoint) + { + chartpointchecked.Elem(pn) = i; + + int worked = 0; + int spworked = 0; + GetSortedTrianglesAroundPoint(pn,t,trigsaroundp); + trigsaroundp.Append(t); + + problem = 0; + for (l = 2; l <= trigsaroundp.Size()-1; l++) + { + tn1 = trigsaroundp.Get(l-1); + tn2 = trigsaroundp.Get(l); + const STLTriangle& t1 = GetTriangle(tn1); + const STLTriangle& t2 = GetTriangle(tn2); + t1.GetNeighbourPoints(t2, ap1, ap2); + if (IsEdge(ap1,ap2)) break; + + if (GetChartNr(tn2) != i && !TrigIsInOC(tn2,i)) {problem = 1;} + } + + if (problem) + { + for (l = 2; l <= trigsaroundp.Size()-1; l++) + { + tn1 = trigsaroundp.Get(l-1); + tn2 = trigsaroundp.Get(l); + const STLTriangle& t1 = GetTriangle(tn1); + const STLTriangle& t2 = GetTriangle(tn2); + t1.GetNeighbourPoints(t2, ap1, ap2); + if (IsEdge(ap1,ap2)) break; + + if ((GetChartNr(tn1) == i && GetChartNr(tn2) != i && TrigIsInOC(tn2,i)) || + (GetChartNr(tn2) == i && GetChartNr(tn1) != i && TrigIsInOC(tn1,i))) + { + if (addedges || !GetNEPP(pn)) + { + STLEdge se(ap1,ap2); + se.SetLeftTrig(tn1); + se.SetRightTrig(tn2); + int edgenum = AddEdge(se); + AddEdgePP(ap1,edgenum); + AddEdgePP(ap2,edgenum); + edgecnt++; + } + if (!addedges && !GetSpiralPoint(pn)) + { + SetSpiralPoint(pn); + spworked = 1; + } + worked = 1; + } + } + } + //backwards: + problem = 0; + for (l = trigsaroundp.Size()-1; l >= 2; l--) + { + tn1 = trigsaroundp.Get(l+1); + tn2 = trigsaroundp.Get(l); + const STLTriangle& t1 = GetTriangle(tn1); + const STLTriangle& t2 = GetTriangle(tn2); + t1.GetNeighbourPoints(t2, ap1, ap2); + if (IsEdge(ap1,ap2)) break; + + if (GetChartNr(tn2) != i && !TrigIsInOC(tn2,i)) {problem = 1;} + } + if (problem) + for (l = trigsaroundp.Size()-1; l >= 2; l--) + { + tn1 = trigsaroundp.Get(l+1); + tn2 = trigsaroundp.Get(l); + const STLTriangle& t1 = GetTriangle(tn1); + const STLTriangle& t2 = GetTriangle(tn2); + t1.GetNeighbourPoints(t2, ap1, ap2); + if (IsEdge(ap1,ap2)) break; + + if ((GetChartNr(tn1) == i && GetChartNr(tn2) != i && TrigIsInOC(tn2,i)) || + (GetChartNr(tn2) == i && GetChartNr(tn1) != i && TrigIsInOC(tn1,i))) + { + if (addedges || !GetNEPP(pn)) + { + STLEdge se(ap1,ap2); + se.SetLeftTrig(tn1); + se.SetRightTrig(tn2); + int edgenum = AddEdge(se); + AddEdgePP(ap1,edgenum); + AddEdgePP(ap2,edgenum); + edgecnt++; + } + if (!addedges && !GetSpiralPoint(pn)) + { + SetSpiralPoint(pn); + spworked = 1; + //if (GetNEPP(pn) == 0) {(*mycout) << "ERROR: spiralpoint with no edge found!" << endl;} + } + worked = 1; + } + } + + if (worked) + { + //(*testout) << "set edgepoint due to spirals: pn=" << i << endl; + SetLineEndPoint(pn); + } + if (spworked) + { + /* + (*mycout) << "Warning: Critical Point " << tt.PNum(k) + << "( chart " << i << ", trig " << t + << ") has been neutralized!!!" << endl; + */ + cnt++; + } + // markedpoints.Elem(tt.PNum(k)) = 1; + } + } + } + } + PrintMessage(5, "found ", cnt, " critical points!"); + PrintMessage(5, "added ", edgecnt, " edges due to critical points!"); + + PopStatus(); + + //search points where inner chart and outer chart and "no chart" trig come together at edge-point + + PrintMessage(7,"search for special chart points"); + for (i = 1; i <= GetNOCharts(); i++) + { + STLChart& chart = GetChart(i); + for (j = 1; j <= chart.GetNChartT(); j++) + { + int t = chart.GetChartTrig(j); + const STLTriangle& tt = GetTriangle(t); + + for (k = 1; k <= 3; k++) + { + pn = tt.PNum(k); + if (GetNEPP(pn) == 2) + { + onoc = 0; + notonoc = 0; + for (n = 1; n <= trigsperpoint.EntrySize(pn); n++) + { + tpp = trigsperpoint.Get(pn,n); + if (tpp != t && GetChartNr(tpp) != i) + { + if (TrigIsInOC(tpp,i)) {onoc = 1;} + if (!TrigIsInOC(tpp,i)) {notonoc = 1;} + } + } + if (onoc && notonoc && !IsLineEndPoint(pn)) + { + GetSortedTrianglesAroundPoint(pn,t,trigsaroundp); + int here = 1; //we start on this side of edge, !here = there + int thereOC = 0; + int thereNotOC = 0; + for (l = 2; l <= trigsaroundp.Size(); l++) + { + GetTriangle(trigsaroundp.Get(l-1)). + GetNeighbourPoints(GetTriangle(trigsaroundp.Get(l)), ap1, ap2); + if (IsEdge(ap1,ap2)) {here = (here+1)%2;} + if (!here && TrigIsInOC(trigsaroundp.Get(l),i)) {thereOC = 1;} + if (!here && !TrigIsInOC(trigsaroundp.Get(l),i)) {thereNotOC = 1;} + } + if (thereOC && thereNotOC) + { + //(*mycout) << "Special OCICnotC - point " << pn << " found!" << endl; + //(*testout) << "set edgepoint due to spirals: pn=" << i << endl; + SetLineEndPoint(pn); + } + } + } + } + } + } + PrintMessage(5,"have now ", GetNE(), " edges with yellow angle = ", stlparam.yangle, " degree"); +} + +//get trigs at a point, started with starttrig, then every left +void STLGeometry :: GetSortedTrianglesAroundPoint(int p, int starttrig, Array& trigs) +{ + int acttrig = starttrig; + trigs.SetAllocSize(trigsperpoint.EntrySize(p)); + trigs.SetSize(0); + trigs.Append(acttrig); + int i, j, t, ap1, ap2, locindex1(0), locindex2(0); + + //(*mycout) << "trigs around point " << p << endl; + + int end = 0; + while (!end) + { + const STLTriangle& at = GetTriangle(acttrig); + for (i = 1; i <= trigsperpoint.EntrySize(p); i++) + { + t = trigsperpoint.Get(p,i); + const STLTriangle& nt = GetTriangle(t); + if (at.IsNeighbourFrom(nt)) + { + at.GetNeighbourPoints(nt, ap1, ap2); + if (ap2 == p) {Swap(ap1,ap2);} + if (ap1 != p) {PrintSysError("In GetSortedTrianglesAroundPoint!!!");} + + for (j = 1; j <= 3; j++) + { + if (at.PNum(j) == ap1) {locindex1 = j;}; + if (at.PNum(j) == ap2) {locindex2 = j;}; + } + if ((locindex2+1)%3+1 == locindex1) + { + if (t != starttrig) + { + trigs.Append(t); + // (*mycout) << "trig " << t << endl; + acttrig = t; + } + else + { + end = 1; + } + break; + } + } + } + } + +} + +/* +int STLGeometry :: NeighbourTrig(int trig, int nr) const +{ + return neighbourtrigs.Get(trig,nr); +} +*/ + + + +void STLGeometry :: SmoothGeometry () +{ + int i, j, k; + + double maxerr0, maxerr; + + for (i = 1; i <= GetNP(); i++) + { + if (GetNEPP(i)) continue; + + maxerr0 = 0; + for (j = 1; j <= NOTrigsPerPoint(i); j++) + { + int tnum = TrigPerPoint(i, j); + double err = Angle (GetTriangle(tnum).Normal (), + GetTriangle(tnum).GeomNormal(GetPoints())); + if (err > maxerr0) + maxerr0 = err; + } + + Point3d pi = GetPoint (i); + if (maxerr0 < 1.1) continue; // about 60 degree + + maxerr0 /= 2; // should be at least halfen + + for (k = 1; k <= NOTrigsPerPoint(i); k++) + { + const STLTriangle & trig = GetTriangle (TrigPerPoint (i, k)); + Point3d c = Center(GetPoint (trig.PNum(1)), + GetPoint (trig.PNum(2)), + GetPoint (trig.PNum(3))); + + Point3d np = pi + 0.1 * (c - pi); + SetPoint (i, np); + + maxerr = 0; + for (j = 1; j <= NOTrigsPerPoint(i); j++) + { + int tnum = TrigPerPoint(i, j); + double err = Angle (GetTriangle(tnum).Normal (), + GetTriangle(tnum).GeomNormal(GetPoints())); + if (err > maxerr) + maxerr = err; + } + + if (maxerr < maxerr0) + { + pi = np; + } + } + + SetPoint (i, pi); + } +} + + + + class STLGeometryRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const; + }; + + NetgenGeometry * STLGeometryRegister :: Load (string filename) const + { + const char * cfilename = filename.c_str(); + + if (strcmp (&cfilename[strlen(cfilename)-3], "stl") == 0) + { + PrintMessage (1, "Load STL geometry file ", cfilename); + + ifstream infile(cfilename); + + STLGeometry * hgeom = STLGeometry :: Load (infile); + hgeom -> edgesfound = 0; + return hgeom; + } + else if (strcmp (&cfilename[strlen(cfilename)-4], "stlb") == 0) + { + PrintMessage (1, "Load STL binary geometry file ", cfilename); + + ifstream infile(cfilename); + + STLGeometry * hgeom = STLGeometry :: LoadBinary (infile); + hgeom -> edgesfound = 0; + return hgeom; + } + else if (strcmp (&cfilename[strlen(cfilename)-3], "nao") == 0) + { + PrintMessage (1, "Load naomi (F. Kickinger) geometry file ", cfilename); + + ifstream infile(cfilename); + + STLGeometry * hgeom = STLGeometry :: LoadNaomi (infile); + hgeom -> edgesfound = 0; + return hgeom; + } + + + return NULL; + } + + + class STLInit + { + public: + STLInit() + { + geometryregister.Append (new STLGeometryRegister); + } + }; + + STLInit stlinit; + + +} diff --git a/libsrc/stlgeom/stlgeom.hpp b/libsrc/stlgeom/stlgeom.hpp new file mode 100644 index 00000000..d064e2d7 --- /dev/null +++ b/libsrc/stlgeom/stlgeom.hpp @@ -0,0 +1,471 @@ +#ifndef FILE_STLGEOM +#define FILE_STLGEOM + +/**************************************************************************/ +/* File: stlgeom.hpp */ +/* Author: Joachim Schoeberl */ +/* Author2: Johannes Gerstmayr */ +/* Date: 26. Jul. 99 */ +/**************************************************************************/ + +/** + STL Geometry + + + Terminology: + + Point ... coordinates of STL triangles + Triangle (short Trig) STL triangle + TopEdge .... edge in topology, boundary of STL triangles (many) + Edge .... Edges which will occur in the mesh (confirmed edges, less) +*/ + + +#include + + +namespace netgen +{ + inline int IsInArray(int n, const Array& ia) + { + return ia.Contains(n); + } + + inline bool AddIfNotExists(Array& list, int x) + { + if (list.Contains(x)) return false; + list.Append(x); + return true; + } + + extern DLL_HEADER MeshingParameters mparam; + + + +#include "stltopology.hpp" +#include "stltool.hpp" +#include "stlline.hpp" + + + + + + + + class STLEdgeDataList + { + Array storedstatus; + STLTopology & geom; + public: + + STLEdgeDataList(STLTopology & ageom); + ~STLEdgeDataList(); + + void Store (); + void Restore (); + + void SetSize(int /* size */) { }; + void Clear() { }; + int Size() const { return geom.GetNTE(); } + const STLTopEdge & Get(int i) const { return geom.GetTopEdge(i); } + STLTopEdge & Elem(int i) { return geom.GetTopEdge(i); } + + int GetNEPP(int pn) const {return geom.NTopEdgesPerPoint(pn); } + int GetEdgePP(int pn, int vi) const {return geom.TopEdgePerPoint(pn, vi);}; + + //void AddEdgePP(int pn, int vn) { } ; + + void ResetAll(); + void ChangeStatus(int status1, int status2); + + int GetEdgeNum(int np1, int np2) const + { return geom.GetTopEdgeNum (np1, np2); } + + int GetNConfEdges() const; + + void Write(ofstream& of) const; + void Read(ifstream& ifs); + + void BuildLineWithEdge(int ep1, int ep2, Array& line); + void BuildClusterWithEdge(int ep1, int ep2, Array& line); + + int GetNEPPStat(int p, int status) const; + int GetNConfCandEPP(int p) const; + }; + + + + + + + class STLGeometry : public STLTopology, public NetgenGeometry + { + // edges to be meshed: + Array edges; + //edges per point + TABLE edgesperpoint; + + // line: a connection of edges + Array lines; + Array lineendpoints; //per geometrypoint, 1 = is endpoint; 0 = no endpoint, + + Array normals; //normals belong to points! + + Array externaledges; + + int undoexternaledges; + Array storedexternaledges; + + STLEdgeDataList * edgedata; + // STLEdgeDataList edgedata_store; + int calcedgedataanglesnew; + + int edgedatastored; + + + + int facecnt; + //meshpoint is only set, if an edge is at this point!!! + + Array vicinity; //is one, if a triangle belongs to vicinity (eg. of selecttrig) + Array markedtrigs; //is one, if a triangle belongs to marked triangles (calcdirtystrigs) + Array markedsegs; //every pointpair is a segment!!! + Array selectedmultiedge; + + + //spiralpoints: + Array spiralpoints; + // + Array atlas; + //marks all already charted trigs with chartnumber + Array chartmark; + //outerchartspertrig, ascending sorted + TABLE outerchartspertrig; + + + //for meshing and project: + Array meshcharttrigs; //per trig: 1=belong to chart, 0 not + int meshchart; + + Array ha_points; // help array, np long, filled with 0 + + + // sharp geometric edges not declared as edges + // (not considered for spiral check) + INDEX_2_HASHTABLE * smoothedges; + + + //transformation: + Vec<3> meshtrignv; + Vec<3> ex, ey, ez; + Point<3> p1; + + mutable class RefinementSTLGeometry * ref; + + public: + int edgesfound; + int surfacemeshed; + int surfaceoptimized; + int volumemeshed; + + int trigsconverted; //when STLTriangles exist -> 1 + + //for selecting nodes + //int selecttrig, nodeofseltrig; + + //only for testing; + Array meshlines; + Array meshpoints; + + double area; + public: + STLGeometry(); + virtual ~STLGeometry(); + + + void Clear(); + + virtual void Save (string filename) const; + + + void STLInfo(double* data); + //stldoctor: + void SmoothNormals(); + void MarkNonSmoothNormals(); + + void CalcEdgeData(); + void CalcEdgeDataAngles(); + + const STLEdgeDataList& EdgeDataList() const {return *edgedata;} + + void UndoEdgeChange(); + void StoreEdgeData(); + void RestoreEdgeData(); + + //void ClearSelectedMultiEdge() {selectedmultiedge.SetSize(0);} + //void AddSelectedMultiEdge(twoint ep) {selectedmultiedge.Append(ep);} + //int SelectedMultiEdgeSize() {return selectedmultiedge.Size();} + const Array& SelectedMultiEdge() {return selectedmultiedge;} + twoint GetNearestSelectedDefinedEdge(); + void BuildSelectedMultiEdge(twoint ep); + void BuildSelectedEdge(twoint ep); + void BuildSelectedCluster(twoint ep); + + void ImportEdges(); + void AddEdges(const Array >& eps); + void ExportEdges(); + void LoadEdgeData(const char* file); + void SaveEdgeData(const char* file); + // void SetEdgeAtSelected(int mode); + + + void STLDoctorConfirmEdge(); + void STLDoctorCandidateEdge(); + void STLDoctorExcludeEdge(); + void STLDoctorUndefinedEdge(); + + void STLDoctorSetAllUndefinedEdges(); + void STLDoctorEraseCandidateEdges(); + void STLDoctorConfirmCandidateEdges(); + void STLDoctorConfirmedToCandidateEdges(); + + void STLDoctorDirtyEdgesToCandidates(); + void STLDoctorLongLinesToCandidates(); + + void UndoExternalEdges(); + void StoreExternalEdges(); + void RestoreExternalEdges(); + + void ImportExternalEdges(const char * filename); // Flame edges, JS + // void LoadExternalEdges(); + + void BuildExternalEdgesFromEdges(); + void SaveExternalEdges(); + void AddExternalEdgeAtSelected(); + void AddClosedLinesToExternalEdges(); + void AddLongLinesToExternalEdges(); + void AddAllNotSingleLinesToExternalEdges(); + void STLDoctorBuildEdges(); + void AddExternalEdgesFromGeomLine(); + void DeleteDirtyExternalEdges(); + void DeleteExternalEdgeAtSelected(); + void DeleteExternalEdgeInVicinity(); + void AddExternalEdge(int p1, int p2); + void DeleteExternalEdge(int p1, int p2); + int IsExternalEdge(int p1, int p2); + int NOExternalEdges() const {return externaledges.Size();} + twoint GetExternalEdge(int i) const {return externaledges.Get(i);} + + void DestroyDirtyTrigs(); + void CalcNormalsFromGeometry(); + void MoveSelectedPointToMiddle(); + void NeighbourAnglesOfSelectedTrig(); + void PrintSelectInfo(); + void ShowSelectedTrigChartnum(); + void ShowSelectedTrigCoords(); + void SmoothGeometry (); + + + void LoadMarkedTrigs(); + void SaveMarkedTrigs(); + void ClearMarkedSegs() {markedsegs.SetSize(0);} + void AddMarkedSeg(const Point<3> & ap1, const Point<3> & ap2) + { + markedsegs.Append(ap1);markedsegs.Append(ap2); + } + + void GetMarkedSeg(int i, Point<3> & ap1, Point<3> & ap2) + { + ap1=markedsegs.Get(i*2-1); + ap2=markedsegs.Get(i*2); + } + int GetNMarkedSegs() {return markedsegs.Size()/2;} + void CalcVicinity(int starttrig); + void GetVicinity(int starttrig, int size, Array& vic); + + int Vicinity(int trig) const; + + void InitMarkedTrigs(); + void MarkDirtyTrigs(); + void SmoothDirtyTrigs(); + void GeomSmoothRevertedTrigs(); + void MarkRevertedTrigs(); + double CalcTrigBadness(int i); + int IsMarkedTrig(int trig) const; + void SetMarkedTrig(int trig, int num); + void MarkTopErrorTrigs (); + + //Selected triangle + void SetSelectTrig(int trig); + int GetSelectTrig() const; + void SetNodeOfSelTrig(int n); + int GetNodeOfSelTrig() const; + + + int AddNormal(const Vec3d& n) {return normals.Append(n);} + const Vec3d & GetNormal(int nr) const {return normals.Get(nr);} + void SetNormal(int nr, const Vec3d& n) {normals.Elem(nr) = n;} + + int AddEdge(const STLEdge& v) {return edges.Append(v);} + int AddEdge(int p1, int p2); + + STLEdge GetEdge(int nr) {return edges.Get(nr);} + int GetNE() {return edges.Size();} + + double Area(); + + double GetAngle(int t1, int t2); + double GetGeomAngle(int t1, int t2); + //if triangles t1 and t2 touch, return 1 and in p1, p2 the touching points + //int TrigsTouch(int t1, int t2, int& p1, int& p2); + + + + /// + + ///ReadTriangle->STLTriangle, initialise some important variables, always after load!!! + virtual void InitSTLGeometry (const Array & readtrigs); + virtual void TopologyChanged(); //do some things, if topology changed! + int CheckGeometryOverlapping(); + + //get NO edges per point + int GetEPPSize() const {return edgesperpoint.Size();}; + int GetNEPP(int pn) + { + if (edgesperpoint.Size() == 0) {BuildEdgesPerPoint();} + return edgesperpoint.EntrySize(pn); + }; + int GetEdgePP(int pn, int vi) + { + if (edgesperpoint.Size() == 0) {BuildEdgesPerPoint();} + return edgesperpoint.Get(pn,vi); + }; + void AddEdgePP(int pn, int vn) {edgesperpoint.Add1(pn,vn);}; + //von 2 punkten ermitteln, ob sie eine Kante sind + int IsEdge(int p1, int p2); + int IsEdgeNum(int p1, int p2); + + ///Build EdgeSegments + void ClearEdges(); + void BuildEdges(); + void BuildEdgesPerPoint(); + void UseExternalEdges(); + + + void FindEdgesFromAngles(); + void CalcFaceNums(); + int GetNOBodys(); + int GetNOFaces() {return facecnt;} + void LinkEdges(); + + void AddConeAndSpiralEdges(); + void AddFaceEdges(); //each face should have at least one starting edge (outherwise it won't be meshed) + + void GetDirtyChartTrigs(int chartnum, STLChart& chart, const Array& outercharttrigs, + Array& chartpointchecked, Array& dirtytrigs); + + void ClearSpiralPoints(); + void SetSpiralPoint(int pn) {spiralpoints.Elem(pn) = 1;}; + int GetSpiralPoint(int pn) const {return spiralpoints.Get(pn);}; + + void GetSortedTrianglesAroundPoint(int p, int starttrig, Array& trigs); + + // smooth edges: sharp geometric edges not declared as edges + void BuildSmoothEdges (); + int IsSmoothEdge (int pi1, int pi2) const; + + + //make charts with regions of a max. angle + void MakeAtlas(class Mesh & mesh); + + //outerchartspertrig, sorted! + int GetOCPTSize() const {return outerchartspertrig.Size();}; + int GetNOCPT(int tn) const {return outerchartspertrig.EntrySize(tn);}; + int GetOCPT(int tn, int vi) const {return outerchartspertrig.Get(tn,vi);}; + void SetOCPT(int tn, int vi, int ocn) {outerchartspertrig.Set(tn,vi,ocn);}; + void AddOCPT(int tn, int ocn) {outerchartspertrig.Add1(tn, ocn);}; + int TrigIsInOC(int tn, int ocn) const; + + //get chart number of a trig or 0 if unmarked + int GetChartNr(int i) const; + int GetMarker(int i) const + { return chartmark.Get(i); } + void SetMarker(int nr, int m); + int GetNOCharts() const; + //get a chart from atlas + const STLChart& GetChart(int nr) const; + STLChart& GetChart(int nr) {return *(atlas.Get(nr));}; + int AtlasMade() const; + + void GetInnerChartLimes(Array& limes, int chartnum); + + //FOR MESHING + int GetMeshChartNr () { return meshchart; } + void GetMeshChartBoundary (Array & points, + Array & points3d, + Array & lines, double h); + + + Point<3> PointBetween(const Point<3> & p1, int t1, const Point<3> & p2, int t2); + + //select triangles in meshcharttrigs of actual (defined by trig) whole chart + void PrepareSurfaceMeshing(); + // + void DefineTangentialPlane(const Point<3> & ap1, const Point<3> & ap2, int trig); + // + void SelectChartOfTriangle (int trignum); + // + void SelectChartOfPoint (const Point<3> & p); + // + const Vec<3> & GetChartNormalVector () const { return meshtrignv; } + + // list of trigs + void ToPlane (const Point<3> & locpoint, int * trigs, Point<2> & plainpoint, + double h, int& zone, int checkchart); + //return 0, wenn alles OK, 1 sonst + int FromPlane (const Point<2> & plainpoint, Point<3> & locpoint, double h); + + //get nearest point in actual chart and return any triangle where it lies on + int ProjectNearest(Point<3> & p3d) const; + //project point with normal nv from last define tangential plane + + int LastTrig() const; + int Project(Point<3> & p3d) const; + int ProjectOnWholeSurface (Point<3> & p3d) const; + + int GetNLines() const {return lines.Size();} + int AddLine(STLLine* line) {return lines.Append(line);} + STLLine* GetLine(int nr) const {return lines.Get(nr);} + int GetLineP(int lnr, int pnr) const {return lines.Get(lnr)->PNum(pnr);} + int GetLineNP(int nr) const {return lines.Get(nr)->NP();} + + void SetLineEndPoint(int pn); + int IsLineEndPoint(int pn); + int LineEndPointsSet() const {return lineendpoints.Size() == GetNP();} + void ClearLineEndPoints(); + + void RestrictLocalH(class Mesh & mesh, double gh); + void RestrictLocalHCurv(class Mesh & mesh, double gh); + void RestrictHChartDistOneChart(int chartnum, Array& acttrigs, class Mesh & mesh, + double gh, double fact, double minh); + + friend class MeshingSTLSurface; + + + virtual int GenerateMesh (Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend); + + virtual const Refinement & GetRefinement () const; + }; + + +#include "meshstlsurface.hpp" + + + + extern int STLMeshingDummy (STLGeometry* stlgeometry, Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend); + + +} +#endif diff --git a/libsrc/stlgeom/stlgeomchart.cpp b/libsrc/stlgeom/stlgeomchart.cpp new file mode 100644 index 00000000..55f800c7 --- /dev/null +++ b/libsrc/stlgeom/stlgeomchart.cpp @@ -0,0 +1,749 @@ +//20.11.1999 third part of stlgeom.cc, functions with chart and atlas + +#include + +#include +#include +#include + +#include + +#include "stlgeom.hpp" + +namespace netgen +{ + +int chartdebug = 0; + + + +void STLGeometry :: MakeAtlas(Mesh & mesh) +{ + int timer1 = NgProfiler::CreateTimer ("makeatlas"); + int timer2 = NgProfiler::CreateTimer ("makeatlas - part 2"); + int timer3 = NgProfiler::CreateTimer ("makeatlas - part 3"); + + PushStatusF("Make Atlas"); + + double h = mparam.maxh; + + double atlasminh = 5e-3 * Dist (boundingbox.PMin(), boundingbox.PMax()); + PrintMessage(5, "atlasminh = ", atlasminh); + + //speedup for make atlas + if (GetNT() > 50000) + mesh.SetGlobalH(min2 (0.05*Dist (boundingbox.PMin(), boundingbox.PMax()), + mparam.maxh)); + + atlas.SetSize(0); + ClearSpiralPoints(); + BuildSmoothEdges(); + + NgProfiler::StartTimer (timer1); + + double chartangle = stlparam.chartangle; + double outerchartangle = stlparam.outerchartangle; + + chartangle = chartangle/180.*M_PI; + outerchartangle = outerchartangle/180.*M_PI; + + double coschartangle = cos(chartangle); + double cosouterchartangle = cos(outerchartangle); + double cosouterchartanglehalf = cos(0.5*outerchartangle); + double sinchartangle = sin(chartangle); + double sinouterchartangle = sin(outerchartangle); + + Array outermark(GetNT()); //marks all trigs form actual outer region + Array outertested(GetNT()); //marks tested trigs for outer region + Array pointstochart(GetNP()); //point in chart becomes chartnum + Array innerpointstochart(GetNP()); //point in chart becomes chartnum + Array chartpoints; //point in chart becomes chartnum + Array innerchartpoints; + Array dirtycharttrigs; + + Array chartdistacttrigs (GetNT()); //outercharttrigs + chartdistacttrigs = 0; + + + STLBoundary chartbound(this); //knows the actual chart boundary + //int chartboundarydivisions = 10; + markedsegs.SetSize(0); //for testing!!! + + Array chartpointchecked(GetNP()); //for dirty-chart-trigs + + pointstochart.SetSize(GetNP()); + innerpointstochart.SetSize(GetNP()); + chartmark.SetSize(GetNT()); + + for (int i = 1; i <= GetNP(); i++) + { + innerpointstochart.Elem(i) = 0; + pointstochart.Elem(i) = 0; + chartpointchecked.Elem(i) = 0; + } + + double eps = 1e-12 * Dist (boundingbox.PMin(), boundingbox.PMax()); + + int spiralcheckon = stldoctor.spiralcheck; + if (!spiralcheckon) {PrintWarning("++++++++++++\nspiral deactivated by user!!!!\n+++++++++++++++"); } + + chartmark = 0; + outermark = 0; + outertested = 0; + + double atlasarea = Area(); + double workedarea = 0; + double showinc = 100.*5000./(double)GetNT(); + double nextshow = 0; + // Point<3> startp; + int lastunmarked = 1; + + PrintMessage(5,"one dot per 5000 triangles: "); + + int markedtrigcnt = 0; + while (markedtrigcnt < GetNT()) + { + if (multithread.terminate) { PopStatus(); return; } + + if (workedarea / atlasarea*100. >= nextshow) + {PrintDot(); nextshow+=showinc;} + + SetThreadPercent(100.0 * workedarea / atlasarea); + + STLChart * chart = new STLChart(this); + atlas.Append(chart); + + //find unmarked trig + int prelastunmarked = lastunmarked; + + bool found = false; + for (int j = lastunmarked; j <= GetNT(); j++) + if (!GetMarker(j)) + { + found = true; + lastunmarked = j; + break; + } + + chartpoints.SetSize(0); + innerchartpoints.SetSize(0); + chartbound.Clear(); + chartbound.SetChart(chart); + + if (!found) { PrintSysError("Make Atlas, no starttrig found"); return; } + + //find surrounding trigs + // int starttrig = j; + int starttrig = lastunmarked; + + Point<3> startp = GetPoint(GetTriangle(starttrig).PNum(1)); + + int accepted; + int chartnum = GetNOCharts(); + + Vec<3> sn = GetTriangle(starttrig).Normal(); + chart->SetNormal (startp, sn); + + + SetMarker(starttrig, chartnum); + markedtrigcnt++; + chart->AddChartTrig(starttrig); + chartbound.AddTriangle(GetTriangle(starttrig)); + + workedarea += GetTriangle(starttrig).Area(points); + + for (int i = 1; i <= 3; i++) + { + innerpointstochart.Elem(GetTriangle(starttrig).PNum(i)) = chartnum; + pointstochart.Elem(GetTriangle(starttrig).PNum(i)) = chartnum; + chartpoints.Append(GetTriangle(starttrig).PNum(i)); + innerchartpoints.Append(GetTriangle(starttrig).PNum(i)); + } + + bool changed = true; + int oldstartic = 1; + int oldstartic2; + + NgProfiler::StartTimer (timer2); + + + while (changed) + { + changed = false; + oldstartic2 = oldstartic; + oldstartic = chart->GetNT(); + // for (ic = oldstartic2; ic <= chart->GetNT(); ic++) + for (int ic = oldstartic2; ic <= oldstartic; ic++) + { + int i = chart->GetTrig(ic); + if (GetMarker(i) == chartnum) + { + for (int j = 1; j <= NONeighbourTrigs(i); j++) + { + int nt = NeighbourTrig(i,j); + int np1, np2; + GetTriangle(i).GetNeighbourPoints(GetTriangle(nt),np1,np2); + if (GetMarker(nt) == 0 && !IsEdge(np1,np2)) + { + Vec<3> n2 = GetTriangle(nt).Normal(); + if ( (n2 * sn) >= coschartangle ) + { + + accepted = 1; + /* + //alter spiralentest, schnell, aber ungenau + for (k = 1; k <= 3; k++) + { + //find overlapping charts: + Point3d pt = GetPoint(GetTriangle(nt).PNum(k)); + if (innerpointstochart.Get(GetTriangle(nt).PNum(k)) != chartnum) + { + for (l = 1; l <= chartpoints.Size(); l++) + { + Vec3d vptpl(GetPoint(chartpoints.Get(l)), pt); + double vlen = vptpl.Length(); + if (vlen > 0) + { + vptpl /= vlen; + if ( fabs( vptpl * sn) > sinchartangle ) + { + accepted = 0; + break; + } + } + } + + } + } + */ + + //find overlapping charts exacter (fast, too): + for (int k = 1; k <= 3; k++) + { + int nnt = NeighbourTrig(nt,k); + if (GetMarker(nnt) != chartnum) + { + int nnp1, nnp2; + GetTriangle(nt).GetNeighbourPoints(GetTriangle(nnt),nnp1,nnp2); + + accepted = chartbound.TestSeg(GetPoint(nnp1), + GetPoint(nnp2), + sn,sinchartangle,1 /*chartboundarydivisions*/ ,points, eps); + + + Vec<3> n3 = GetTriangle(nnt).Normal(); + if ( (n3 * sn) >= coschartangle && + IsSmoothEdge (nnp1, nnp2) ) + accepted = 1; + } + if (!accepted) {break;} + } + + + if (accepted) + { + SetMarker(nt, chartnum); + changed = true; + markedtrigcnt++; + workedarea += GetTriangle(nt).Area(points); + chart->AddChartTrig(nt); + + chartbound.AddTriangle(GetTriangle(nt)); + + for (int k = 1; k <= 3; k++) + { + if (innerpointstochart.Get(GetTriangle(nt).PNum(k)) + != chartnum) + { + innerpointstochart.Elem(GetTriangle(nt).PNum(k)) = chartnum; + pointstochart.Elem(GetTriangle(nt).PNum(k)) = chartnum; + chartpoints.Append(GetTriangle(nt).PNum(k)); + innerchartpoints.Append(GetTriangle(nt).PNum(k)); + } + } + } + } + } + } + } + } + } + + NgProfiler::StopTimer (timer2); + NgProfiler::StartTimer (timer3); + + //find outertrigs + + // chartbound.Clear(); + // warum, ic-bound auf edge macht Probleme js ??? + + + outermark.Elem(starttrig) = chartnum; + //chart->AddOuterTrig(starttrig); + changed = true; + oldstartic = 1; + while (changed) + { + changed = false; + oldstartic2 = oldstartic; + oldstartic = chart->GetNT(); + + for (int ic = oldstartic2; ic <= oldstartic; ic++) + { + int i = chart->GetTrig(ic); + if (outermark.Get(i) != chartnum) continue; + + for (int j = 1; j <= NONeighbourTrigs(i); j++) + { + int nt = NeighbourTrig(i,j); + if (outermark.Get(nt) == chartnum) continue; + + const STLTriangle & ntrig = GetTriangle(nt); + int np1, np2; + GetTriangle(i).GetNeighbourPoints(GetTriangle(nt),np1,np2); + + if (IsEdge (np1, np2)) continue; + + + /* + if (outertested.Get(nt) == chartnum) + continue; + */ + outertested.Elem(nt) = chartnum; + + Vec<3> n2 = GetTriangle(nt).Normal(); + + //abfragen, ob noch im tolerierten Winkel + if ( (n2 * sn) >= cosouterchartangle ) + { + accepted = 1; + + bool isdirtytrig = false; + Vec<3> gn = GetTriangle(nt).GeomNormal(points); + double gnlen = gn.Length(); + + if (n2 * gn <= cosouterchartanglehalf * gnlen) + isdirtytrig = true; + + //zurueckweisen, falls eine Spiralartige outerchart entsteht + + //find overlapping charts exacter: + //do not check dirty trigs! + if (spiralcheckon && !isdirtytrig) + for (int k = 1; k <= 3; k++) + { + int nnt = NeighbourTrig(nt,k); + + if (outermark.Elem(nnt) != chartnum) + { + int nnp1, nnp2; + GetTriangle(nt).GetNeighbourPoints(GetTriangle(nnt),nnp1,nnp2); + + accepted = + chartbound.TestSeg(GetPoint(nnp1),GetPoint(nnp2), + sn,sinouterchartangle, 0 /*chartboundarydivisions*/ ,points, eps); + + + Vec<3> n3 = GetTriangle(nnt).Normal(); + if ( (n3 * sn) >= cosouterchartangle && + IsSmoothEdge (nnp1, nnp2) ) + accepted = 1; + } + if (!accepted) break; + } + + + // outer chart is only small environment of + // inner chart: + + if (accepted) + { + accepted = 0; + + for (int k = 1; k <= 3; k++) + if (innerpointstochart.Get(ntrig.PNum(k)) == chartnum) + { + accepted = 1; + break; + } + + if (!accepted) + for (int k = 1; k <= 3; k++) + { + Point<3> pt = GetPoint(ntrig.PNum(k)); + double h2 = sqr(mesh.GetH(pt)); + for (int l = 1; l <= innerchartpoints.Size(); l++) + { + double tdist = + Dist2(pt, GetPoint (innerchartpoints.Get(l))); + if (tdist < 4 * h2) + { + accepted = 1; + break; + } + } + if (accepted) break; + } + } + + + if (accepted) + { + changed = true; + outermark.Elem(nt) = chartnum; + + if (GetMarker(nt) != chartnum) + { + chartbound.AddTriangle(GetTriangle(nt)); + chart->AddOuterTrig(nt); + for (int k = 1; k <= 3; k++) + { + if (pointstochart.Get(GetTriangle(nt).PNum(k)) + != chartnum) + { + pointstochart.Elem(GetTriangle(nt).PNum(k)) = chartnum; + chartpoints.Append(GetTriangle(nt).PNum(k)); + } + } + } + } + } + } + } + } + + NgProfiler::StopTimer (timer3); + + //end of while loop for outer chart + GetDirtyChartTrigs(chartnum, *chart, outermark, chartpointchecked, dirtycharttrigs); + //dirtycharttrigs are local (chart) point numbers!!!!!!!!!!!!!!!! + + if (dirtycharttrigs.Size() != 0 && + (dirtycharttrigs.Size() != chart->GetNChartT() || dirtycharttrigs.Size() != 1)) + { + if (dirtycharttrigs.Size() == chart->GetNChartT() && dirtycharttrigs.Size() != 1) + { + //if all trigs would be eliminated -> leave 1 trig! + dirtycharttrigs.SetSize(dirtycharttrigs.Size() - 1); + } + for (int k = 1; k <= dirtycharttrigs.Size(); k++) + { + int tn = chart->GetChartTrig(dirtycharttrigs.Get(k)); + outermark.Elem(tn) = 0; //not necessary, for later use + SetMarker(tn, 0); + markedtrigcnt--; + workedarea -= GetTriangle(tn).Area(points); + } + chart->MoveToOuterChart(dirtycharttrigs); + lastunmarked = 1; + lastunmarked = prelastunmarked; + } + + //calculate an estimate meshsize, not to produce too large outercharts, with factor 2 larger! + RestrictHChartDistOneChart(chartnum, chartdistacttrigs, mesh, h, 0.5, atlasminh); + // NgProfiler::Print(stdout); + } + + NgProfiler::StopTimer (timer1); + // NgProfiler::Print(stdout); + + + PrintMessage(5,""); + PrintMessage(5,"NO charts=", atlas.Size()); + + int cnttrias = 0; + outerchartspertrig.SetSize(GetNT()); + for (int i = 1; i <= atlas.Size(); i++) + { + for (int j = 1; j <= GetChart(i).GetNT(); j++) + { + int tn = GetChart(i).GetTrig(j); + AddOCPT(tn,i); + } + + cnttrias += GetChart(i).GetNT(); + } + PrintMessage(5, "NO outer chart trias=", cnttrias); + + //sort outerchartspertrig + for (int i = 1; i <= GetNT(); i++) + { + for (int k = 1; k < GetNOCPT(i); k++) + for (int j = 1; j < GetNOCPT(i); j++) + { + int swap = GetOCPT(i,j); + if (GetOCPT(i,j+1) < swap) + { + SetOCPT(i,j,GetOCPT(i,j+1)); + SetOCPT(i,j+1,swap); + } + } + + // check make atlas + if (GetChartNr(i) <= 0 || GetChartNr(i) > GetNOCharts()) + PrintSysError("Make Atlas: chartnr(", i, ")=0!!"); + } + + mesh.SetGlobalH(mparam.maxh); + mesh.SetMinimalH(mparam.minh); + + + AddConeAndSpiralEdges(); + + PrintMessage(5,"Make Atlas finished"); + + PopStatus(); +} + + +int STLGeometry::TrigIsInOC(int tn, int ocn) const +{ + if (tn < 1 || tn > GetNT()) + { + // assert (1); + abort (); + PrintSysError("STLGeometry::TrigIsInOC illegal tn: ", tn); + + return 0; + } + + /* + int firstval = 0; + int i; + for (i = 1; i <= GetNOCPT(tn); i++) + { + if (GetOCPT(tn, i) == ocn) {firstval = 1;} + } + */ + + int found = 0; + + int inc = 1; + while (inc <= GetNOCPT(tn)) {inc *= 2;} + inc /= 2; + + int start = inc; + + while (!found && inc > 0) + { + if (GetOCPT(tn,start) > ocn) {inc = inc/2; start -= inc;} + else if (GetOCPT(tn,start) < ocn) {inc = inc/2; if (start+inc <= GetNOCPT(tn)) {start += inc;}} + else {found = 1;} + } + + return GetOCPT(tn, start) == ocn; +} + +int STLGeometry :: GetChartNr(int i) const +{ + if (i > chartmark.Size()) + { + PrintSysError("GetChartNr(", i, ") not possible!!!"); + i = 1; + } + return chartmark.Get(i); +} +/* +int STLGeometry :: GetMarker(int i) const +{ + return chartmark.Get(i); +} +*/ +void STLGeometry :: SetMarker(int nr, int m) +{ + chartmark.Elem(nr) = m; +} +int STLGeometry :: GetNOCharts() const +{ + return atlas.Size(); +} +const STLChart& STLGeometry :: GetChart(int nr) const +{ + if (nr > atlas.Size()) + { + PrintSysError("GetChart(", nr, ") not possible!!!"); + nr = 1; + } + return *(atlas.Get(nr)); +} + +int STLGeometry :: AtlasMade() const +{ + return chartmark.Size() != 0; +} + + +/* +//return 1 if not exists +int AddIfNotExists(Array& list, int x) +{ + int i; + for (i = 1; i <= list.Size(); i++) + { + if (list.Get(i) == x) {return 0;} + } + list.Append(x); + return 1; +} +*/ + +void STLGeometry :: GetInnerChartLimes(Array& limes, int chartnum) +{ + int j, k; + + int t, nt, np1, np2; + + limes.SetSize(0); + + STLChart& chart = GetChart(chartnum); + + for (j = 1; j <= chart.GetNChartT(); j++) + { + t = chart.GetChartTrig(j); + const STLTriangle& tt = GetTriangle(t); + for (k = 1; k <= 3; k++) + { + nt = NeighbourTrig(t,k); + if (GetChartNr(nt) != chartnum) + { + tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); + if (!IsEdge(np1,np2)) + { + limes.Append(twoint(np1,np2)); + /* + p3p1 = GetPoint(np1); + p3p2 = GetPoint(np2); + if (AddIfNotExists(limes,np1)) + { + plimes1.Append(p3p1); + //plimes1trigs.Append(t); + //plimes1origin.Append(np1); + } + if (AddIfNotExists(limes1,np2)) + { + plimes1.Append(p3p2); + //plimes1trigs.Append(t); + //plimes1origin.Append(np2); + } + //chart.AddILimit(twoint(np1,np2)); + + for (int di = 1; di <= divisions; di++) + { + double f1 = (double)di/(double)(divisions+1.); + double f2 = (divisions+1.-(double)di)/(double)(divisions+1.); + + plimes1.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2, + p3p1.Y()*f1+p3p2.Y()*f2, + p3p1.Z()*f1+p3p2.Z()*f2)); + //plimes1trigs.Append(t); + //plimes1origin.Append(0); + } + */ + } + } + } + } +} + + + +void STLGeometry :: GetDirtyChartTrigs(int chartnum, STLChart& chart, + const Array& outercharttrigs, + Array& chartpointchecked, + Array& dirtytrigs) +{ + dirtytrigs.SetSize(0); + int j,k,n; + + int np1, np2, nt; + int cnt = 0; + + for (j = 1; j <= chart.GetNChartT(); j++) + { + int t = chart.GetChartTrig(j); + const STLTriangle& tt = GetTriangle(t); + + for (k = 1; k <= 3; k++) + { + nt = NeighbourTrig(t,k); + if (GetChartNr(nt) != chartnum && outercharttrigs.Get(nt) != chartnum) + { + tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); + if (!IsEdge(np1,np2)) + { + dirtytrigs.Append(j); //local numbers!!! + cnt++; + break; //only once per trig!!! + } + } + } + } + cnt = 0; + + int ap1, ap2, tn1, tn2, l, problem, pn; + Array trigsaroundp; + + for (j = chart.GetNChartT(); j >= 1; j--) + { + int t = chart.GetChartTrig(j); + const STLTriangle& tt = GetTriangle(t); + + for (k = 1; k <= 3; k++) + { + pn = tt.PNum(k); + //if (chartpointchecked.Get(pn) == chartnum) + //{continue;} + + int checkpoint = 0; + for (n = 1; n <= trigsperpoint.EntrySize(pn); n++) + { + if (trigsperpoint.Get(pn,n) != t && //ueberfluessig??? + GetChartNr(trigsperpoint.Get(pn,n)) != chartnum && + outercharttrigs.Get(trigsperpoint.Get(pn,n)) != chartnum) {checkpoint = 1;}; + } + if (checkpoint) + { + chartpointchecked.Elem(pn) = chartnum; + + GetSortedTrianglesAroundPoint(pn,t,trigsaroundp); + trigsaroundp.Append(t); //ring + + problem = 0; + //forward: + for (l = 2; l <= trigsaroundp.Size()-1; l++) + { + tn1 = trigsaroundp.Get(l-1); + tn2 = trigsaroundp.Get(l); + const STLTriangle& t1 = GetTriangle(tn1); + const STLTriangle& t2 = GetTriangle(tn2); + t1.GetNeighbourPoints(t2, ap1, ap2); + if (IsEdge(ap1,ap2)) break; + + if (GetChartNr(tn2) != chartnum && outercharttrigs.Get(tn2) != chartnum) {problem = 1;} + } + + //backwards: + for (l = trigsaroundp.Size()-1; l >= 2; l--) + { + tn1 = trigsaroundp.Get(l+1); + tn2 = trigsaroundp.Get(l); + const STLTriangle& t1 = GetTriangle(tn1); + const STLTriangle& t2 = GetTriangle(tn2); + t1.GetNeighbourPoints(t2, ap1, ap2); + if (IsEdge(ap1,ap2)) break; + + if (GetChartNr(tn2) != chartnum && outercharttrigs.Get(tn2) != chartnum) {problem = 1;} + } + if (problem && !IsInArray(j,dirtytrigs)) + { + dirtytrigs.Append(j); + cnt++; + break; //only once per triangle + } + } + } + } + +} + +} diff --git a/libsrc/stlgeom/stlgeommesh.cpp b/libsrc/stlgeom/stlgeommesh.cpp new file mode 100644 index 00000000..d7da795f --- /dev/null +++ b/libsrc/stlgeom/stlgeommesh.cpp @@ -0,0 +1,1590 @@ +//20.11.1999 second part of stlgeom.cc, mainly mesh functions + +#include + +#include +#include +#include + +#include + +#include "stlgeom.hpp" + +namespace netgen +{ +int EdgeUsed(int p1, int p2, Array& edges, INDEX_2_HASHTABLE& hashtab) +{ + if (p1 > p2) {swap (p1,p2);} + + if (hashtab.Used(INDEX_2(p1,p2))) + {return hashtab.Get(INDEX_2(p1,p2));} + + return 0; +} + +Point<3> STLGeometry :: PointBetween(const Point<3> & ap1, int t1, + const Point<3> & ap2, int t2) +{ + //funktioniert nicht in allen Fällen! + + PrintWarning("Point between"); + + + ClearMarkedSegs(); + + InitMarkedTrigs(); + SetMarkedTrig(t1,1); + SetMarkedTrig(t2,1); + + TABLE edgepoints; + TABLE edgepointdists; + TABLE edgepointorigines; + TABLE edgepointoriginps; + + Array edgetrigs; + Array edgepointnums; + Array edgetriglocinds; + + int size = 3*GetNT(); + INDEX_2_HASHTABLE hashtab(size); + + int divisions = 10; + + edgepoints.SetSize(size); + edgepointdists.SetSize(size); + edgepointorigines.SetSize(size); + edgepointoriginps.SetSize(size); + + edgetrigs.SetSize(size); + edgepointnums.SetSize(size); + edgetriglocinds.SetSize(size); + + Array edgelist1; + Array edgelist2; + + edgelist1.SetSize(0); + edgelist2.SetSize(0); + + + int i, j, k, l, m; + int edgecnt = 0; + + //first triangle: + for (i = 1; i <= 3; i++) + { + int ptn1 = GetTriangle(t1).PNum(i); + int ptn2 = GetTriangle(t1).PNumMod(i+1); + + if (ptn1 > ptn2) {swap(ptn1,ptn2);} + + Point3d pt1 = GetPoint(ptn1); + Point3d pt2 = GetPoint(ptn2); + + edgecnt++; + edgetrigs.Elem(edgecnt) = t1; + edgepointnums.Elem(edgecnt) = INDEX_2(ptn1,ptn2); + hashtab.Set(edgepointnums.Get(edgecnt),edgecnt); + + edgetriglocinds.Elem(edgecnt) = i; + edgelist1.Append(edgecnt); + + for (j = 1; j <= divisions; j++) + { + double lfact = (double)j/(double)divisions; + Point3d pbtw(lfact*pt1.X()+(1.-lfact)*pt2.X(), + lfact*pt1.Y()+(1.-lfact)*pt2.Y(), + lfact*pt1.Z()+(1.-lfact)*pt2.Z()); + + //AddMarkedSeg(ap1,pbtw); + + edgepoints.Add1(edgecnt,pbtw); + edgepointdists.Add1(edgecnt,Dist(pbtw,ap1)); + edgepointorigines.Add1(edgecnt,0); + edgepointoriginps.Add1(edgecnt,0); + } + } + + int finished = 0; + int endpointorigine = 0; + int endpointoriginp = 0; + double endpointmindist = 1E50; + + int maxsize = 0; + while (!finished) + { + finished = 1; + + if (edgelist1.Size() > maxsize) {maxsize = edgelist1.Size();} + + for (i = 1; i <= edgelist1.Size(); i++) + { + int en = edgelist1.Get(i); + int trig = edgetrigs.Get(en); + int edgenum = edgetriglocinds.Get(en); + int tn = NeighbourTrigSorted(trig,edgenum); + + if (tn != t2) + { + for (k = 1; k <= 3; k++) + { + int pnt1 = GetTriangle(tn).PNum(k); + int pnt2 = GetTriangle(tn).PNumMod(k+1); + + if (pnt1 > pnt2) {swap(pnt1,pnt2);} + + Point3d pt1 = GetPoint(pnt1); + Point3d pt2 = GetPoint(pnt2); + + //AddMarkedSeg(pt1,pt2); + + //if (!(pnt1 == ep1 && pnt2 == ep2)) + // { + int edgeused = 0; + edgenum = EdgeUsed(pnt1, pnt2, edgepointnums, hashtab); + if (edgenum != en) + { + if (edgenum != 0) + {edgeused = 1;} + else + { + edgecnt++; + edgenum = edgecnt; + + edgetrigs.Elem(edgenum) = tn; + edgepointnums.Elem(edgenum) = INDEX_2(pnt1,pnt2); + hashtab.Set(edgepointnums.Get(edgenum),edgenum); + edgetriglocinds.Elem(edgenum) = k; + } + + if (edgenum > size || edgenum == 0) {PrintSysError("edgenum = ", edgenum);} + + double minofmindist = 1E50; + int changed = 0; + + for (l = 1; l <= divisions; l++) + { + double lfact = (double)l/(double)divisions; + Point3d pbtw(lfact*pt1.X()+(1.-lfact)*pt2.X(), + lfact*pt1.Y()+(1.-lfact)*pt2.Y(), + lfact*pt1.Z()+(1.-lfact)*pt2.Z()); + + double mindist = 1E50; + int index=0; + + for (m = 1; m <= divisions; m++) + { + const Point3d& p = edgepoints.Get(en,m); + if (Dist(pbtw,p) + edgepointdists.Get(en,m) < mindist) + {mindist = Dist(pbtw,p) + edgepointdists.Get(en,m); index = m;} + } + + //if (mindist < endpointmindist) {finished = 0;} + if (mindist < minofmindist) {minofmindist = mindist;} + + + if (!edgeused) + { + //AddMarkedSeg(pbtw,edgepoints.Get(en,index)); + + edgepoints.Add1(edgenum,pbtw); + edgepointdists.Add1(edgenum,mindist); + edgepointorigines.Add1(edgenum,en); + edgepointoriginps.Add1(edgenum,index); + changed = 1; + } + else + { + if (mindist < edgepointdists.Get(edgenum,l)) + { + edgepointdists.Set(edgenum,l,mindist); + edgepointorigines.Set(edgenum,l,en); + edgepointoriginps.Set(edgenum,l,index); + changed = 1; + } + } + } + if (minofmindist < endpointmindist-1E-10 && changed) + { + finished = 0; + edgelist2.Append(edgenum); + } + } + } + } + else + { + double mindist = 1E50; + int index(0); + for (m = 1; m <= divisions; m++) + { + const Point3d& p = edgepoints.Get(en,m); + if (Dist(ap2,p) + edgepointdists.Get(en,m) < mindist) + {mindist = Dist(ap2,p) + edgepointdists.Get(en,m); index = m;} + } + if (mindist < endpointmindist) + { + endpointorigine = en; + endpointoriginp = index; + endpointmindist = mindist; + } + } + } + edgelist1.SetSize(0); + for (i = 1; i <= edgelist2.Size(); i++) + { + edgelist1.Append(edgelist2.Get(i)); + } + } + + if (!endpointorigine) {PrintSysError("No connection found!");} + + Array plist; + + plist.Append(ap2); + int laste = endpointorigine; + int lastp = endpointoriginp; + int lle, llp; + + + while (laste) + { + plist.Append(edgepoints.Get(laste,lastp)); + + lle = laste; + llp = lastp; + laste = edgepointorigines.Get(lle,llp); + lastp = edgepointoriginps.Get(lle,llp); + } + + plist.Append(ap1); + + for (i = 1; i <= plist.Size()-1; i++) + { + AddMarkedSeg(plist.Get(i),plist.Get(i+1)); + } + + PrintMessage(5,"PointBetween: complexity=", maxsize); + + + Point3d pm; + double dist = 0; + int found = 0; + + for (i = 1; i <= plist.Size()-1; i++) + { + dist += Dist(plist.Get(i),plist.Get(i+1)); + if (dist > endpointmindist*0.5) + { + double segl = Dist(plist.Get(i), plist.Get(i+1)); + double d = dist - endpointmindist * 0.5; + pm = Point3d(d/segl*plist.Get(i).X() + (1.-d/segl)*plist.Get(i+1).X(), + d/segl*plist.Get(i).Y() + (1.-d/segl)*plist.Get(i+1).Y(), + d/segl*plist.Get(i).Z() + (1.-d/segl)*plist.Get(i+1).Z()); + found = 1; + break; + } + } + if (!found) {PrintWarning("Problem in PointBetween"); pm = Center(ap1,ap2);} + + AddMarkedSeg(pm, Point3d(0.,0.,0.)); + + return pm; + +} + + +void STLGeometry :: PrepareSurfaceMeshing() +{ + meshchart = -1; //clear no old chart + meshcharttrigs.SetSize(GetNT()); + meshcharttrigs = 0; +} + +void STLGeometry::GetMeshChartBoundary (Array & apoints, + Array & points3d, + Array & alines, double h) +{ + twoint seg, newseg; + int zone; + Point<2> p2; + + const STLChart& chart = GetChart(meshchart); + + + for (int i = 1; i <= chart.GetNOLimit(); i++) + { + seg = chart.GetOLimit(i); + INDEX_2 i2; + for (int j = 1; j <= 2; j++) + { + int pi = (j == 1) ? seg.i1 : seg.i2; + int lpi; + if (ha_points.Get(pi) == 0) + { + const Point<3> & p3d = GetPoint (pi); + Point<2> p2d; + + points3d.Append (p3d); + ToPlane(p3d, 0, p2d, h, zone, 0); + apoints.Append (p2d); + + lpi = apoints.Size(); + ha_points.Elem(pi) = lpi; + } + else + lpi = ha_points.Get(pi); + + i2.I(j) = lpi; + } + alines.Append (i2); + + /* + seg = chart.GetOLimit(i); + psize = points.Size(); + + newseg.i1 = psize+1; + newseg.i2 = psize+2; + + ToPlane(GetPoint(seg.i1), 0, p2, h, zone, 0); + points.Append(p2); + points3d.Append (GetPoint(seg.i1)); + ToPlane(GetPoint(seg.i2), 0, p2, h, zone, 0); + points.Append(p2); + points3d.Append (GetPoint(seg.i2)); + lines.Append (INDEX_2 (points.Size()-1, points.Size())); + */ + } + + for (int i = 1; i <= chart.GetNOLimit(); i++) + { + seg = chart.GetOLimit(i); + ha_points.Elem(seg.i1) = 0; + ha_points.Elem(seg.i2) = 0; + } +} + +void STLGeometry :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2, int trig) +{ + p1 = ap1; //save for ToPlane, in data of STLGeometry class + Point<3> p2 = ap2; //only locally used + + meshchart = GetChartNr(trig); + + if (usechartnormal) + meshtrignv = GetChart(meshchart).GetNormal(); + else + meshtrignv = GetTriangle(trig).Normal(); + + //meshtrignv = GetTriangle(trig).Normal(points); + + meshtrignv /= meshtrignv.Length(); + + GetTriangle(trig).ProjectInPlain(points, meshtrignv, p2); + + + ez = meshtrignv; + ez /= ez.Length(); + ex = p2 - p1; + ex -= (ex * ez) * ez; + ex /= ex.Length(); + ey = Cross (ez, ex); + +} + + +void STLGeometry :: SelectChartOfTriangle (int trignum) +{ + meshchart = GetChartNr(trignum); + meshtrignv = GetTriangle(trignum).Normal(); +} + + +void STLGeometry :: SelectChartOfPoint (const Point<3> & p) +{ + int i, ii; + + Array trigsinbox; + + Box<3> box(p,p); + box.Increase (1e-6); + GetTrianglesInBox (box, trigsinbox); + + + // for (i = 1; i <= GetNT(); i++) + for (ii = 1; ii <= trigsinbox.Size(); ii++) + { + i = trigsinbox.Get(ii); + Point<3> hp = p; + if (GetTriangle(i).GetNearestPoint(points, hp) <= 1E-8) + { + SelectChartOfTriangle (i); + break; + } + } + return; +} + + + +void STLGeometry :: ToPlane (const Point<3> & locpoint, int * trigs, + Point<2> & plainpoint, double h, int& zone, + int checkchart) +{ + if (checkchart) + { + + //check if locpoint lies on actual chart: + zone = 0; + + + // Point3d p; + int i = 1; + const STLChart& chart = GetChart(meshchart); + int foundinchart = 0; + const double range = 1e-6; //1e-4 old + + + + + if (trigs) + { + int * htrigs = trigs; + while (*htrigs) + { + if (TrigIsInOC (*htrigs, meshchart)) + { + foundinchart = 1; + break; + } + htrigs++; + } + } + + else + { + Array trigsinbox; + + if (!geomsearchtreeon) + { + //alter chart-tree + Box<3> box(locpoint, locpoint); + box.Increase (range); + chart.GetTrianglesInBox (box.PMin(), box.PMax(), trigsinbox); + } + else + { + Array trigsinbox2; + Box<3> box(locpoint, locpoint); + box.Increase (range); + GetTrianglesInBox (box, trigsinbox2); + for (i = 1; i <= trigsinbox2.Size(); i++) + { + if (TrigIsInOC(trigsinbox2.Get(i),meshchart)) {trigsinbox.Append(trigsinbox2.Get(i));} + } + + } + + + for (i = 1; i <= trigsinbox.Size(); i++) + { + Point<3> p = locpoint; + if (GetTriangle(trigsinbox.Get(i)).GetNearestPoint(points, p) + <= 1E-8) + { + foundinchart = 1; + break; + } + + } + } + + //do not use this point (but do correct projection (joachim) + if (!foundinchart) + { + zone = -1; // plainpoint.X() = 11111; plainpoint.Y() = 11111; return; + } + } + + else + { + zone = 0; + } + + //transform in plane + Vec<3> p1p = locpoint - p1; + plainpoint(0) = (p1p * ex) / h; + plainpoint(1) = (p1p * ey) / h; + +} + +int STLGeometry :: FromPlane (const Point<2> & plainpoint, + Point<3> & locpoint, double h) +{ + Point2d plainpoint2 (plainpoint); + + plainpoint2.X() *= h; + plainpoint2.Y() *= h; + Vec3d p1p = plainpoint2.X() * ex + plainpoint2.Y() * ey; + locpoint = p1 + p1p; + + + int rv = Project(locpoint); + if (!rv) {return 1;} //project nicht gegangen + return 0; +} + +int lasttrig; +int STLGeometry :: LastTrig() const {return lasttrig;}; + +//project normal to tangential plane +int STLGeometry :: Project(Point<3> & p3d) const +{ + Point<3> p, pf; + + int i, j; + int fi = 0; + int cnt = 0; + int different = 0; + const double lamtol = 1e-6; + + const STLChart& chart = GetChart(meshchart); + + int nt = chart.GetNT(); + + QuadraticFunction3d quadfun(p3d, meshtrignv); + + /* + Vec3d hv = meshtrignv; + hv /= hv.Length(); + Vec3d t1, t2; + hv.GetNormal (t1); + Cross (hv, t1, t2); + */ + + for (j = 1; j <= nt; j++) + { + i = chart.GetTrig(j); + + const Point<3> & c = GetTriangle(i).center; + /* + double d1 = t1 * (c-p3d); + double d2 = t2 * (c-p3d); + */ + /* + if (d1 * d1 + d2 * d2 > sqr (GetTriangle(i).rad)) + continue; + */ + if (quadfun.Eval(c) > sqr (GetTriangle(i).rad)) + continue; + + p = p3d; + Vec<3> lam; + int err = GetTriangle(i).ProjectInPlain(points, meshtrignv, p, lam); + int inside = (err == 0 && lam(0) > -lamtol && + lam(1) > -lamtol && (1-lam(0)-lam(1)) > -lamtol); + + + /* + p = p3d; + GetTriangle(i).ProjectInPlain(points, meshtrignv, p); + if (GetTriangle(i).PointInside(points, p)) + */ + if (inside) + { + if (cnt != 0) + { + if (Dist2(p,pf)>=1E-16) + { + // (*testout) << "ERROR: found two points to project which are different" << endl; + //(*testout) << "p=" << p << ", pf=" << pf << endl; + different = 1; + } + } + pf = p; fi = i; cnt++; + } + + if (inside) + break; + + } + + // if (cnt == 2) {(*testout) << "WARNING: found 2 triangles to project" << endl;} + //if (cnt == 3) {(*testout) << "WARNING: found 3 triangles to project" << endl;} + //if (cnt > 3) {(*testout) << "WARNING: found more than 3 triangles to project" << endl;} + + if (fi != 0) {lasttrig = fi;} + if (fi != 0 && !different) {p3d = pf; return fi;} + + // (*testout) << "WARNING: Project failed" << endl; + return 0; + +} + +//project normal to tangential plane +int STLGeometry :: ProjectOnWholeSurface(Point<3> & p3d) const +{ + Point<3> p, pf; + + int i; + int fi = 0; + int cnt = 0; + int different = 0; + const double lamtol = 1e-6; + + for (i = 1; i <= GetNT(); i++) + { + p = p3d; + Vec<3> lam; + int err = + GetTriangle(i).ProjectInPlain(points, meshtrignv, p, lam); + int inside = (err == 0 && lam(0) > -lamtol && + lam(1) > -lamtol && (1-lam(0)-lam(1)) > -lamtol); + + /* + p = p3d; + GetTriangle(i).ProjectInPlain(points, meshtrignv, p); + if (GetTriangle(i).PointInside(points, p)) + */ + if (inside) + { + if (cnt != 0) + { + if (Dist2(p,pf)>=1E-16) + { + // (*testout) << "ERROR: found two points to project which are different" << endl; + // (*testout) << "p=" << p << ", pf=" << pf << endl; + different = 1; + } + } + pf = p; fi = i; cnt++; + } + } + /* + if (cnt == 2) {(*testout) << "WARNING: found 2 triangles to project" << endl;} + if (cnt == 3) {(*testout) << "WARNING: found 3 triangles to project" << endl;} + if (cnt > 3) {(*testout) << "WARNING: found more than 3 triangles to project" << endl;} + */ + if (fi != 0) {lasttrig = fi;} + if (fi != 0 && !different) {p3d = pf; return fi;} + + // (*testout) << "WARNING: Project failed" << endl; + return 0; + +} + + +int STLGeometry :: ProjectNearest(Point<3> & p3d) const +{ + Point<3> p, pf = 0.0; + + //set new chart + const STLChart& chart = GetChart(meshchart); + int i; + double nearest = 1E50; + double dist; + int ft = 0; + + for (i = 1; i <= chart.GetNT(); i++) + { + p = p3d; + dist = GetTriangle(chart.GetTrig(i)).GetNearestPoint(points, p); + if (dist < nearest) + { + pf = p; + nearest = dist; + ft = chart.GetTrig(i); + } + } + p3d = pf; + //if (!ft) {(*testout) << "ERROR: ProjectNearest failed" << endl;} + + return ft; +} + + + + +//Restrict local h due to curvature for make atlas +void STLGeometry :: RestrictLocalHCurv(class Mesh & mesh, double gh) +{ + PushStatusF("Restrict H due to surface curvature"); + + //bei jedem Dreieck alle Nachbardreiecke vergleichen, und, fallskein Kante dazwischen, + //die Meshsize auf ein bestimmtes Mass limitieren + int i,j; + + int ap1,ap2,p3,p4; + Point<3> p1p, p2p, p3p, p4p; + Vec<3> n, ntn; + double rzyl, localh; + + // double localhfact = 0.5; + // double geometryignorelength = 1E-4; + double minlocalh = stlparam.atlasminh; + + Box<3> bb = GetBoundingBox(); + // mesh.SetLocalH(bb.PMin() - Vec3d(10, 10, 10),bb.PMax() + Vec3d(10, 10, 10), + // mparam.grading); + + // mesh.SetGlobalH(gh); + + double mincalch = 1E10; + double maxcalch = -1E10 +; + double objectsize = bb.Diam(); + double geometryignoreedgelength = objectsize * 1e-5; + + + if (stlparam.resthatlasenable) + { + Array minh; //minimales h pro punkt + minh.SetSize(GetNP()); + for (i = 1; i <= GetNP(); i++) + { + minh.Elem(i) = gh; + } + + for (i = 1; i <= GetNT(); i++) + { + SetThreadPercent((double)i/(double)GetNT()*100.); + + if (multithread.terminate) + {PopStatus(); return;} + + const STLTriangle& trig = GetTriangle(i); + n = GetTriangle(i).Normal(); + for (j = 1; j <= 3; j++) + { + const STLTriangle& nt = GetTriangle(NeighbourTrig(i,j)); + + trig.GetNeighbourPointsAndOpposite(nt,ap1,ap2,p3); + + //checken, ob ap1-ap2 eine Kante sind + if (IsEdge(ap1,ap2)) continue; + + p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - ap1 - ap2; + + p1p = GetPoint(ap1); p2p = GetPoint(ap2); + p3p = GetPoint(p3); p4p = GetPoint(p4); + + double h1 = GetDistFromInfiniteLine(p1p,p2p, p4p); + double h2 = GetDistFromInfiniteLine(p1p,p2p, p3p); + double diaglen = Dist (p1p, p2p); + + if (diaglen < geometryignoreedgelength) + continue; + rzyl = ComputeCylinderRadius + (n, GetTriangle(NeighbourTrig(i,j)).Normal(), + h1, h2); + + + if (h1 < 1e-3 * diaglen && h2 < 1e-3 * diaglen) + continue; + if (h1 < 1e-5 * objectsize && h2 < 1e-5 * objectsize) + continue; + + + // rzyl = mindist/(2*sinang); + localh = 10.*rzyl / stlparam.resthatlasfac; + if (localh < mincalch) {mincalch = localh;} + if (localh > maxcalch) {maxcalch = localh;} + + if (localh < minlocalh) {localh = minlocalh;} + if (localh < gh) + { + minh.Elem(ap1) = min2(minh.Elem(ap1),localh); + minh.Elem(ap2) = min2(minh.Elem(ap2),localh); + } + + mesh.RestrictLocalHLine(p1p, p2p, localh); + } + + } + } + PrintMessage(5, "done\nATLAS H: nmin local h=", mincalch); + PrintMessage(5, "ATLAS H: max local h=", maxcalch); + PrintMessage(5, "Local h tree has ", mesh.LocalHFunction().GetNBoxes(), " boxes of size ", + (int)sizeof(GradingBox)); + + PopStatus(); + +} + //restrict local h due to near edges and due to outer chart distance +void STLGeometry :: RestrictLocalH(class Mesh & mesh, double gh) +{ + + //bei jedem Dreieck alle Nachbardreiecke vergleichen, und, fallskein Kante dazwischen, + //die Meshsize auf ein bestimmtes Mass limitieren + int i,j; + + int ap1,ap2,p3,p4; + Point3d p1p, p2p, p3p, p4p; + Vec3d n, ntn; + double rzyl, localh; + + // double localhfact = 0.5; + // double geometryignorelength = 1E-4; + + Box<3> bb = GetBoundingBox(); + //mesh.SetLocalH(bb.PMin() - Vec3d(10, 10, 10),bb.PMax() + Vec3d(10, 10, 10), + // mparam.grading); + + //mesh.SetGlobalH(gh); + + double mincalch = 1E10; + double maxcalch = -1E10; + + double objectsize = bb.Diam(); + double geometryignoreedgelength = objectsize * 1e-5; + + if (stlparam.resthsurfcurvenable) + { + PushStatusF("Restrict H due to surface curvature"); + + Array minh; //minimales h pro punkt + minh.SetSize(GetNP()); + for (i = 1; i <= GetNP(); i++) + { + minh.Elem(i) = gh; + } + + for (i = 1; i <= GetNT(); i++) + { + SetThreadPercent((double)i/(double)GetNT()*100.); + if (i%20000==19999) {PrintMessage(7, (double)i/(double)GetNT()*100. , "%");} + + if (multithread.terminate) + {PopStatus(); return;} + + const STLTriangle& trig = GetTriangle(i); + n = GetTriangle(i).Normal(); + for (j = 1; j <= 3; j++) + { + const STLTriangle& nt = GetTriangle(NeighbourTrig(i,j)); + + trig.GetNeighbourPointsAndOpposite(nt,ap1,ap2,p3); + + //checken, ob ap1-ap2 eine Kante sind + if (IsEdge(ap1,ap2)) continue; + + p4 = trig.PNum(1) + trig.PNum(2) + trig.PNum(3) - ap1 - ap2; + + p1p = GetPoint(ap1); p2p = GetPoint(ap2); + p3p = GetPoint(p3); p4p = GetPoint(p4); + + double h1 = GetDistFromInfiniteLine(p1p,p2p, p4p); + double h2 = GetDistFromInfiniteLine(p1p,p2p, p3p); + double diaglen = Dist (p1p, p2p); + + if (diaglen < geometryignoreedgelength) + continue; + rzyl = ComputeCylinderRadius + (n, GetTriangle (NeighbourTrig(i,j)).Normal(), + h1, h2); + + + if (h1 < 1e-3 * diaglen && h2 < 1e-3 * diaglen) + continue; + + if (h1 < 1e-5 * objectsize && h2 < 1e-5 * objectsize) + continue; + + + // rzyl = mindist/(2*sinang); + localh = rzyl / stlparam.resthsurfcurvfac; + if (localh < mincalch) {mincalch = localh;} + if (localh > maxcalch) {maxcalch = localh;} + if (localh < gh) + { + minh.Elem(ap1) = min2(minh.Elem(ap1),localh); + minh.Elem(ap2) = min2(minh.Elem(ap2),localh); + } + + //if (localh < 0.2) {localh = 0.2;} + + if(localh < objectsize) + mesh.RestrictLocalHLine(p1p, p2p, localh); + (*testout) << "restrict h along " << p1p << " - " << p2p << " to " << localh << endl; + + if (localh < 0.1) + { + localh = 0.1; + } + + } + } + PrintMessage(7, "done\nmin local h=", mincalch, "\nmax local h=", maxcalch); + PopStatus(); + } + + if (stlparam.resthcloseedgeenable) + { + PushStatusF("Restrict H due to close edges"); + //geht nicht für spiralen!!!!!!!!!!!!!!!!!! + + double disttohfact = sqr(10.0 / stlparam.resthcloseedgefac); + int k,l; + double h1, h2, dist; + int rc = 0; + Point3d p3p1; + double mindist = 1E50; + + PrintMessage(7,"build search tree..."); + Box3dTree* lsearchtree = new Box3dTree (GetBoundingBox().PMin() - Vec3d(1,1,1), + GetBoundingBox().PMax() + Vec3d(1,1,1)); + + Array pmins(GetNLines()); + Array pmaxs(GetNLines()); + + double maxhline; + for (i = 1; i <= GetNLines(); i++) + { + maxhline = 0; + STLLine* l1 = GetLine(i); + Point3d pmin(GetPoint(l1->StartP())), pmax(GetPoint(l1->StartP())), px; + + for (j = 2; j <= l1->NP(); j++) + { + px = GetPoint(l1->PNum(j)); + maxhline = max2(maxhline,mesh.GetH(px)); + pmin.SetToMin (px); + pmax.SetToMax (px); + } + Box3d box(pmin,pmax); + box.Increase(maxhline); + + lsearchtree->Insert (box.PMin(), box.PMax(), i); + pmins.Elem(i) = box.PMin(); + pmaxs.Elem(i) = box.PMax(); + } + + Array linenums; + int k2; + + for (i = 1; i <= GetNLines(); i++) + { + SetThreadPercent((double)i/(double)GetNLines()*100.); + if (multithread.terminate) + {PopStatus(); return;} + + linenums.SetSize(0); + lsearchtree->GetIntersecting(pmins.Get(i),pmaxs.Get(i),linenums); + + STLLine* l1 = GetLine(i); + for (j = 1; j <= l1->NP(); j++) + { + p3p1 = GetPoint(l1->PNum(j)); + h1 = sqr(mesh.GetH(p3p1)); + + for (k2 = 1; k2 <= linenums.Size(); k2++) + { + k = linenums.Get(k2); + if (k <= i) {continue;} + /* + //old, without searchtrees + for (k = i+1; k <= GetNLines(); k++) + { + */ + STLLine* l2 = GetLine(k); + for (l = 1; l <= l2->NP(); l++) + { + const Point3d& p3p2 = GetPoint(l2->PNum(l)); + h2 = sqr(mesh.GetH(p3p2)); + dist = Dist2(p3p1,p3p2)*disttohfact; + if (dist > 1E-12) + { + if (dist < h1) + { + mesh.RestrictLocalH(p3p1,sqrt(dist)); + rc++; + mindist = min2(mindist,sqrt(dist)); + } + if (dist < h2) + { + mesh.RestrictLocalH(p3p2,sqrt(dist)); + rc++; + mindist = min2(mindist,sqrt(dist)); + } + } + } + } + } + } + PrintMessage(5, "done\n Restricted h in ", rc, " points due to near edges!"); + PopStatus(); + } + + if (stlparam.resthedgeangleenable) + { + PushStatusF("Restrict h due to close edges"); + + int lp1, lp2; + Vec3d v1,v2; + mincalch = 1E50; + maxcalch = -1E50; + + for (i = 1; i <= GetNP(); i++) + { + SetThreadPercent((double)i/(double)GetNP()*100.); + if (multithread.terminate) + {PopStatus(); return;} + + if (GetNEPP(i) == 2 && !IsLineEndPoint(i)) + { + if (GetEdge(GetEdgePP(i,1)).PNum(2) == GetEdge(GetEdgePP(i,2)).PNum(1) || + GetEdge(GetEdgePP(i,1)).PNum(1) == GetEdge(GetEdgePP(i,2)).PNum(2)) + { + lp1 = 1; lp2 = 2; + } + else + { + lp1 = 2; lp2 = 1; + } + + v1 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,1)).PNum(1)), + GetPoint(GetEdge(GetEdgePP(i,1)).PNum(2))); + v2 = Vec3d(GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp1)), + GetPoint(GetEdge(GetEdgePP(i,2)).PNum(lp2))); + + rzyl = ComputeCylinderRadius(v1, v2, v1.Length(), v2.Length()); + + localh = rzyl / stlparam.resthedgeanglefac; + if (localh < mincalch) {mincalch = localh;} + if (localh > maxcalch) {maxcalch = localh;} + + if (localh != 0) + mesh.RestrictLocalH(GetPoint(i), localh); + } + } + PrintMessage(7,"edge-angle min local h=", mincalch, "\nedge-angle max local h=", maxcalch); + PopStatus(); + } + + if (stlparam.resthchartdistenable) + { + PushStatusF("Restrict H due to outer chart distance"); + + // mesh.LocalHFunction().Delete(); + + //berechne minimale distanz von chart zu einem nicht-outerchart-punkt in jedem randpunkt einer chart + + Array acttrigs(GetNT()); //outercharttrigs + acttrigs = 0; + + for (i = 1; i <= GetNOCharts(); i++) + { + SetThreadPercent((double)i/(double)GetNOCharts()*100.); + if (multithread.terminate) + {PopStatus(); return;} + + RestrictHChartDistOneChart(i, acttrigs, mesh, gh, 1., 0.); + } + + PopStatus(); + // NgProfiler::Print(stdout); + } + + if (stlparam.resthlinelengthenable) + { + //restrict h due to short lines + PushStatusF("Restrict H due to line-length"); + + double minhl = 1E50; + double linefact = 1./stlparam.resthlinelengthfac; + double l; + for (i = 1; i <= GetNLines(); i++) + { + SetThreadPercent((double)i/(double)GetNLines()*100.); + if (multithread.terminate) + {PopStatus(); return;} + + l = GetLine(i)->GetLength(points); + + const Point3d& pp1 = GetPoint(GetLine(i)->StartP()); + const Point3d& pp2 = GetPoint(GetLine(i)->EndP()); + + if (l != 0) + { + minhl = min2(minhl,l*linefact); + + mesh.RestrictLocalH(pp1, l*linefact); + mesh.RestrictLocalH(pp2, l*linefact); + } + } + PopStatus(); + PrintMessage(5, "minh due to line length=", minhl); + } +} + +void STLGeometry :: RestrictHChartDistOneChart(int chartnum, Array& acttrigs, + class Mesh & mesh, double gh, double fact, double minh) +{ + static int timer1 = NgProfiler::CreateTimer ("restrictH OneChart 1"); + static int timer2 = NgProfiler::CreateTimer ("restrictH OneChart 2"); + static int timer3 = NgProfiler::CreateTimer ("restrictH OneChart 3"); + static int timer3a = NgProfiler::CreateTimer ("restrictH OneChart 3a"); + static int timer3b = NgProfiler::CreateTimer ("restrictH OneChart 3b"); + + NgProfiler::StartTimer (timer1); + double limessafety = stlparam.resthchartdistfac*fact; // original: 2 + double localh; + + // mincalch = 1E10; + //maxcalch = -1E10; + Array limes1; + Array limes2; + + Array plimes1; + Array plimes2; + + Array plimes1trigs; //check from wich trig the points come + Array plimes2trigs; + + Array plimes1origin; //either the original pointnumber or zero, if new point + + int divisions = 10; + + int np1, np2; + // Point3d p3p1, p3p2; + STLTriangle tt; + + limes1.SetSize(0); + limes2.SetSize(0); + plimes1.SetSize(0); + plimes2.SetSize(0); + plimes1trigs.SetSize(0); + plimes2trigs.SetSize(0); + plimes1origin.SetSize(0); + + STLChart& chart = GetChart(chartnum); + chart.ClearOLimit(); + chart.ClearILimit(); + + for (int j = 1; j <= chart.GetNChartT(); j++) + { + int t = chart.GetChartTrig(j); + tt = GetTriangle(t); + for (int k = 1; k <= 3; k++) + { + int nt = NeighbourTrig(t,k); + if (GetChartNr(nt) != chartnum) + { + tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); + if (!IsEdge(np1,np2) && !GetSpiralPoint(np1) && !GetSpiralPoint(np2)) + { + Point3d p3p1 = GetPoint(np1); + Point3d p3p2 = GetPoint(np2); + if (AddIfNotExists(limes1,np1)) + { + plimes1.Append(p3p1); + plimes1trigs.Append(t); + plimes1origin.Append(np1); + } + if (AddIfNotExists(limes1,np2)) + { + plimes1.Append(p3p2); + plimes1trigs.Append(t); + plimes1origin.Append(np2); + } + chart.AddILimit(twoint(np1,np2)); + + for (int di = 1; di <= divisions; di++) + { + double f1 = (double)di/(double)(divisions+1.); + double f2 = (divisions+1.-(double)di)/(double)(divisions+1.); + + plimes1.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2, + p3p1.Y()*f1+p3p2.Y()*f2, + p3p1.Z()*f1+p3p2.Z()*f2)); + plimes1trigs.Append(t); + plimes1origin.Append(0); + } + } + } + } + } + + NgProfiler::StopTimer (timer1); + + NgProfiler::StartTimer (timer2); + for (int j = 1; j <= chart.GetNT(); j++) + acttrigs.Elem(chart.GetTrig(j)) = chartnum; + + for (int j = 1; j <= chart.GetNOuterT(); j++) + { + int t = chart.GetOuterTrig(j); + tt = GetTriangle(t); + for (int k = 1; k <= 3; k++) + { + int nt = NeighbourTrig(t,k); + if (acttrigs.Get(nt) != chartnum) + { + tt.GetNeighbourPoints(GetTriangle(nt),np1,np2); + + if (!IsEdge(np1,np2)) + { + Point3d p3p1 = GetPoint(np1); + Point3d p3p2 = GetPoint(np2); + + if (AddIfNotExists(limes2,np1)) {plimes2.Append(p3p1); plimes2trigs.Append(t);} + if (AddIfNotExists(limes2,np2)) {plimes2.Append(p3p2); plimes2trigs.Append(t);} + chart.AddOLimit(twoint(np1,np2)); + + for (int di = 1; di <= divisions; di++) + { + double f1 = (double)di/(double)(divisions+1.); + double f2 = (divisions+1.-(double)di)/(double)(divisions+1.); + + plimes2.Append(Point3d(p3p1.X()*f1+p3p2.X()*f2, + p3p1.Y()*f1+p3p2.Y()*f2, + p3p1.Z()*f1+p3p2.Z()*f2)); + plimes2trigs.Append(t); + } + } + } + } + } + + NgProfiler::StopTimer (timer2); + NgProfiler::StartTimer (timer3); + + double chartmindist = 1E50; + + if (plimes2.Size()) + { + NgProfiler::StartTimer (timer3a); + Box3d bbox; + bbox.SetPoint (plimes2.Get(1)); + for (int j = 2; j <= plimes2.Size(); j++) + bbox.AddPoint (plimes2.Get(j)); + Point3dTree stree(bbox.PMin(), bbox.PMax()); + for (int j = 1; j <= plimes2.Size(); j++) + stree.Insert (plimes2.Get(j), j); + Array foundpts; + + NgProfiler::StopTimer (timer3a); + NgProfiler::StartTimer (timer3b); + + for (int j = 1; j <= plimes1.Size(); j++) + { + double mindist = 1E50; + + const Point3d & ap1 = plimes1.Get(j); + double boxs = mesh.GetH (plimes1.Get(j)) * limessafety; + + Point3d pmin = ap1 - Vec3d (boxs, boxs, boxs); + Point3d pmax = ap1 + Vec3d (boxs, boxs, boxs); + + stree.GetIntersecting (pmin, pmax, foundpts); + + + for (int kk = 1; kk <= foundpts.Size(); kk++) + { + int k = foundpts.Get(kk); + double dist = Dist2(plimes1.Get(j),plimes2.Get(k)); + if (dist < mindist) mindist = dist; + } + + /* + const Point3d & ap1 = plimes1.Get(j); + double his = mesh.GetH (plimes1.Get(j)); + + double xmin = ap1.X() - his * limessafety; + double xmax = ap1.X() + his * limessafety; + double ymin = ap1.Y() - his * limessafety; + double ymax = ap1.Y() + his * limessafety; + double zmin = ap1.Z() - his * limessafety; + double zmax = ap1.Z() + his * limessafety; + + for (k = 1; k <= plimes2.Size(); k++) + { + const Point3d & ap2 = plimes2.Get(k); + if (ap2.X() >= xmin && ap2.X() <= xmax && + ap2.Y() >= ymin && ap2.Y() <= ymax && + ap2.Z() >= zmin && ap2.Z() <= zmax) + { + dist = Dist2(plimes1.Get(j),plimes2.Get(k)); + if (dist < mindist) + { + mindist = dist; + } + } + } + */ + mindist = sqrt(mindist); + localh = mindist/limessafety; + + if (localh < minh && localh != 0) {localh = minh;} //minh is generally 0! (except make atlas) + if (localh < gh && localh > 0) + { + mesh.RestrictLocalH(plimes1.Get(j), localh); + // if (mindist < mincalch) {mincalch = mindist;} + // if (mindist > maxcalch) {maxcalch = mindist;} + if (mindist < chartmindist) {chartmindist = mindist;} + } + } + NgProfiler::StopTimer (timer3b); + } + NgProfiler::StopTimer (timer3); +} + + +int STLMeshingDummy (STLGeometry* stlgeometry, Mesh*& mesh, MeshingParameters & mparam, + int perfstepsstart, int perfstepsend) +{ + if (perfstepsstart > perfstepsend) return 0; + + multithread.terminate = 0; + int success = 1; + //int trialcntouter = 0; + + if (perfstepsstart <= MESHCONST_MESHEDGES) + { + + mesh = new Mesh(); + mesh->geomtype = Mesh::GEOM_STL; + + mesh -> SetGlobalH (mparam.maxh); + mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), + stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), + mparam.grading); + mesh -> LoadLocalMeshSize (mparam.meshsizefilename); + + success = 0; + + //mesh->DeleteMesh(); + + STLMeshing (*stlgeometry, *mesh); + + stlgeometry->edgesfound = 1; + stlgeometry->surfacemeshed = 0; + stlgeometry->surfaceoptimized = 0; + stlgeometry->volumemeshed = 0; + } + + if (multithread.terminate) + return 0; + + if (perfstepsstart <= MESHCONST_MESHSURFACE && + perfstepsend >= MESHCONST_MESHSURFACE) + { + + if (!stlgeometry->edgesfound) + { + PrintUserError("You have to do 'analyse geometry' first!!!"); + return 0; + } + if (stlgeometry->surfacemeshed || stlgeometry->surfacemeshed) + { + PrintUserError("Already meshed. Please start again with 'Analyse Geometry'!!!"); + return 0; + } + + success = 0; + int retval = STLSurfaceMeshing (*stlgeometry, *mesh); + if (retval == MESHING3_OK) + { + PrintMessage(3,"Success !!!!"); + stlgeometry->surfacemeshed = 1; + stlgeometry->surfaceoptimized = 0; + stlgeometry->volumemeshed = 0; + success = 1; + } + else if (retval == MESHING3_OUTERSTEPSEXCEEDED) + { + PrintError("Give up because of too many trials. Meshing aborted!"); + } + else if (retval == MESHING3_TERMINATE) + { + PrintWarning("Meshing Stopped by user!"); + } + else + { + PrintError("Surface meshing not successful. Meshing aborted!"); + } + +#ifdef STAT_STREAM + (*statout) << mesh->GetNSeg() << " & " << endl + << mesh->GetNSE() << " & " << endl + << GetTime() << " & "; +#endif + } + if (multithread.terminate) + return 0; + + if (success) + { + if (perfstepsstart <= MESHCONST_OPTSURFACE && + perfstepsend >= MESHCONST_OPTSURFACE) + { + if (!stlgeometry->edgesfound) + { + PrintUserError("You have to do 'meshing->analyse geometry' first!!!"); + return 0; + } + if (!stlgeometry->surfacemeshed) + { + PrintUserError("You have to do 'meshing->mesh surface' first!!!"); + return 0; + } + if (stlgeometry->volumemeshed) + { + PrintWarning("Surface optimization with meshed volume is dangerous!!!"); + } + + /* + if (!optstring || strlen(optstring) == 0) + { + mparam.optimize2d = "smcm"; + } + else + { + mparam.optimize2d = optstring; + } + */ + + STLSurfaceOptimization (*stlgeometry, *mesh, mparam); + + if (stlparam.recalc_h_opt) + { + mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), + stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), + mparam.grading); + mesh -> LoadLocalMeshSize (mparam.meshsizefilename); + mesh -> CalcLocalHFromSurfaceCurvature (mparam.grading, + stlparam.resthsurfmeshcurvfac); + mparam.optimize2d = "cmsmSm"; + STLSurfaceOptimization (*stlgeometry, *mesh, mparam); +#ifdef STAT_STREAM + (*statout) << GetTime() << " & "; +#endif + + extern void Render(); + Render(); + } + stlgeometry->surfaceoptimized = 1; + } + if (multithread.terminate) + return 0; + + if (perfstepsstart <= MESHCONST_MESHVOLUME && + perfstepsend >= MESHCONST_MESHVOLUME) + { + if (stlgeometry->volumemeshed) + { + PrintUserError("Volume already meshed!"); return 0; + } + + if (!stlgeometry->edgesfound) + { + PrintUserError("You have to do 'meshing->analyse geometry' first!!!"); + return 0; + } + if (!stlgeometry->surfacemeshed) + { + PrintUserError("You have to do 'meshing->mesh surface' first!!!"); + return 0; + } + if (!stlgeometry->surfaceoptimized) + { + PrintWarning("You should do 'meshing->optimize surface' first!!!"); + } + + + PrintMessage(5,"Check Overlapping boundary: "); + mesh->FindOpenElements(); + mesh->CheckOverlappingBoundary(); + PrintMessage(5,""); + + + if (stlparam.recalc_h_opt) + { + mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), + stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), + mparam.grading); + mesh -> LoadLocalMeshSize (mparam.meshsizefilename); + mesh -> CalcLocalH (mparam.grading); + } + + + PrintMessage(5,"Volume meshing"); + int retval = MeshVolume (mparam, *mesh); + if (retval == MESHING3_OK) + { + RemoveIllegalElements(*mesh); + stlgeometry->volumemeshed = 1; + } + else if (retval == MESHING3_OUTERSTEPSEXCEEDED) + { + PrintError("Give up because of too many trials. Meshing aborted!"); + return 0; + } + else if (retval == MESHING3_TERMINATE) + { + PrintWarning("Meshing Stopped by user!"); + } + else + { + PrintError("Volume meshing not successful. Meshing aborted!"); + return 0; + } + +#ifdef STAT_STREAM + (*statout) << GetTime() << " & " << endl; +#endif + MeshQuality3d (*mesh); + } + + if (multithread.terminate) + return 0; + + if (perfstepsstart <= MESHCONST_OPTVOLUME && + perfstepsend >= MESHCONST_OPTVOLUME) + { + if (!stlgeometry->edgesfound) + { + PrintUserError("You have to do 'meshing->analyse geometry' first!!!"); + return 0; + } + if (!stlgeometry->surfacemeshed) + { + PrintUserError("You have to do 'meshing->mesh surface' first!!!"); + return 0; + } + if (!stlgeometry->volumemeshed) + { + PrintUserError("You have to do 'meshing->mesh volume' first!!!"); + return 0; + } + + /* + if (!optstring || strlen(optstring) == 0) + { + mparam.optimize3d = "cmdmstm"; + } + else + { + mparam.optimize3d = optstring; + } + */ + + OptimizeVolume (mparam, *mesh); + +#ifdef STAT_STREAM + (*statout) << GetTime() << " & " << endl; + (*statout) << mesh->GetNE() << " & " << endl + << mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl; +#endif + + extern void Render(); + Render(); + } + } + + + return 0; +} + + + +} diff --git a/libsrc/stlgeom/stlline.cpp b/libsrc/stlgeom/stlline.cpp new file mode 100644 index 00000000..9a49b748 --- /dev/null +++ b/libsrc/stlgeom/stlline.cpp @@ -0,0 +1,798 @@ +#include + +#include +#include +#include + +#include + +#include "stlgeom.hpp" + +namespace netgen +{ + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//++++++++++++++ EDGE DATA ++++++++++++++++++++++++++++++++++++++++++ +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +/* +void STLEdgeData :: Write(ofstream& of) const +{ + of // << angle << " " + << p1 << " " + << p2 << " " + << lt << " " + << rt << " " + // << status + << endl; +} + +void STLEdgeData :: Read(ifstream& ifs) +{ + // ifs >> angle; + ifs >> p1; + ifs >> p2; + ifs >> lt; + ifs >> rt; + // ifs >> status; +} + + +int STLEdgeData :: GetStatus () const +{ + if (topedgenr <= 0 || topedgenr > top->GetNTE()) return 0; + return top->GetTopEdge (topedgenr).GetStatus(); +} + +void STLEdgeData ::SetStatus (int stat) +{ + if (topedgenr >= 1 && topedgenr <= top->GetNTE()) + top->GetTopEdge (topedgenr).SetStatus(stat); +} + + +float STLEdgeData :: CosAngle() const +{ + return top->GetTopEdge (topedgenr).CosAngle(); +} + + + +void STLEdgeDataList :: ResetAll() +{ + int i; + for (i = 1; i <= edgedata.Size(); i++) + { + edgedata.Elem(i).SetUndefined(); + } +} + +void STLEdgeDataList :: ResetCandidates() +{ + int i; + for (i = 1; i <= edgedata.Size(); i++) + { + if (edgedata.Get(i).Candidate()) + {edgedata.Elem(i).SetUndefined();} + } +} + +int STLEdgeDataList :: GetNConfEdges() const +{ + int i; + int cnt = 0; + for (i = 1; i <= edgedata.Size(); i++) + { + if (edgedata.Get(i).Confirmed()) {cnt++;} + } + return cnt; +} + +void STLEdgeDataList :: ConfirmCandidates() +{ + int i; + for (i = 1; i <= edgedata.Size(); i++) + { + if (edgedata.Get(i).Candidate()) + {edgedata.Elem(i).SetConfirmed();} + } +} + +int STLEdgeDataList :: GetEdgeNum(int np1, int np2) const +{ + INDEX_2 ed(np1,np2); + ed.Sort(); + if (hashtab.Used(ed)) + { + return hashtab.Get(ed); + } + +// int i; +// for (i = 1; i <= Size(); i++) +// { +// if ((Get(i).p1 == np1 && Get(i).p2 == np2) || +// (Get(i).p2 == np1 && Get(i).p1 == np2)) +// { +// return i; +// } +// } + + return 0; +} + +const STLEdgeDataList& STLEdgeDataList :: operator=(const STLEdgeDataList& edl) +{ + int i; + SetSize(edl.Size()); + for (i = 1; i <= Size(); i++) + { + Add(edl.Get(i), i); + } + return *this; +} + +void STLEdgeDataList :: Add(const STLEdgeData& ed, int i) +{ + INDEX_2 edge(ed.p1,ed.p2); + edge.Sort(); + hashtab.Set(edge, i); + Elem(i) = ed; + AddEdgePP(ed.p1,i); + AddEdgePP(ed.p2,i); +} + +void STLEdgeDataList :: Write(ofstream& of) const +{ + of.precision(16); + int i; + of << Size() << endl; + + for (i = 1; i <= Size(); i++) + { + Get(i).Write(of); + } +} + +void STLEdgeDataList :: Read(ifstream& ifs) +{ + int i,n; + ifs >> n; + + SetSize(n); + STLEdgeData ed; + for (i = 1; i <= n; i++) + { + ed.Read(ifs); + Add(ed,i); + } +} + +int STLEdgeDataList :: GetNEPPStat(int p, int status) const +{ + int i; + int cnt = 0; + for (i = 1; i <= GetNEPP(p); i++) + { + if (Get(GetEdgePP(p,i)).GetStatus() == status) + { + cnt++; + } + } + return cnt; +} + +int STLEdgeDataList :: GetNConfCandEPP(int p) const +{ + int i; + int cnt = 0; + for (i = 1; i <= GetNEPP(p); i++) + { + if (Get(GetEdgePP(p,i)).ConfCand()) + { + cnt++; + } + } + return cnt; +} + + +void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, Array& line) +{ + int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); + + int found, pstart, p, en, pnew, ennew; + int closed = 0; + int j, i; + for (j = 1; j <= 2; j++) + { + if (j == 1) {p = ep1;} + if (j == 2) {p = ep2;} + + pstart = p; + en = GetEdgeNum(ep1,ep2); + + found = 1; + while (found && !closed) + { + found = 0; + + if (GetNEPPStat(p,status) == 2) + { + for (i = 1; i <= GetNEPP(p); i++) + { + const STLEdgeData& e = Get(GetEdgePP(p,i)); + if (GetEdgePP(p,i) != en && e.GetStatus() == status) + { + if (e.p1 == p) + {pnew = e.p2;} + else + {pnew = e.p1;} + + ennew = GetEdgePP(p,i); + } + } + if (pnew == pstart) {closed = 1;} + else + { + line.Append(twoint(p,pnew)); + p = pnew; + en = ennew; + found = 1; + } + } + } + } + +} +*/ + + + + +STLEdgeDataList :: STLEdgeDataList (STLTopology & ageom) + : geom(ageom) +{ + ; +} + +STLEdgeDataList :: ~STLEdgeDataList() +{ + ; +} + + +void STLEdgeDataList :: Store () +{ + int i, ne = geom.GetNTE(); + storedstatus.SetSize(ne); + for (i = 1; i <= ne; i++) + { + storedstatus.Elem(i) = Get(i).GetStatus(); + } +} + +void STLEdgeDataList :: Restore () +{ + int i, ne = geom.GetNTE(); + if (storedstatus.Size() == ne) + for (i = 1; i <= ne; i++) + geom.GetTopEdge(i).SetStatus (storedstatus.Elem(i)); +} + + +void STLEdgeDataList :: ResetAll() +{ + int i, ne = geom.GetNTE(); + for (i = 1; i <= ne; i++) + geom.GetTopEdge (i).SetStatus (ED_UNDEFINED); +} + +int STLEdgeDataList :: GetNConfEdges() const +{ + int i, ne = geom.GetNTE(); + int cnt = 0; + for (i = 1; i <= ne; i++) + if (geom.GetTopEdge (i).GetStatus() == ED_CONFIRMED) + cnt++; + return cnt; +} + +void STLEdgeDataList :: ChangeStatus(int status1, int status2) +{ + int i, ne = geom.GetNTE(); + for (i = 1; i <= ne; i++) + if (geom.GetTopEdge (i).GetStatus() == status1) + geom.GetTopEdge (i).SetStatus (status2); +} + +/* +void STLEdgeDataList :: Add(const STLEdgeData& ed, int i) +{ + INDEX_2 edge(ed.p1,ed.p2); + edge.Sort(); + hashtab.Set(edge, i); + Elem(i) = ed; + AddEdgePP(ed.p1,i); + AddEdgePP(ed.p2,i); +} +*/ + +void STLEdgeDataList :: Write(ofstream& of) const +{ + + /* + of.precision(16); + int i; + of << Size() << endl; + + for (i = 1; i <= Size(); i++) + { + Get(i).Write(of); + } + + */ + of.precision(16); + int i, ne = geom.GetNTE(); + //of << GetNConfEdges() << endl; + of << geom.GetNTE() << endl; + + for (i = 1; i <= ne; i++) + { + const STLTopEdge & edge = geom.GetTopEdge(i); + //if (edge.GetStatus() == ED_CONFIRMED) + of << edge.GetStatus() << " "; + + const Point3d & p1 = geom.GetPoint (edge.PNum(1)); + const Point3d & p2 = geom.GetPoint (edge.PNum(2)); + of << p1.X() << " " + << p1.Y() << " " + << p1.Z() << " " + << p2.X() << " " + << p2.Y() << " " + << p2.Z() << endl; + } + +} + +void STLEdgeDataList :: Read(ifstream& ifs) +{ + int i, nce; + Point3d p1, p2; + int pi1, pi2; + int status, ednum; + + ifs >> nce; + for (i = 1; i <= nce; i++) + { + ifs >> status; + ifs >> p1.X() >> p1.Y() >> p1.Z(); + ifs >> p2.X() >> p2.Y() >> p2.Z(); + + pi1 = geom.GetPointNum (p1); + pi2 = geom.GetPointNum (p2); + ednum = geom.GetTopEdgeNum (pi1, pi2); + + + if (ednum) + { + geom.GetTopEdge(ednum).SetStatus (status); + // geom.GetTopEdge (ednum).SetStatus (ED_CONFIRMED); + } + } + /* + int i,n; + ifs >> n; + + SetSize(n); + STLEdgeData ed; + for (i = 1; i <= n; i++) + { + ed.Read(ifs); + Add(ed,i); + } + */ +} + +int STLEdgeDataList :: GetNEPPStat(int p, int status) const +{ + int i; + int cnt = 0; + for (i = 1; i <= GetNEPP(p); i++) + { + if (Get(GetEdgePP(p,i)).GetStatus() == status) + { + cnt++; + } + } + return cnt; +} + +int STLEdgeDataList :: GetNConfCandEPP(int p) const +{ + int i; + int cnt = 0; + for (i = 1; i <= GetNEPP(p); i++) + { + if (Get(GetEdgePP(p,i)).GetStatus() == ED_CANDIDATE || + Get(GetEdgePP(p,i)).GetStatus() == ED_CONFIRMED) + { + cnt++; + } + } + return cnt; +} + + +void STLEdgeDataList :: BuildLineWithEdge(int ep1, int ep2, Array& line) +{ + int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); + + int found, pstart, p(0), en, pnew(0), ennew(0); + int closed = 0; + int j, i; + for (j = 1; j <= 2; j++) + { + if (j == 1) {p = ep1;} + if (j == 2) {p = ep2;} + + pstart = p; + en = GetEdgeNum(ep1,ep2); + + found = 1; + while (found && !closed) + { + found = 0; + + if (GetNEPPStat(p,status) == 2) + { + for (i = 1; i <= GetNEPP(p); i++) + { + const STLTopEdge & e = Get(GetEdgePP(p,i)); + if (GetEdgePP(p,i) != en && e.GetStatus() == status) + { + if (e.PNum(1) == p) + {pnew = e.PNum(2);} + else + {pnew = e.PNum(1);} + + ennew = GetEdgePP(p,i); + } + } + if (pnew == pstart) {closed = 1;} + else + { + line.Append(twoint(p,pnew)); + p = pnew; + en = ennew; + found = 1; + } + } + } + } + +} + +int Exists(int p1, int p2, const Array& line) +{ + int i; + for (i = 1; i <= line.Size(); i++) + { + if ( (line.Get(i).i1 == p1 && line.Get(i).i2 == p2) || + (line.Get(i).i1 == p2 && line.Get(i).i2 == p1) ) + {return 1;} + } + return 0; +} + +void STLEdgeDataList :: BuildClusterWithEdge(int ep1, int ep2, Array& line) +{ + int status = Get(GetEdgeNum(ep1,ep2)).GetStatus(); + + int p(0), en; + int j, i, k; + int oldend; + int newend = 1; + int pnew, ennew(0); + + int changed = 1; + while (changed) + { + changed = 0; + for (j = 1; j <= 2; j++) + { + oldend = newend; + newend = line.Size(); + for (k = oldend; k <= line.Size(); k++) + { + if (j == 1) p = line.Get(k).i1; + if (j == 2) p = line.Get(k).i2; + en = GetEdgeNum(line.Get(k).i1, line.Get(k).i2); + + for (i = 1; i <= GetNEPP(p); i++) + { + pnew = 0; + const STLTopEdge & e = Get(GetEdgePP(p,i)); + if (GetEdgePP(p,i) != en && e.GetStatus() == status) + { + if (e.PNum(1) == p) + {pnew = e.PNum(2);} + else + {pnew = e.PNum(1);} + + ennew = GetEdgePP(p,i); + } + if (pnew && !Exists(p,pnew,line)) + { + changed = 1; + line.Append(twoint(p,pnew)); + p = pnew; + en = ennew; + } + } + + } + } + + } + +} + + + + + + + + + + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//+++++++++++++++++++ STL LINE +++++++++++++++++++++++++++++++ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +STLLine :: STLLine(const STLGeometry * ageometry) + : pts(), lefttrigs(), righttrigs() +{ + geometry = ageometry; + split = 0; +}; + +int STLLine :: GetNS() const +{ + if (pts.Size() <= 1) {return 0;} + return pts.Size()-1; +} +void STLLine :: GetSeg(int nr, int& p1, int& p2) const +{ + p1 = pts.Get(nr); + p2 = pts.Get(nr+1); +} + +int STLLine :: GetLeftTrig(int nr) const +{ + if (nr > lefttrigs.Size()) {PrintSysError("In STLLine::GetLeftTrig!!!"); return 0;} + return lefttrigs.Get(nr); +}; + +int STLLine :: GetRightTrig(int nr) const +{ + if (nr > righttrigs.Size()) {PrintSysError("In STLLine::GetRightTrig!!!"); return 0;} + return righttrigs.Get(nr); +}; + +double STLLine :: GetSegLen(const Array >& ap, int nr) const +{ + return Dist(ap.Get(PNum(nr)),ap.Get(PNum(nr+1))); +} + +double STLLine :: GetLength(const Array >& ap) const +{ + double len = 0; + for (int i = 2; i <= pts.Size(); i++) + { + len += (ap.Get(pts.Get(i)) - ap.Get(pts.Get(i-1))).Length(); + } + return len; +} + +void STLLine :: GetBoundingBox (const Array > & ap, Box<3> & box) const +{ + box.Set (ap.Get (pts[0])); + for (int i = 1; i < pts.Size(); i++) + box.Add (ap.Get(pts[i])); +} + + + +Point<3> STLLine :: +GetPointInDist(const Array >& ap, double dist, int& index) const +{ + if (dist <= 0) + { + index = 1; + return ap.Get(StartP()); + } + + double len = 0; + int i; + for (i = 1; i < pts.Size(); i++) + { + double seglen = Dist (ap.Get(pts.Get(i)), + ap.Get(pts.Get(i+1))); + + if (len + seglen > dist) + { + index = i; + double relval = (dist - len) / (seglen + 1e-16); + Vec3d v (ap.Get(pts.Get(i)), ap.Get(pts.Get(i+1))); + return ap.Get(pts.Get(i)) + relval * v; + } + + len += seglen; + } + + index = pts.Size() - 1; + return ap.Get(EndP()); +} + + +/* +double stlgh; +double GetH(const Point3d& p, double x) +{ + return stlgh;//+0.5)*(x+0.5); +} +*/ +STLLine* STLLine :: Mesh(const Array >& ap, + Array& mp, double ghi, + class Mesh& mesh) const +{ + static int timer1a = NgProfiler::CreateTimer ("mesh stl-line 1a"); + static int timer1b = NgProfiler::CreateTimer ("mesh stl-line 1b"); + static int timer2 = NgProfiler::CreateTimer ("mesh stl-line 2"); + static int timer3 = NgProfiler::CreateTimer ("mesh stl-line 3"); + + NgProfiler::StartTimer (timer1a); + + STLLine* line = new STLLine(geometry); + + //stlgh = ghi; //uebergangsloesung!!!! + + double len = GetLength(ap); + double inthl = 0; //integral of 1/h + double dist = 0; + double h; + int ind; + Point3d p; + + Box<3> bbox; + GetBoundingBox (ap, bbox); + double diam = bbox.Diam(); + + double minh = mesh.LocalHFunction().GetMinH (bbox.PMin(), bbox.PMax()); + + double maxseglen = 0; + for (int i = 1; i <= GetNS(); i++) + maxseglen = max2 (maxseglen, GetSegLen (ap, i)); + + int nph = 10+int(maxseglen / minh); //anzahl der integralauswertungen pro segment + + Array inthi(GetNS()*nph); + Array curvelen(GetNS()*nph); + + NgProfiler::StopTimer (timer1a); + NgProfiler::StartTimer (timer1b); + + + for (int i = 1; i <= GetNS(); i++) + { + //double seglen = GetSegLen(ap,i); + for (int j = 1; j <= nph; j++) + { + p = GetPointInDist(ap,dist,ind); + //h = GetH(p,dist/len); + h = mesh.GetH(p); + + + dist += GetSegLen(ap,i)/(double)nph; + + inthl += GetSegLen(ap,i)/nph/(h); + inthi.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph/h; + curvelen.Elem((i-1)*nph+j) = GetSegLen(ap,i)/nph; + } + } + + + int inthlint = int(inthl+1); + + if ( (inthlint < 3) && (StartP() == EndP())) + { + inthlint = 3; + } + if ( (inthlint == 1) && ShouldSplit()) + { + inthlint = 2; + } + + double fact = inthl/(double)inthlint; + dist = 0; + int j = 1; + + + p = ap.Get(StartP()); + int pn = AddPointIfNotExists(mp, p, 1e-10*diam); + + int segn = 1; + line->AddPoint(pn); + line->AddLeftTrig(GetLeftTrig(segn)); + line->AddRightTrig(GetRightTrig(segn)); + line->AddDist(dist); + + NgProfiler::StopTimer (timer1b); + NgProfiler::StartTimer (timer2); + + inthl = 0; //restart each meshseg + for (int i = 1; i <= inthlint; i++) + { + while (inthl < 1.000000001 && j <= inthi.Size()) + { + inthl += inthi.Get(j)/fact; + dist += curvelen.Get(j); + j++; + } + + //went too far: + j--; + double tofar = (inthl - 1)/inthi.Get(j); + inthl -= tofar*inthi.Get(j); + dist -= tofar*curvelen.Get(j)*fact; + + if (i == inthlint && fabs(dist - len) >= 1E-8) + { + PrintSysError("meshline failed!!!"); + } + + if (i != inthlint) + { + p = GetPointInDist(ap,dist,ind); + pn = AddPointIfNotExists(mp, p, 1e-10*diam); + segn = ind; + line->AddPoint(pn); + line->AddLeftTrig(GetLeftTrig(segn)); + line->AddRightTrig(GetRightTrig(segn)); + line->AddDist(dist); + } + + inthl = tofar*inthi.Get(j); + dist += tofar*curvelen.Get(j)*fact; + j++; + } + + NgProfiler::StopTimer (timer2); + NgProfiler::StartTimer (timer3); + + + p = ap.Get(EndP()); + pn = AddPointIfNotExists(mp, p, 1e-10*diam); + segn = GetNS(); + line->AddPoint(pn); + line->AddLeftTrig(GetLeftTrig(segn)); + line->AddRightTrig(GetRightTrig(segn)); + line->AddDist(dist); + + for (int ii = 1; ii <= line->GetNS(); ii++) + { + int p1, p2; + line->GetSeg(ii,p1,p2); + } + /* + (*testout) << "line, " << ap.Get(StartP()) << "-" << ap.Get(EndP()) + << " len = " << Dist (ap.Get(StartP()), ap.Get(EndP())) << endl; + */ + + NgProfiler::StopTimer (timer3); + + return line; +} +} diff --git a/libsrc/stlgeom/stlline.hpp b/libsrc/stlgeom/stlline.hpp new file mode 100644 index 00000000..06ce5857 --- /dev/null +++ b/libsrc/stlgeom/stlline.hpp @@ -0,0 +1,188 @@ +#ifndef FILE_STLLINE +#define FILE_STLLINE + + +/**************************************************************************/ +/* File: stlline.hh */ +/* Author: Joachim Schoeberl */ +/* Author2: Johannes Gerstmayr */ +/* Date: 20. Nov. 99 */ +/**************************************************************************/ + +class STLGeometry; +class STLTopology; + +class STLEdge +{ +public: + int pts[2]; + int trigs[2]; //left and right trig + + STLEdge (const int * apts) {pts[0] = apts[0]; pts[1] = apts[1];} + STLEdge (int v1, int v2) {pts[0] = v1; pts[1] = v2;} + STLEdge () {pts[0]=0;pts[1]=0;} + int PNum(int i) const {return pts[(i-1)];} + + int LeftTrig() const {return trigs[0];} + int RightTrig() const {return trigs[1];} + void SetLeftTrig(int i) {trigs[0] = i;} + void SetRightTrig(int i) {trigs[1] = i;} +}; + +enum STL_ED_STATUS { ED_EXCLUDED, ED_CONFIRMED, ED_CANDIDATE, ED_UNDEFINED }; + + +/* + +class STLEdgeData +{ +public: + // float angle; + int p1; + int p2; + int lt; //left trig + int rt; //right trig + // int status; + + STLTopology * top; // pointer to stl topology + int topedgenr; // number of corresponding topology edge + + STLEdgeData() {}; + STLEdgeData(float anglei, int p1i, int p2i, int lti, int rti) +{ +// angle = anglei; +p1 = p1i; p2 = p2i; + lt = lti; rt = rti; + } + + int GetStatus () const; + void SetStatus (int stat); + + void SetExcluded() { SetStatus (ED_EXCLUDED); } + void SetConfirmed() { SetStatus (ED_CONFIRMED); } + void SetCandidate() { SetStatus (ED_CANDIDATE); } + void SetUndefined() { SetStatus (ED_UNDEFINED); } + + int Excluded() const {return GetStatus() == ED_EXCLUDED;} + int Confirmed() const {return GetStatus() == ED_CONFIRMED;} + int Candidate() const {return GetStatus() == ED_CANDIDATE;} + int Undefined() const {return GetStatus() == ED_UNDEFINED;} + int ConfCand() const {return GetStatus() == ED_CONFIRMED || GetStatus() == ED_CANDIDATE;} + + float CosAngle() const; + + void Write(ofstream& of) const; + void Read(ifstream& ifs); +}; + +class STLEdgeDataList +{ +private: + INDEX_2_HASHTABLE hashtab; + Array edgedata; + TABLE edgesperpoint; + +public: + + STLEdgeDataList():edgedata(),hashtab(1),edgesperpoint() {}; + const STLEdgeDataList& operator=(const STLEdgeDataList& edl); + void SetSize(int size) + { + edgedata.SetSize(size); + hashtab.SetSize(size); + edgesperpoint.SetSize(size); + } + void Clear() {SetSize(0);} + int Size() const {return edgedata.Size();} + const STLEdgeData& Get(int i) const {return edgedata.Get(i);} + STLEdgeData& Elem(int i) {return edgedata.Elem(i);} + void Add(const STLEdgeData& ed, int i); + + int GetNEPP(int pn) const + { + return edgesperpoint.EntrySize(pn); + }; + int GetEdgePP(int pn, int vi) const + { + return edgesperpoint.Get(pn,vi); + }; + void AddEdgePP(int pn, int vn) {edgesperpoint.Add(pn,vn);}; + + void ResetAll(); + void ResetCandidates(); + void ConfirmCandidates(); + int GetEdgeNum(int np1, int np2) const; + + int GetNConfEdges() const; + + void Write(ofstream& of) const; + void Read(ifstream& ifs); + + void BuildLineWithEdge(int ep1, int ep2, Array& line); + + int GetNEPPStat(int p, int status) const; + int GetNConfCandEPP(int p) const; +}; +*/ + + + + + + + + + + + + + + + + +//a line defined by several points (polyline) +class STLLine +{ +private: + const STLGeometry * geometry; + Array pts; + Array lefttrigs; + Array righttrigs; + Array dists; + int split; + +public: + STLLine(const STLGeometry * ageometry); + void AddPoint(int i) {pts.Append(i);} + int PNum(int i) const {return pts.Get(i);} + int NP() const {return pts.Size();} + int GetNS() const; + void GetSeg(int nr, int& p1, int& p2) const; + double GetSegLen(const Array >& ap, int nr) const; + int GetLeftTrig(int nr) const; + int GetRightTrig(int nr) const; + double GetDist(int nr) const { return dists.Get(nr);}; + void GetBoundingBox (const Array > & ap, Box<3> & box) const; + + void AddLeftTrig(int nr) {lefttrigs.Append(nr);} + void AddRightTrig(int nr) {righttrigs.Append(nr);} + void AddDist (double dist) {dists.Append(dist); } + int StartP() const {return pts.Get(1);} + int EndP() const {return pts.Get(pts.Size());} + + double GetLength(const Array >& ap) const; + + //suche punkt in entfernung (in linienkoordinaten) dist + //in index ist letzter punkt VOR dist (d.h. max pts.Size()-1) + Point<3> GetPointInDist(const Array >& ap, double dist, int& index) const; + + //return a meshed polyline + STLLine* Mesh(const Array >& ap, + Array& mp, double ghi, + class Mesh& mesh) const; + + void DoSplit() {split = 1;} + int ShouldSplit() const {return split;} +}; + +#endif diff --git a/libsrc/stlgeom/stlpkg.cpp b/libsrc/stlgeom/stlpkg.cpp new file mode 100644 index 00000000..9423e35f --- /dev/null +++ b/libsrc/stlgeom/stlpkg.cpp @@ -0,0 +1,580 @@ +#include +#include +#include +#include + +#include + + +#include +#include + +#include + +#include "vsstl.hpp" + +extern "C" int Ng_STL_Init (Tcl_Interp * interp); + + + +namespace netgen +{ + extern AutoPtr ng_geometry; + extern AutoPtr mesh; + + static VisualSceneSTLGeometry vsstlgeom; + static VisualSceneSTLMeshing vsstlmeshing; + + char * err_needsstlgeometry = (char*) "This operation needs an STL geometry"; + + + + + + class STLGeometryVisRegister : public GeometryRegister + { + public: + virtual NetgenGeometry * Load (string filename) const { return NULL; } + virtual VisualScene * GetVisualScene (const NetgenGeometry * geom) const; + virtual void SetParameters (Tcl_Interp * interp) + { + stlparam.yangle = + atof (Tcl_GetVar (interp, "::stloptions.yangle", 0)); + stlparam.contyangle = + atof (Tcl_GetVar (interp, "::stloptions.contyangle", 0)); + stlparam.edgecornerangle = + atof (Tcl_GetVar (interp, "::stloptions.edgecornerangle", 0)); + stlparam.chartangle = + atof (Tcl_GetVar (interp, "::stloptions.chartangle", 0)); + stlparam.outerchartangle = + atof (Tcl_GetVar (interp, "::stloptions.outerchartangle", 0)); + + stlparam.usesearchtree = + atoi (Tcl_GetVar (interp, "::stloptions.usesearchtree", 0)); + + + stlparam.atlasminh = + atof (Tcl_GetVar (interp, "::stloptions.atlasminh", 0)); + + stlparam.resthsurfcurvfac = + atof (Tcl_GetVar (interp, "::stloptions.resthsurfcurvfac", 0)); + stlparam.resthsurfcurvenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthsurfcurvenable", 0)); + + stlparam.resthatlasfac = + atof (Tcl_GetVar (interp, "::stloptions.resthatlasfac", 0)); + stlparam.resthatlasenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthatlasenable", 0)); + + stlparam.resthchartdistfac = + atof (Tcl_GetVar (interp, "::stloptions.resthchartdistfac", 0)); + stlparam.resthchartdistenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthchartdistenable", 0)); + + stlparam.resthlinelengthfac = + atof (Tcl_GetVar (interp, "::stloptions.resthlinelengthfac", 0)); + stlparam.resthlinelengthenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthlinelengthenable", 0)); + + stlparam.resthcloseedgefac = + atof (Tcl_GetVar (interp, "::stloptions.resthcloseedgefac", 0)); + stlparam.resthcloseedgeenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthcloseedgeenable", 0)); + + stlparam.resthedgeanglefac = + atof (Tcl_GetVar (interp, "::stloptions.resthedgeanglefac", 0)); + stlparam.resthedgeangleenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthedgeangleenable", 0)); + + stlparam.resthsurfmeshcurvfac = + atof (Tcl_GetVar (interp, "::stloptions.resthsurfmeshcurvfac", 0)); + stlparam.resthsurfmeshcurvenable = + atoi (Tcl_GetVar (interp, "::stloptions.resthsurfmeshcurvenable", 0)); + + stlparam.recalc_h_opt = + atoi (Tcl_GetVar (interp, "::stloptions.recalchopt", 0)); + // stlparam.Print (cout); + } + }; + + + + int Ng_SetSTLParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + STLGeometryVisRegister reg; + reg.SetParameters (interp); + + return TCL_OK; + } + + + + + + + + + int Ng_STLDoctor (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + //cout << "STL doctor" << endl; + STLGeometry * stlgeometry = + dynamic_cast (ng_geometry.Ptr()); + + + stldoctor.drawmeshededges = + atoi (Tcl_GetVar (interp, "::stldoctor.drawmeshededges", 0)); + + stldoctor.geom_tol_fact = + atof (Tcl_GetVar (interp, "::stldoctor.geom_tol_fact", 0)); + + + stldoctor.useexternaledges = + atoi (Tcl_GetVar (interp, "::stldoctor.useexternaledges", 0)); + + stldoctor.showfaces = + atoi (Tcl_GetVar (interp, "::stldoctor.showfaces", 0)); + + stldoctor.conecheck = + atoi (Tcl_GetVar (interp, "::stldoctor.conecheck", 0)); + + stldoctor.spiralcheck = + atoi (Tcl_GetVar (interp, "::stldoctor.spiralcheck", 0)); + + stldoctor.selectwithmouse = + atoi (Tcl_GetVar (interp, "::stldoctor.selectwithmouse", 0)); + + stldoctor.showedgecornerpoints = + atoi (Tcl_GetVar (interp, "::stldoctor.showedgecornerpoints", 0)); + + stldoctor.showmarkedtrigs = + atoi (Tcl_GetVar (interp, "::stldoctor.showmarkedtrigs", 0)); + + stldoctor.showtouchedtrigchart = + atoi (Tcl_GetVar (interp, "::stldoctor.showtouchedtrigchart", 0)); + + //cout << "smt=" << stldoctor.showmarkedtrigs << endl; + + stldoctor.dirtytrigfact = + atof (Tcl_GetVar (interp, "::stldoctor.dirtytrigfact", 0)); + + stldoctor.smoothnormalsweight = + atof (Tcl_GetVar (interp, "::stldoctor.smoothnormalsweight", 0)); + + stldoctor.smoothangle = + atof (Tcl_GetVar (interp, "::stldoctor.smoothangle", 0)); + + stldoctor.selectmode = + atoi (Tcl_GetVar (interp, "::stldoctor.selectmode", 0)); + + stldoctor.edgeselectmode = + atoi (Tcl_GetVar (interp, "::stldoctor.edgeselectmode", 0)); + + stldoctor.longlinefact = + atoi (Tcl_GetVar (interp, "::stldoctor.longlinefact", 0)); + + stldoctor.showexcluded = + atoi (Tcl_GetVar (interp, "::stldoctor.showexcluded", 0)); + + + + if (!stldoctor.selectwithmouse) + { + stldoctor.selecttrig = + atoi (Tcl_GetVar (interp, "::stldoctor.selecttrig", 0)); + + stldoctor.nodeofseltrig = + atoi (Tcl_GetVar (interp, "::stldoctor.nodeofseltrig", 0)); + } + + stldoctor.showvicinity = + atoi (Tcl_GetVar (interp, "::stldoctor.showvicinity", 0)); + + stldoctor.vicinity = + atoi (Tcl_GetVar (interp, "::stldoctor.vicinity", 0)); + + + if (argc >= 2) + { + if (!stlgeometry) + { + Tcl_SetResult (interp, err_needsstlgeometry, TCL_STATIC); + return TCL_ERROR; + } + + if (strcmp (argv[1], "destroy0trigs") == 0) + { + stlgeometry->DestroyDirtyTrigs(); + } + else if (strcmp (argv[1], "movepointtomiddle") == 0) + { + stlgeometry->MoveSelectedPointToMiddle(); + } + else if (strcmp (argv[1], "calcnormals") == 0) + { + stlgeometry->CalcNormalsFromGeometry(); + } + else if (strcmp (argv[1], "showchartnum") == 0) + { + stlgeometry->ShowSelectedTrigChartnum(); + } + else if (strcmp (argv[1], "showcoords") == 0) + { + stlgeometry->ShowSelectedTrigCoords(); + } + else if (strcmp (argv[1], "loadmarkedtrigs") == 0) + { + stlgeometry->LoadMarkedTrigs(); + } + else if (strcmp (argv[1], "savemarkedtrigs") == 0) + { + stlgeometry->SaveMarkedTrigs(); + } + else if (strcmp (argv[1], "neighbourangles") == 0) + { + stlgeometry->NeighbourAnglesOfSelectedTrig(); + } + else if (strcmp (argv[1], "vicinity") == 0) + { + stlgeometry->CalcVicinity(stldoctor.selecttrig); + } + else if (strcmp (argv[1], "markdirtytrigs") == 0) + { + stlgeometry->MarkDirtyTrigs(); + } + else if (strcmp (argv[1], "smoothdirtytrigs") == 0) + { + stlgeometry->SmoothDirtyTrigs(); + } + else if (strcmp (argv[1], "smoothrevertedtrigs") == 0) + { + stlgeometry->GeomSmoothRevertedTrigs(); + } + else if (strcmp (argv[1], "invertselectedtrig") == 0) + { + stlgeometry->InvertTrig(stlgeometry->GetSelectTrig()); + } + else if (strcmp (argv[1], "deleteselectedtrig") == 0) + { + stlgeometry->DeleteTrig(stlgeometry->GetSelectTrig()); + } + else if (strcmp (argv[1], "smoothgeometry") == 0) + { + stlgeometry->SmoothGeometry(); + } + else if (strcmp (argv[1], "orientafterselectedtrig") == 0) + { + stlgeometry->OrientAfterTrig(stlgeometry->GetSelectTrig()); + } + else if (strcmp (argv[1], "marktoperrortrigs") == 0) + { + stlgeometry->MarkTopErrorTrigs(); + } + else if (strcmp (argv[1], "exportedges") == 0) + { + stlgeometry->ExportEdges(); + } + else if (strcmp (argv[1], "importedges") == 0) + { + stlgeometry->ImportEdges(); + } + else if (strcmp (argv[1], "importexternaledges") == 0) + { + stlgeometry->ImportExternalEdges(argv[2]); + } + else if (strcmp (argv[1], "loadedgedata") == 0) + { + if (argc >= 3) + { + stlgeometry->LoadEdgeData(argv[2]); + } + } + else if (strcmp (argv[1], "saveedgedata") == 0) + { + if (argc >= 3) + { + stlgeometry->SaveEdgeData(argv[2]); + } + } + + else if (strcmp (argv[1], "buildexternaledges") == 0) + { + stlgeometry->BuildExternalEdgesFromEdges(); + } + else if (strcmp (argv[1], "smoothnormals") == 0) + { + stlgeometry->SmoothNormals(); + } + else if (strcmp (argv[1], "marknonsmoothnormals") == 0) + { + stlgeometry->MarkNonSmoothNormals(); + } + else if (strcmp (argv[1], "addexternaledge") == 0) + { + stlgeometry->AddExternalEdgeAtSelected(); + } + else if (strcmp (argv[1], "addgeomline") == 0) + { + stlgeometry->AddExternalEdgesFromGeomLine(); + } + else if (strcmp (argv[1], "addlonglines") == 0) + { + stlgeometry->AddLongLinesToExternalEdges(); + } + else if (strcmp (argv[1], "addclosedlines") == 0) + { + stlgeometry->AddClosedLinesToExternalEdges(); + } + else if (strcmp (argv[1], "addnotsinglelines") == 0) + { + stlgeometry->AddAllNotSingleLinesToExternalEdges(); + } + else if (strcmp (argv[1], "deletedirtyexternaledges") == 0) + { + stlgeometry->DeleteDirtyExternalEdges(); + } + else if (strcmp (argv[1], "deleteexternaledge") == 0) + { + stlgeometry->DeleteExternalEdgeAtSelected(); + } + else if (strcmp (argv[1], "deletevicexternaledge") == 0) + { + stlgeometry->DeleteExternalEdgeInVicinity(); + } + + else if (strcmp (argv[1], "addlonglines") == 0) + { + stlgeometry->STLDoctorLongLinesToCandidates(); + } + else if (strcmp (argv[1], "deletedirtyedges") == 0) + { + stlgeometry->STLDoctorDirtyEdgesToCandidates(); + } + else if (strcmp (argv[1], "undoedgechange") == 0) + { + stlgeometry->UndoEdgeChange(); + } + else if (strcmp (argv[1], "buildedges") == 0) + { + stlgeometry->STLDoctorBuildEdges(); + } + else if (strcmp (argv[1], "confirmedge") == 0) + { + stlgeometry->STLDoctorConfirmEdge(); + } + else if (strcmp (argv[1], "candidateedge") == 0) + { + stlgeometry->STLDoctorCandidateEdge(); + } + else if (strcmp (argv[1], "excludeedge") == 0) + { + stlgeometry->STLDoctorExcludeEdge(); + } + else if (strcmp (argv[1], "undefinededge") == 0) + { + stlgeometry->STLDoctorUndefinedEdge(); + } + else if (strcmp (argv[1], "setallundefinededges") == 0) + { + stlgeometry->STLDoctorSetAllUndefinedEdges(); + } + else if (strcmp (argv[1], "erasecandidateedges") == 0) + { + stlgeometry->STLDoctorEraseCandidateEdges(); + } + else if (strcmp (argv[1], "confirmcandidateedges") == 0) + { + stlgeometry->STLDoctorConfirmCandidateEdges(); + } + else if (strcmp (argv[1], "confirmedtocandidateedges") == 0) + { + stlgeometry->STLDoctorConfirmedToCandidateEdges(); + } + } + + return TCL_OK; + } + + + + + + + + + + + + + + + int Ng_STLInfo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + double data[10]; + static char buf[20]; + + STLGeometry * stlgeometry = dynamic_cast (ng_geometry.Ptr()); + + if (!stlgeometry) + { + Tcl_SetResult (interp, err_needsstlgeometry, TCL_STATIC); + return TCL_ERROR; + } + + + + if (stlgeometry) + { + stlgeometry->STLInfo(data); + // cout << "NT=" << data[0] << endl; + + if (argc == 2) + { + if (strcmp (argv[1], "status") == 0) + { + switch (stlgeometry->GetStatus()) + { + case STLGeometry::STL_GOOD: + strcpy (buf, "GOOD"); break; + case STLGeometry::STL_WARNING: + strcpy (buf, "WARNING"); break; + case STLGeometry::STL_ERROR: + strcpy (buf, "ERROR"); break; + } + Tcl_SetResult (interp, buf, TCL_STATIC); + return TCL_OK; + } + if (strcmp (argv[1], "statustext") == 0) + { + Tcl_SetResult (interp, (char*)stlgeometry->GetStatusText().c_str(), TCL_STATIC); + return TCL_OK; + } + if (strcmp (argv[1], "topology_ok") == 0) + { + sprintf (buf, "%d", stlgeometry->Topology_Ok()); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + if (strcmp (argv[1], "orientation_ok") == 0) + { + sprintf (buf, "%d", stlgeometry->Orientation_Ok()); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + } + } + else + { + data[0] = 0; + data[1] = 0; + data[2] = 0; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = 0; + data[7] = 0; + } + + + + + sprintf (buf, "%i", (int)data[0]); + Tcl_SetVar (interp, argv[1], buf, 0); + + sprintf (buf, "%5.3g", data[1]); + Tcl_SetVar (interp, argv[2], buf, 0); + sprintf (buf, "%5.3g", data[2]); + Tcl_SetVar (interp, argv[3], buf, 0); + sprintf (buf, "%5.3g", data[3]); + Tcl_SetVar (interp, argv[4], buf, 0); + + sprintf (buf, "%5.3g", data[4]); + Tcl_SetVar (interp, argv[5], buf, 0); + sprintf (buf, "%5.3g", data[5]); + Tcl_SetVar (interp, argv[6], buf, 0); + sprintf (buf, "%5.3g", data[6]); + Tcl_SetVar (interp, argv[7], buf, 0); + + sprintf (buf, "%i", (int)data[7]); + Tcl_SetVar (interp, argv[8], buf, 0); + + return TCL_OK; + } + + + + extern int Ng_SetMeshingParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); + + int Ng_STLCalcLocalH (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + for (int i = 0; i < geometryregister.Size(); i++) + geometryregister[i] -> SetParameters (interp); + + + Ng_SetMeshingParameters (clientData, interp, argc, argv); + + STLGeometry * stlgeometry = dynamic_cast (ng_geometry.Ptr()); + if (mesh.Ptr() && stlgeometry) + { + mesh -> SetLocalH (stlgeometry->GetBoundingBox().PMin() - Vec3d(10, 10, 10), + stlgeometry->GetBoundingBox().PMax() + Vec3d(10, 10, 10), + mparam.grading); + stlgeometry -> RestrictLocalH(*mesh, mparam.maxh); + + if (stlparam.resthsurfmeshcurvenable) + mesh -> CalcLocalHFromSurfaceCurvature (mparam.grading, + stlparam.resthsurfmeshcurvfac); + } + + return TCL_OK; + } + + + + + VisualScene * STLGeometryVisRegister :: GetVisualScene (const NetgenGeometry * geom) const + { + const STLGeometry * geometry = dynamic_cast (geom); + if (geometry) + { + vsstlmeshing.SetGeometry (const_cast (geometry)); + return &vsstlmeshing; + } + return NULL; + } +} + + +using namespace netgen; + +extern "C" int Ng_stl_Init (Tcl_Interp * interp); +int Ng_stl_Init (Tcl_Interp * interp) +{ + geometryregister.Append (new STLGeometryVisRegister); + + Tcl_CreateCommand (interp, "Ng_SetSTLParameters", Ng_SetSTLParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_STLDoctor", Ng_STLDoctor, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_STLInfo", Ng_STLInfo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_STLCalcLocalH", Ng_STLCalcLocalH, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + return TCL_OK; +} diff --git a/libsrc/stlgeom/stltool.cpp b/libsrc/stlgeom/stltool.cpp new file mode 100644 index 00000000..20cb2c61 --- /dev/null +++ b/libsrc/stlgeom/stltool.cpp @@ -0,0 +1,1227 @@ +#include + +#include +#include +#include + +#include + +#include "stlgeom.hpp" + +namespace netgen +{ + + +//add a point into a pointlist, return pointnumber +int AddPointIfNotExists(Array& ap, const Point3d& p, double eps) +{ + double eps2 = sqr(eps); + for (int i = 1; i <= ap.Size(); i++) + if (Dist2(ap.Get(i),p) <= eps2 ) + return i; + return ap.Append(p); +} + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +double GetDistFromLine(const Point<3> & lp1, const Point<3> & lp2, + Point<3> & p) +{ + Vec3d vn = lp2 - lp1; + Vec3d v1 = p - lp1; + Vec3d v2 = lp2 - p; + + Point3d pold = p; + + if (v2 * vn <= 0) {p = lp2; return (pold - p).Length();} + if (v1 * vn <= 0) {p = lp1; return (pold - p).Length();} + + double vnl = vn.Length(); + if (vnl == 0) {return Dist(lp1,p);} + + vn /= vnl; + p = lp1 + (v1 * vn) * vn; + return (pold - p).Length(); +}; + +double GetDistFromInfiniteLine(const Point<3>& lp1, const Point<3>& lp2, const Point<3>& p) +{ + Vec3d vn(lp1, lp2); + Vec3d v1(lp1, p); + + double vnl = vn.Length(); + + if (vnl == 0) + { + return Dist (lp1, p); + } + else + { + return Cross (vn, v1).Length() / vnl; + } +}; + + + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//Binary IO-Manipulation + + + +void FIOReadInt(istream& ios, int& i) +{ + const int ilen = sizeof(int); + + char buf[ilen]; + for (int j = 0; j < ilen; j++) + ios.get(buf[j]); + memcpy(&i, &buf, ilen); +} + +void FIOWriteInt(ostream& ios, const int& i) +{ + const int ilen = sizeof(int); + + char buf[ilen]; + memcpy(&buf, &i, ilen); + + for (int j = 0; j < ilen; j++) + ios << buf[j]; +} + +void FIOReadDouble(istream& ios, double& i) +{ + const int ilen = sizeof(double); + + char buf[ilen]; + for (int j = 0; j < ilen; j++) + ios.get(buf[j]); + + memcpy(&i, &buf, ilen); +} + +void FIOWriteDouble(ostream& ios, const double& i) +{ + const int ilen = sizeof(double); + + char buf[ilen]; + memcpy(&buf, &i, ilen); + + for (int j = 0; j < ilen; j++) + ios << buf[j]; +} + +void FIOReadFloat(istream& ios, float& i) +{ + const int ilen = sizeof(float); + + char buf[ilen]; + int j; + for (j = 0; j < ilen; j++) + { + ios.get(buf[j]); + } + memcpy(&i, &buf, ilen); +} + +void FIOWriteFloat(ostream& ios, const float& i) +{ + const int ilen = sizeof(float); + + char buf[ilen]; + memcpy(&buf, &i, ilen); + + for (int j = 0; j < ilen; j++) + ios << buf[j]; +} + +void FIOReadString(istream& ios, char* str, int len) +{ + for (int j = 0; j < len; j++) + ios.get(str[j]); +} + +//read string and add terminating 0 +void FIOReadStringE(istream& ios, char* str, int len) +{ + for (int j = 0; j < len; j++) + ios.get(str[j]); + str[len] = 0; +} + +void FIOWriteString(ostream& ios, char* str, int len) +{ + for (int j = 0; j < len; j++) + ios << str[j]; +} + + +/* +void FIOReadInt(istream& ios, int& i) +{ + const int ilen = sizeof(int); + + char buf[ilen]; + int j; + for (j = 0; j < ilen; j++) + { + ios.get(buf[ilen-j-1]); + } + memcpy(&i, &buf, ilen); +} + +void FIOWriteInt(ostream& ios, const int& i) +{ + const int ilen = sizeof(int); + + char buf[ilen]; + memcpy(&buf, &i, ilen); + + int j; + for (j = 0; j < ilen; j++) + { + ios << buf[ilen-j-1]; + } +} + +void FIOReadDouble(istream& ios, double& i) +{ + const int ilen = sizeof(double); + + char buf[ilen]; + int j; + for (j = 0; j < ilen; j++) + { + ios.get(buf[ilen-j-1]); + } + memcpy(&i, &buf, ilen); +} + +void FIOWriteDouble(ostream& ios, const double& i) +{ + const int ilen = sizeof(double); + + char buf[ilen]; + memcpy(&buf, &i, ilen); + + int j; + for (j = 0; j < ilen; j++) + { + ios << buf[ilen-j-1]; + } +} + +void FIOReadFloat(istream& ios, float& i) +{ + const int ilen = sizeof(float); + + char buf[ilen]; + int j; + for (j = 0; j < ilen; j++) + { + ios.get(buf[ilen-j-1]); + } + memcpy(&i, &buf, ilen); +} + +void FIOWriteFloat(ostream& ios, const float& i) +{ + const int ilen = sizeof(float); + + char buf[ilen]; + memcpy(&buf, &i, ilen); + + int j; + for (j = 0; j < ilen; j++) + { + ios << buf[ilen-j-1]; + } +} + +void FIOReadString(istream& ios, char* str, int len) +{ + int j; + for (j = 0; j < len; j++) + { + ios.get(str[j]); + } +} + +//read string and add terminating 0 +void FIOReadStringE(istream& ios, char* str, int len) +{ + int j; + for (j = 0; j < len; j++) + { + ios.get(str[j]); + } + str[len] = 0; +} + +void FIOWriteString(ostream& ios, char* str, int len) +{ + int j; + for (j = 0; j < len; j++) + { + ios << str[j]; + } +} +*/ + +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +STLReadTriangle :: STLReadTriangle (const Point<3> * apts, + const Vec<3> & anormal) +{ + pts[0] = apts[0]; + pts[1] = apts[1]; + pts[2] = apts[2]; + normal = anormal; +} + + + +STLTriangle :: STLTriangle(const int * apts) +{ + pts[0] = apts[0]; + pts[1] = apts[1]; + pts[2] = apts[2]; + + facenum = 0; +} + +int STLTriangle :: IsNeighbourFrom(const STLTriangle& t) const +{ + //triangles must have same orientation!!! + + for(int i = 0; i <= 2; i++) + for(int j = 0; j <= 2; j++) + if (t.pts[(i+1)%3] == pts[j] && + t.pts[i] == pts[(j+1)%3]) + + return 1; + + return 0; +} + +int STLTriangle :: IsWrongNeighbourFrom(const STLTriangle& t) const +{ + //triangles have not same orientation!!! + for(int i = 0; i <= 2; i++) + for(int j = 0; j <= 2; j++) + if (t.pts[(i+1)%3] == pts[(j+1)%3] && + t.pts[i] == pts[j]) + + return 1; + + return 0; +} + +void STLTriangle :: GetNeighbourPoints(const STLTriangle& t, int& p1, int& p2) const +{ + for(int i = 1; i <= 3; i++) + for(int j = 1; j <= 3; j++) + if (t.PNumMod(i+1) == PNumMod(j) && + t.PNumMod(i) == PNumMod(j+1)) + { + p1 = PNumMod(j); + p2 = PNumMod(j+1); + return; + } + + PrintSysError("Get neighbourpoints failed!"); +} + +int STLTriangle :: GetNeighbourPointsAndOpposite(const STLTriangle& t, int& p1, int& p2, int& po) const +{ + for(int i = 1; i <= 3; i++) + for(int j = 1; j <= 3; j++) + if (t.PNumMod(i+1) == PNumMod(j) && + t.PNumMod(i) == PNumMod(j+1)) + { + p1 = PNumMod(j); + p2 = PNumMod(j+1); + po = PNumMod(j+2); + return 1; + } + + return 0; +} + +Vec<3> STLTriangle :: GeomNormal(const Array >& ap) const +{ + const Point<3> & p1 = ap.Get(PNum(1)); + const Point<3> & p2 = ap.Get(PNum(2)); + const Point<3> & p3 = ap.Get(PNum(3)); + + return Cross(p2-p1, p3-p1); +} + + +void STLTriangle :: SetNormal (const Vec<3> & n) +{ + double len = n.Length(); + if (len > 0) + { + normal = n; + normal.Normalize(); + } + else + { + normal = Vec<3> (1, 0, 0); + } +} + + +void STLTriangle :: ChangeOrientation() +{ + normal *= -1; + Swap(pts[0],pts[1]); +} + + + +double STLTriangle :: Area(const Array >& ap) const +{ + return 0.5 * Cross(ap.Get(PNum(2))-ap.Get(PNum(1)), + ap.Get(PNum(3))-ap.Get(PNum(1))).Length(); +} + +double STLTriangle :: MinHeight(const Array >& ap) const +{ + double ml = MaxLength(ap); + if (ml != 0) {return 2.*Area(ap)/ml;} + PrintWarning("max Side Length of a triangle = 0!!!"); + return 0; +} + +double STLTriangle :: MaxLength(const Array >& ap) const +{ + return max3(Dist(ap.Get(PNum(1)),ap.Get(PNum(2))), + Dist(ap.Get(PNum(2)),ap.Get(PNum(3))), + Dist(ap.Get(PNum(3)),ap.Get(PNum(1)))); +} + +void STLTriangle :: ProjectInPlain(const Array >& ap, + const Vec<3> & n, Point<3> & pp) const +{ + const Point<3> & p1 = ap.Get(PNum(1)); + const Point<3> & p2 = ap.Get(PNum(2)); + const Point<3> & p3 = ap.Get(PNum(3)); + + Vec<3> v1 = p2 - p1; + Vec<3> v2 = p3 - p1; + Vec<3> nt = Cross(v1, v2); + + double c = - (p1(0)*nt(0) + p1(1)*nt(1) + p1(2)*nt(2)); + + double prod = n * nt; + + if (fabs(prod) == 0) + { + pp = Point<3>(1.E20,1.E20,1.E20); + return; + } + + double nfact = -(pp(0)*nt(0) + pp(1)*nt(1) + pp(2)*nt(2) + c) / (prod); + pp = pp + (nfact) * n; + +} + + +int STLTriangle :: ProjectInPlain (const Array >& ap, + const Vec<3> & nproj, + Point<3> & pp, Vec<3> & lam) const +{ + const Point<3> & p1 = ap.Get(PNum(1)); + const Point<3> & p2 = ap.Get(PNum(2)); + const Point<3> & p3 = ap.Get(PNum(3)); + + Vec<3> v1 = p2-p1; + Vec<3> v2 = p3-p1; + + Mat<3> mat; + for (int i = 0; i < 3; i++) + { + mat(i,0) = v1(i); + mat(i,1) = v2(i); + mat(i,2) = nproj(i); + } + + int err = 0; + mat.Solve (pp-p1, lam); + // int err = SolveLinearSystem (v1, v2, nproj, pp-p1, lam); + + if (!err) + { + // pp = p1 + lam(0) * v1 + lam(1) * v2; + + pp(0) = p1(0) + lam(0) * v1(0) + lam(1) * v2(0); + pp(1) = p1(1) + lam(0) * v1(1) + lam(1) * v2(1); + pp(2) = p1(2) + lam(0) * v1(2) + lam(1) * v2(2); + } + return err; +} + + + + + +void STLTriangle :: ProjectInPlain(const Array >& ap, + Point<3> & pp) const +{ + const Point<3> & p1 = ap.Get(PNum(1)); + const Point<3> & p2 = ap.Get(PNum(2)); + const Point<3> & p3 = ap.Get(PNum(3)); + + Vec<3> v1 = p2 - p1; + Vec<3> v2 = p3 - p1; + Vec<3> nt = Cross(v1, v2); + + double c = - (p1(0)*nt(0) + p1(1)*nt(1) + p1(2)*nt(2)); + + double prod = nt * nt; + + double nfact = -(pp(0)*nt(0) + pp(1)*nt(1) + pp(2)*nt(2) + c) / (prod); + + pp = pp + (nfact) * nt; +} + +int STLTriangle :: PointInside(const Array > & ap, + const Point<3> & pp) const +{ + const Point<3> & p1 = ap.Get(PNum(1)); + const Point<3> & p2 = ap.Get(PNum(2)); + const Point<3> & p3 = ap.Get(PNum(3)); + + Vec<3> v1 = p2 - p1; + Vec<3> v2 = p3 - p1; + Vec<3> v = pp - p1; + double det, l1, l2; + Vec<3> ex, ey, ez; + + + ez = GeomNormal(ap); + ez /= ez.Length(); + ex = v1; + ex /= ex.Length(); + ey = Cross (ez, ex); + + Vec<2> v1p(v1*ex, v1*ey); + Vec<2> v2p(v2*ex, v2*ey); + Vec<2> vp(v*ex, v*ey); + + det = v2p(1) * v1p(0) - v2p(0) * v1p(1); + + if (fabs(det) == 0) {return 0;} + + l2 = (vp(1) * v1p(0) - vp(0) * v1p(1)) / det; + + if (v1p(0) != 0.) + { + l1 = (vp(0) - l2 * v2p(0)) / v1p(0); + } + else if (v1p(1) != 0.) + { + l1 = (vp(1) - l2 * v2p(1)) / v1p(1); + } + else {return 0;} + + if (l1 >= -1E-10 && l2 >= -1E-10 && l1 + l2 <= 1.+1E-10) {return 1;} + return 0; +} + +double STLTriangle :: GetNearestPoint(const Array >& ap, + Point<3> & p3d) const +{ + Point<3> p = p3d; + ProjectInPlain(ap, p); + double dist = (p - p3d).Length(); + + if (PointInside(ap, p)) {p3d = p; return dist;} + else + { + Point<3> pf = 0.0; + double nearest = 1E50; + //int fi = 0; + for (int j = 1; j <= 3; j++) + { + p = p3d; + dist = GetDistFromLine(ap.Get(PNum(j)), ap.Get(PNumMod(j+1)), p); + if (dist < nearest) + { + nearest = dist; + pf = p; + } + } + p3d = pf; + return nearest; + } +} + +int STLTriangle :: HasEdge(int p1, int p2) const +{ + int i; + for (i = 1; i <= 3; i++) + { + if (p1 == PNum(i) && p2 == PNumMod(i+1)) {return 1;} + } + return 0; +} + +ostream& operator<<(ostream& os, const STLTriangle& t) +{ + os << "["; + os << t[0] << ","; + os << t[1] << ","; + os << t[2] << "]"; + + return os; +}; + + + +STLTopEdge :: STLTopEdge () +{ + pts[0] = pts[1] = 0; + trigs[0] = trigs[1] = 0; + cosangle = 1; + status = ED_UNDEFINED; +} + +STLTopEdge :: STLTopEdge (int p1, int p2, int trig1, int trig2) +{ + pts[0] = p1; + pts[1] = p2; + trigs[0] = trig1; + trigs[1] = trig2; + cosangle = 1; + status = ED_UNDEFINED; +} + + + + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +//+++++++++++++++++++ STL CHART +++++++++++++++++++++++++++++++ +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +STLChart :: STLChart(STLGeometry * ageometry) +{ + charttrigs = new Array (0,0); + outertrigs = new Array (0,0); + ilimit = new Array (0,0); + olimit = new Array (0,0); + + geometry = ageometry; + + if ( (stlparam.usesearchtree == 1)) + searchtree = new Box3dTree (geometry->GetBoundingBox().PMin() - Vec3d(1,1,1), + geometry->GetBoundingBox().PMax() + Vec3d(1,1,1)); + else + searchtree = NULL; +} + +void STLChart :: AddChartTrig(int i) +{ + charttrigs->Append(i); + + const STLTriangle & trig = geometry->GetTriangle(i); + const Point3d & p1 = geometry->GetPoint (trig.PNum(1)); + const Point3d & p2 = geometry->GetPoint (trig.PNum(2)); + const Point3d & p3 = geometry->GetPoint (trig.PNum(3)); + + Point3d pmin(p1), pmax(p1); + pmin.SetToMin (p2); + pmin.SetToMin (p3); + pmax.SetToMax (p2); + pmax.SetToMax (p3); + + if (!geomsearchtreeon && (stlparam.usesearchtree == 1)) + {searchtree->Insert (pmin, pmax, i);} +} + +void STLChart :: AddOuterTrig(int i) +{ + outertrigs->Append(i); + + const STLTriangle & trig = geometry->GetTriangle(i); + const Point3d & p1 = geometry->GetPoint (trig.PNum(1)); + const Point3d & p2 = geometry->GetPoint (trig.PNum(2)); + const Point3d & p3 = geometry->GetPoint (trig.PNum(3)); + + Point3d pmin(p1), pmax(p1); + pmin.SetToMin (p2); + pmin.SetToMin (p3); + pmax.SetToMax (p2); + pmax.SetToMax (p3); + + if (!geomsearchtreeon && (stlparam.usesearchtree==1)) + {searchtree->Insert (pmin, pmax, i);} +} + +int STLChart :: IsInWholeChart(int nr) const +{ + for (int i = 1; i <= charttrigs->Size(); i++) + if (charttrigs->Get(i) == nr) return 1; + + for (int i = 1; i <= outertrigs->Size(); i++) + if (outertrigs->Get(i) == nr) return 1; + + return 0; +} + +void STLChart :: GetTrianglesInBox (const Point3d & pmin, + const Point3d & pmax, + Array & trias) const +{ + if (geomsearchtreeon) {PrintMessage(5,"geomsearchtreeon is set!!!");} + + if (searchtree) + searchtree -> GetIntersecting (pmin, pmax, trias); + else + { + Box3d box1(pmin, pmax); + box1.Increase (1e-4); + Box3d box2; + + trias.SetSize(0); + + int nt = GetNT(); + for (int i = 1; i <= nt; i++) + { + int trignum = GetTrig(i); + const STLTriangle & trig = geometry->GetTriangle(trignum); + box2.SetPoint (geometry->GetPoint (trig.PNum(1))); + box2.AddPoint (geometry->GetPoint (trig.PNum(2))); + box2.AddPoint (geometry->GetPoint (trig.PNum(3))); + + if (box1.Intersect (box2)) + trias.Append (trignum); + } + } +} + +//trigs may contain the same triangle double +void STLChart :: MoveToOuterChart(const Array& trigs) +{ + if (!trigs.Size()) {return;} + for (int i = 1; i <= trigs.Size(); i++) + { + if (charttrigs->Get(trigs.Get(i)) != -1) + {AddOuterTrig(charttrigs->Get(trigs.Get(i)));} + charttrigs->Elem(trigs.Get(i)) = -1; + } + DelChartTrigs(trigs); +} + +//trigs may contain the same triangle double +void STLChart :: DelChartTrigs(const Array& trigs) +{ + if (!trigs.Size()) {return;} + + for (int i = 1; i <= trigs.Size(); i++) + { + charttrigs->Elem(trigs.Get(i)) = -1; + } + + int cnt = 0; + for (int i = 1; i <= charttrigs->Size(); i++) + { + if (charttrigs->Elem(i) == -1) + { + cnt++; + } + if (cnt != 0 && i < charttrigs->Size()) + { + charttrigs->Elem(i-cnt+1) = charttrigs->Get(i+1); + } + } + int i = charttrigs->Size() - trigs.Size(); + charttrigs->SetSize(i); + + if (!geomsearchtreeon && stlparam.usesearchtree == 1) + { + PrintMessage(7, "Warning: unsecure routine due to first use of searchtrees!!!"); + //bould new searchtree!!! + searchtree = new Box3dTree (geometry->GetBoundingBox().PMin() - Vec3d(1,1,1), + geometry->GetBoundingBox().PMax() + Vec3d(1,1,1)); + + for (int i = 1; i <= charttrigs->Size(); i++) + { + const STLTriangle & trig = geometry->GetTriangle(i); + const Point3d & p1 = geometry->GetPoint (trig.PNum(1)); + const Point3d & p2 = geometry->GetPoint (trig.PNum(2)); + const Point3d & p3 = geometry->GetPoint (trig.PNum(3)); + + Point3d pmin(p1), pmax(p1); + pmin.SetToMin (p2); + pmin.SetToMin (p3); + pmax.SetToMax (p2); + pmax.SetToMax (p3); + + searchtree->Insert (pmin, pmax, i); + } + } +} + + +void STLChart :: SetNormal (const Point<3> & apref, const Vec<3> & anormal) +{ + pref = apref; + normal = anormal; + double len = normal.Length(); + if (len) normal /= len; + else normal = Vec<3> (1, 0, 0); + + t1 = normal.GetNormal (); + t2 = Cross (normal, t1); +} + +Point<2> STLChart :: Project2d (const Point<3> & p3d) const +{ + Vec<3> v = p3d-pref; + return Point<2> (t1 * v, t2 * v); +} + + + +/* + Point3d p1, p2, center; + double rad; + int i1, i2; +public: +*/ +STLBoundarySeg :: +STLBoundarySeg (int ai1, int ai2, const Array > & points, + const STLChart * chart) +{ + i1 = ai1; + i2 = ai2; + p1 = points.Get(i1); + p2 = points.Get(i2); + center = ::netgen::Center (p1, p2); + rad = Dist (p1, center); + + p2d1 = chart->Project2d (p1); + p2d2 = chart->Project2d (p2); + + boundingbox.Set (p2d1); + boundingbox.Add (p2d2); +} + +void STLBoundarySeg :: Swap () +{ + ::netgen::Swap (i1, i2); + ::netgen::Swap (p1, p2); +} + + + +STLBoundary :: STLBoundary (STLGeometry * ageometry) + : // boundary(), + geometry(ageometry) +{ + ; +} + + +void STLBoundary :: AddOrDelSegment(const STLBoundarySeg & seg) +{ + int i; + int found = 0; + for (i = 1; i <= boundary.Size(); i++) + { + if (found) {boundary.Elem(i-1) = boundary.Get(i);} + if (boundary.Get(i) == seg) {found = 1;} + } + if (!found) + { + boundary.Append(seg); + } + else + { + boundary.SetSize(boundary.Size()-1); + } +} + +void STLBoundary ::AddTriangle(const STLTriangle & t) +{ + int i; + int found1 = 0; + int found2 = 0; + int found3 = 0; + //int offset = 0; + + + STLBoundarySeg seg1(t[0],t[1], geometry->GetPoints(), chart); + STLBoundarySeg seg2(t[1],t[2], geometry->GetPoints(), chart); + STLBoundarySeg seg3(t[2],t[0], geometry->GetPoints(), chart); + + seg1.SetSmoothEdge (geometry->IsSmoothEdge (seg1.I1(), seg1.I2())); + seg2.SetSmoothEdge (geometry->IsSmoothEdge (seg2.I1(), seg2.I2())); + seg3.SetSmoothEdge (geometry->IsSmoothEdge (seg3.I1(), seg3.I2())); + + /* + for (i = 1; i <= boundary.Size(); i++) + { + if (offset) {boundary.Elem(i-offset) = boundary.Get(i);} + if (boundary.Get(i) == seg1) {found1 = 1; offset++;} + if (boundary.Get(i) == seg2) {found2 = 1; offset++;} + if (boundary.Get(i) == seg3) {found3 = 1; offset++;} + } + + if (offset) + { + boundary.SetSize(boundary.Size()-offset); + } + */ + for (i = boundary.Size(); i >= 1; i--) + { + if (boundary.Get(i) == seg1) + { boundary.DeleteElement (i); found1 = 1; } + else if (boundary.Get(i) == seg2) + { boundary.DeleteElement (i); found2 = 1; } + else if (boundary.Get(i) == seg3) + { boundary.DeleteElement (i); found3 = 1; } + } + + if (!found1) {seg1.Swap(); boundary.Append(seg1);} + if (!found2) {seg2.Swap(); boundary.Append(seg2);} + if (!found3) {seg3.Swap(); boundary.Append(seg3);} +} + +int STLBoundary :: TestSeg(const Point<3>& p1, const Point<3> & p2, const Vec<3> & sn, + double sinchartangle, int divisions, Array >& points, double eps) +{ + + if (usechartnormal) + return TestSegChartNV (p1, p2, sn); + + // for statistics + { + int i; + static Array cntclass; + static int cnt = 0; + static int cnti = 0, cnto = 0; + static long int cntsegs = 0; + if (cntclass.Size() == 0) + { + cntclass.SetSize (20); + for (i = 1; i <= cntclass.Size(); i++) + cntclass.Elem(i) = 0; + } + + cntsegs += NOSegments(); + int cla = int (log (double(NOSegments()+1)) / log(2.0)); + if (cla < 1) cla = 1; + if (cla > cntclass.Size()) cla = cntclass.Size(); + cntclass.Elem(cla)++; + cnt++; + if (divisions) + cnti++; + else + cnto++; + if (cnt > 100000) + { + cnt = 0; + /* + (*testout) << "TestSeg-calls for classes:" << endl; + (*testout) << cnti << " inner calls, " << cnto << " outercalls" << endl; + (*testout) << "total testes segments: " << cntsegs << endl; + for (i = 1; i <= cntclass.Size(); i++) + { + (*testout) << int (exp (i * log(2.0))) << " bnd segs: " << cntclass.Get(i) << endl; + } + */ + } + } + + + int i,j,k; + Point<3> seg1p/*, seg2p*/; + Point<3> sp1,sp2; + double lambda1, lambda2, vlen2; + Vec<3> vptpl; + double sinchartangle2 = sqr(sinchartangle); + double scal; + int possible; + + //double maxval = -1; + //double maxvalnew = -1; + + + + double scalp1 = p1(0) * sn(0) + p1(1) * sn(1) + p1(2) * sn(2); + double scalp2 = p2(0) * sn(0) + p2(1) * sn(1) + p2(2) * sn(2); + double minl = min2(scalp1, scalp2); + double maxl = max2(scalp1, scalp2); + Point<3> c = Center (p1, p2); + double dist1 = Dist (c, p1); + + int nseg = NOSegments(); + for (j = 1; j <= nseg; j++) + { + const STLBoundarySeg & seg = GetSegment(j); + + + if (seg.IsSmoothEdge()) + continue; + + + sp1 = seg.P1(); + sp2 = seg.P2(); + + // Test, ob Spiral Konfikt moeglich + + possible = 1; + + double scalsp1 = sp1(0) * sn(0) + sp1(1) * sn(1) + sp1(2) * sn(2); + double scalsp2 = sp2(0) * sn(0) + sp2(1) * sn(1) + sp2(2) * sn(2); + + double minsl = min2(scalsp1, scalsp2); + double maxsl = max2(scalsp1, scalsp2); + + double maxdiff = max2 (maxsl - minl, maxl - minsl); + + /* + Point3d sc = Center (sp1, sp2); + double mindist = Dist(c, sc) - dist1 - GetSegment(j).Radius(); + if (maxdiff < sinchartangle * mindist) + { + possible = 0; + } + */ + + double hscal = maxdiff + sinchartangle * (dist1 + seg.Radius()); + if (hscal * hscal < sinchartangle * Dist2(c, seg.center )) + possible = 0; + + + /* + if (possible) + { + double mindist2ex = MinDistLL2 (p1, p2, sp1, sp2); + if (maxdiff * maxdiff < sinchartangle2 * mindist2ex) + possible = 0; + } + */ + + if (possible) + { + LinearPolynomial2V lp (scalp1 - scalsp1, + scalp2 - scalp1, + -(scalsp2 - scalsp1)); + QuadraticPolynomial2V slp; + slp.Square (lp); + + + Vec3d v (p1, sp1); + Vec3d vl (p1, p2); + Vec3d vsl (sp1, sp2); + + QuadraticPolynomial2V qp (v.Length2(), + -2 * (v * vl), + 2 * (v * vsl), + vl.Length2(), + -2 * (vl * vsl), + vsl.Length2()); + + slp.Add (-sinchartangle2, qp); + + double hv = slp.MaxUnitSquare(); + + if (hv > eps) return 0; + /* + if (hv > maxvalnew) + maxvalnew = hv; + */ + } + + + if (possible && 0) + + for (i = 0; i <= divisions; i++) + { + + lambda1 = (double)i/(double)divisions; + seg1p = Point3d(p1(0)*lambda1+p2(0)*(1.-lambda1), + p1(1)*lambda1+p2(1)*(1.-lambda1), + p1(2)*lambda1+p2(2)*(1.-lambda1)); + + + + for (k = 0; k <= divisions; k++) + { + lambda2 = (double)k/(double)divisions; + vptpl = Vec3d(sp1(0)*lambda2+sp2(0)*(1.-lambda2)-seg1p(0), + sp1(1)*lambda2+sp2(1)*(1.-lambda2)-seg1p(1), + sp1(2)*lambda2+sp2(2)*(1.-lambda2)-seg1p(2)); + + vlen2 = vptpl.Length2(); + + // if (vlen2 > 0) + { + scal = vptpl * sn; + double hv = scal*scal - sinchartangle2*vlen2; + + + + /* + if (hv > maxval) + maxval = hv; + */ + if (hv > eps) return 0; + } + } + } + } + + return 1; + // return (maxvalnew < eps); +} + + + +// checks, whether 2d projection intersects +int STLBoundary :: TestSegChartNV(const Point3d & p1, const Point3d& p2, + const Vec3d& sn) +{ + int nseg = NOSegments(); + + Point<2> p2d1 = chart->Project2d (p1); + Point<2> p2d2 = chart->Project2d (p2); + + Box<2> box2d; + box2d.Set (p2d1); + box2d.Add (p2d2); + + Line2d l1 (p2d1, p2d2); + + double eps = 1e-3; + bool ok = true; + + for (int j = 1; j <= nseg; j++) + { + if (!ok) continue; + const STLBoundarySeg & seg = GetSegment(j); + + if (!box2d.Intersect (seg.BoundingBox())) continue; + if (seg.IsSmoothEdge()) continue; + + const Point<2> & sp1 = seg.P2D1(); + const Point<2> & sp2 = seg.P2D2(); + + Line2d l2 (sp1, sp2); + double lam1, lam2; + + int err = + CrossPointBarycentric (l1, l2, lam1, lam2); + + if (!err && lam1 > eps && lam1 < 1-eps && + lam2 > eps && lam2 < 1-eps) + ok = false; + } + + return ok; +} + + + +STLDoctorParams :: STLDoctorParams() +{ + drawmeshededges = 1; + geom_tol_fact = 1E-6; + longlinefact = 0; + showexcluded = 1; + + selectmode = 0; + edgeselectmode = 0; + useexternaledges = 0; + showfaces = 0; + showtouchedtrigchart = 1; + showedgecornerpoints = 1; + conecheck = 1; + spiralcheck = 1; + selecttrig = 0; + nodeofseltrig = 1; + selectwithmouse = 1; + showmarkedtrigs = 1; + dirtytrigfact = 0.001; + smoothangle = 90; + smoothnormalsweight = 0.2; + vicinity = 0; + showvicinity = 0; +} + + + +STLDoctorParams stldoctor; + +void STLDoctorParams :: Print (ostream & ost) const +{ + ost << "STL doctor parameters:" << endl + << "selecttrig = " << selecttrig << endl + << "selectlocalpoint = " << nodeofseltrig << endl + << "selectwithmouse = " << selectwithmouse << endl + << "showmarkedtrigs = " << showmarkedtrigs << endl + << "dirtytrigfact = " << dirtytrigfact << endl + << "smoothangle = " << smoothangle << endl; +} + + +STLParameters :: STLParameters() +{ + yangle = 30; + contyangle = 20; + edgecornerangle = 60; + chartangle = 15; + outerchartangle = 70; + + usesearchtree = 0; + atlasminh = 1E-4; + resthsurfcurvfac = 2; + resthsurfcurvenable = 0; + resthatlasfac = 2; + resthatlasenable = 1; + resthchartdistfac = 1.2; + resthchartdistenable = 1; + resthlinelengthfac = 0.5; + resthlinelengthenable = 1; + resthcloseedgefac = 1; + resthcloseedgeenable = 1; + resthedgeanglefac = 1; + resthedgeangleenable = 0; + resthsurfmeshcurvfac = 1; + resthsurfmeshcurvenable = 0; + recalc_h_opt = 1; +} + +void STLParameters :: Print (ostream & ost) const +{ + ost << "STL parameters:" << endl + << "yellow angle = " << yangle << endl + << "continued yellow angle = " << contyangle << endl + << "edgecornerangle = " << edgecornerangle << endl + << "chartangle = " << chartangle << endl + << "outerchartangle = " << outerchartangle << endl + << "restrict h due to ..., enable and safety factor: " << endl + << "surface curvature: " << resthsurfcurvenable + << ", fac = " << resthsurfcurvfac << endl + << "atlas surface curvature: " << resthatlasenable + << ", fac = " << resthatlasfac << endl + << "chart distance: " << resthchartdistenable + << ", fac = " << resthchartdistfac << endl + << "line length: " << resthlinelengthenable + << ", fac = " << resthlinelengthfac << endl + << "close edges: " << resthcloseedgeenable + << ", fac = " << resthcloseedgefac << endl + << "edge angle: " << resthedgeangleenable + << ", fac = " << resthedgeanglefac << endl; +} + + +STLParameters stlparam; + + +} diff --git a/libsrc/stlgeom/stltool.hpp b/libsrc/stlgeom/stltool.hpp new file mode 100644 index 00000000..ca3d6e2f --- /dev/null +++ b/libsrc/stlgeom/stltool.hpp @@ -0,0 +1,271 @@ +#ifndef FILE_STLTOOL +#define FILE_STLTOOL + + +//#include "gprim/gprim.hh" + +/**************************************************************************/ +/* File: stlgeom.hh */ +/* Author: Joachim Schoeberl */ +/* Author2: Johannes Gerstmayr */ +/* Date: 20. Nov. 99 */ +/**************************************************************************/ + + + +// use one normal vector for whole chart +extern int usechartnormal; +extern int chartdebug; + +extern int geomsearchtreeon; +extern int AddPointIfNotExists(Array& ap, const Point3d& p, double eps = 1e-8); +//get distance from line lp1-lp2 to point p +extern double GetDistFromLine(const Point<3>& lp1, const Point<3>& lp2, Point<3>& p); +extern double GetDistFromInfiniteLine(const Point<3>& lp1, const Point<3>& lp2, const Point<3>& p); + + +extern void FIOReadInt(istream& ios, int& i); +extern void FIOWriteInt(ostream& ios, const int& i); +extern void FIOReadDouble(istream& ios, double& i); +extern void FIOWriteDouble(ostream& ios, const double& i); +extern void FIOReadFloat(istream& ios, float& i); +extern void FIOWriteFloat(ostream& ios, const float& i); +extern void FIOReadString(istream& ios, char* str, int len); +extern void FIOReadStringE(istream& ios, char* str, int len); +extern void FIOWriteString(ostream& ios, char* str, int len); + + +typedef Array * ArrayINTPTR; + +class STLGeometry; + +class STLChart +{ +private: + STLGeometry * geometry; + Array* charttrigs; // trigs which only belong to this chart + Array* outertrigs; // trigs which belong to other charts + Box3dTree * searchtree; // ADT containing outer trigs + + Array* olimit; //outer limit of outer chart + Array* ilimit; //outer limit of inner chart + + +public: + + STLChart(STLGeometry * ageometry); + void AddChartTrig(int i); + void AddOuterTrig(int i); + + int IsInWholeChart(int nr) const; + + int GetChartTrig(int i) const {return charttrigs->Get(i);} + int GetOuterTrig(int i) const {return outertrigs->Get(i);} + //get all trigs: + int GetTrig(int i) const + { + if (i <= charttrigs->Size()) {return charttrigs->Get(i);} + else {return outertrigs->Get(i-charttrigs->Size());} + } + + int GetNChartT() const {return charttrigs->Size();} + int GetNOuterT() const {return outertrigs->Size();} + int GetNT() const {return charttrigs->Size()+outertrigs->Size(); } + + void GetTrianglesInBox (const Point3d & pmin, + const Point3d & pmax, + Array & trias) const; + void AddOLimit(twoint l) {olimit->Append(l);} + void AddILimit(twoint l) {ilimit->Append(l);} + + void ClearOLimit() {olimit->SetSize(0);} + void ClearILimit() {ilimit->SetSize(0);} + + int GetNOLimit() const {return olimit->Size();} + int GetNILimit() const {return ilimit->Size();} + + twoint GetOLimit(int i) const {return olimit->Get(i);} + twoint GetILimit(int i) const {return ilimit->Get(i);} + + //move triangles trigs (local chart-trig numbers) to outer chart + void MoveToOuterChart(const Array& trigs); + void DelChartTrigs(const Array& trigs); + + + // define local coordinate system, JS: +private: + Vec<3> normal; + Point<3> pref; + Vec<3> t1, t2; +public: + void SetNormal (const Point<3> & apref, const Vec<3> & anormal); + const Vec<3> & GetNormal () const { return normal; } + Point<2> Project2d (const Point<3> & p3d) const; +}; + +class STLBoundarySeg +{ + Point<3> p1, p2, center; + Point<2> p2d1, p2d2; + Box<2> boundingbox; + // Point<2> p2dmin, p2dmax; + + double rad; + int i1, i2; + int smoothedge; +public: + STLBoundarySeg () { ; } + STLBoundarySeg (int ai1, int ai2, const Array > & points, + const STLChart * achart); + + int operator== (const STLBoundarySeg & s2) const + { return i1 == s2.i1 && i2 == s2.i2; } + void Swap (); + int I1() const { return i1; } + int I2() const { return i2; } + const Point<3> & P1() const { return p1; } + const Point<3> & P2() const { return p2; } + const Point<2> & P2D1() const { return p2d1; } + const Point<2> & P2D2() const { return p2d2; } + const Point<2> & P2DMin() const { return boundingbox.PMin(); } + const Point<2> & P2DMax() const { return boundingbox.PMax(); } + const Point<3> & Center() const { return center; } + const Box<2> & BoundingBox() const { return boundingbox; } + double Radius () const { return rad; } + + void SetSmoothEdge (int se) { smoothedge = se; } + int IsSmoothEdge () const { return smoothedge; } + friend class STLBoundary; +}; + +class STLBoundary +{ +private: + STLGeometry * geometry; + const STLChart * chart; + Array boundary; +public: + STLBoundary(STLGeometry * ageometry); + // : boundary() {}; + + void Clear() {boundary.SetSize(0);}; + void SetChart (const STLChart * achart) { chart = achart; } + //don't check, if already exists! + void AddNewSegment(const STLBoundarySeg & seg) {boundary.Append(seg);}; + //check if segment exists + void AddOrDelSegment(const STLBoundarySeg & seg); + //addordelsegment for all 3 triangle segments! + void AddTriangle(const STLTriangle & t); + int NOSegments() {return boundary.Size();}; + const STLBoundarySeg & GetSegment(int i) {return boundary.Get(i);} + + int TestSeg(const Point<3> & p1, const Point<3> & p2, const Vec<3> & sn, + double sinchartangle, int divisions, Array >& points, + double eps); + + int TestSegChartNV(const Point3d& p1, const Point3d& p2, const Vec3d& sn); +}; + + +class STLDoctorParams +{ +public: + int drawmeshededges; + double geom_tol_fact; + + double longlinefact; + int showexcluded; + + int selectmode; //0==trig, 1==edge, 2==point, 3==multiedge, 4==line cluster + int edgeselectmode; + + int useexternaledges; + int showfaces; + int showedgecornerpoints; + int showtouchedtrigchart; + int conecheck; + int spiralcheck; + int selecttrig; + int nodeofseltrig; + int selectwithmouse; + int showmarkedtrigs; + double dirtytrigfact; + double smoothangle; + + double smoothnormalsweight; + + int showvicinity; + int vicinity; + /// + STLDoctorParams(); + /// + void Print (ostream & ost) const; +}; + +extern STLDoctorParams stldoctor; + + + +class STLParameters +{ +public: + /// angle for edge detection + double yangle; + double contyangle; //edges continued with contyangle + /// angle of geometry edge at which the mesher should set a point + double edgecornerangle; + /// angle inside on chart + double chartangle; + /// angle for overlapping parts of char + double outerchartangle; + /// 0 .. no, 1 .. local, (2 .. global) + int usesearchtree; + /// + double resthatlasfac; + int resthatlasenable; + double atlasminh; + + double resthsurfcurvfac; + int resthsurfcurvenable; + + double resthchartdistfac; + int resthchartdistenable; + + double resthcloseedgefac; + int resthcloseedgeenable; + + double resthedgeanglefac; + int resthedgeangleenable; + + double resthsurfmeshcurvfac; + int resthsurfmeshcurvenable; + + double resthlinelengthfac; + int resthlinelengthenable; + + /// + int recalc_h_opt; + /// + STLParameters(); + /// + void Print (ostream & ost) const; +}; + +extern STLParameters stlparam; + + +void STLMeshing (STLGeometry & geom, + class Mesh & mesh); + + +int STLSurfaceMeshing (STLGeometry & geom, + class Mesh & mesh); + +void STLSurfaceOptimization (STLGeometry & geom, + class Mesh & mesh, + class MeshingParameters & mparam); + + + + +#endif diff --git a/libsrc/stlgeom/stltopology.cpp b/libsrc/stlgeom/stltopology.cpp new file mode 100644 index 00000000..f4078ead --- /dev/null +++ b/libsrc/stlgeom/stltopology.cpp @@ -0,0 +1,1076 @@ +#include + +#include +#include +#include + +#include + +#include "stlgeom.hpp" + +namespace netgen +{ + + + STLTopology :: STLTopology() + : trias(), topedges(), points(), ht_topedges(NULL), + trigsperpoint(), neighbourtrigs() +{ + ; +} + +STLTopology :: ~STLTopology() +{ + ; +} + + + + +STLGeometry * STLTopology :: LoadBinary (istream & ist) +{ + STLGeometry * geom = new STLGeometry(); + Array readtrigs; + + PrintMessage(1,"Read STL binary file"); + + if (sizeof(int) != 4 || sizeof(float) != 4) + { + PrintWarning("for stl-binary compatibility only use 32 bit compilation!!!"); + } + + //specific settings for stl-binary format + const int namelen = 80; //length of name of header in file + const int nospaces = 2; //number of spaces after a triangle + + //read header: name + char buf[namelen+1]; + FIOReadStringE(ist,buf,namelen); + PrintMessage(5,"header = ",buf); + + //Read Number of facets + int nofacets; + FIOReadInt(ist,nofacets); + PrintMessage(5,"NO facets = ",nofacets); + + Point<3> pts[3]; + Vec<3> normal; + + char spaces[nospaces+1]; + + for (int cntface = 0; cntface < nofacets; cntface++) + { + if (cntface % 10000 == 0) + // { PrintDot(); } + PrintMessageCR (3, cntface, " triangles loaded\r"); + + float f; + FIOReadFloat(ist,f); normal(0) = f; + FIOReadFloat(ist,f); normal(1) = f; + FIOReadFloat(ist,f); normal(2) = f; + + for (int j = 0; j < 3; j++) + { + FIOReadFloat(ist,f); pts[j](0) = f; + FIOReadFloat(ist,f); pts[j](1) = f; + FIOReadFloat(ist,f); pts[j](2) = f; + } + + readtrigs.Append (STLReadTriangle (pts, normal)); + FIOReadString(ist,spaces,nospaces); + } + PrintMessage (3, nofacets, " triangles loaded\r"); + + geom->InitSTLGeometry(readtrigs); + + return geom; +} + + +void STLTopology :: SaveBinary (const char* filename, const char* aname) const +{ + ofstream ost(filename); + PrintFnStart("Write STL binary file '",filename,"'"); + + if (sizeof(int) != 4 || sizeof(float) != 4) + {PrintWarning("for stl-binary compatibility only use 32 bit compilation!!!");} + + //specific settings for stl-binary format + const int namelen = 80; //length of name of header in file + const int nospaces = 2; //number of spaces after a triangle + + //write header: aname + int i, j; + char buf[namelen+1]; + int strend = 0; + for(i = 0; i <= namelen; i++) + { + if (aname[i] == 0) {strend = 1;} + if (!strend) {buf[i] = aname[i];} + else {buf[i] = 0;} + } + + FIOWriteString(ost,buf,namelen); + PrintMessage(5,"header = ",buf); + + //RWrite Number of facets + int nofacets = GetNT(); + FIOWriteInt(ost,nofacets); + PrintMessage(5,"NO facets = ", nofacets); + + float f; + char spaces[nospaces+1]; + for (i = 0; i < nospaces; i++) {spaces[i] = ' ';} + spaces[nospaces] = 0; + + for (i = 1; i <= GetNT(); i++) + { + const STLTriangle & t = GetTriangle(i); + + const Vec<3> & n = t.Normal(); + f = n(0); FIOWriteFloat(ost,f); + f = n(1); FIOWriteFloat(ost,f); + f = n(2); FIOWriteFloat(ost,f); + + for (j = 1; j <= 3; j++) + { + const Point3d p = GetPoint(t.PNum(j)); + + f = p.X(); FIOWriteFloat(ost,f); + f = p.Y(); FIOWriteFloat(ost,f); + f = p.Z(); FIOWriteFloat(ost,f); + } + FIOWriteString(ost,spaces,nospaces); + } + PrintMessage(5,"done"); +} + + +void STLTopology :: SaveSTLE (const char* filename) const +{ + ofstream outf (filename); + int i, j; + + outf << GetNT() << endl; + for (i = 1; i <= GetNT(); i++) + { + const STLTriangle & t = GetTriangle(i); + for (j = 1; j <= 3; j++) + { + const Point3d p = GetPoint(t.PNum(j)); + outf << p.X() << " " << p.Y() << " " << p.Z() << endl; + } + } + + + int ned = 0; + for (i = 1; i <= GetNTE(); i++) + { + if (GetTopEdge (i).GetStatus() == ED_CONFIRMED) + ned++; + } + + outf << ned << endl; + + for (i = 1; i <= GetNTE(); i++) + { + const STLTopEdge & edge = GetTopEdge (i); + if (edge.GetStatus() == ED_CONFIRMED) + for (j = 1; j <= 2; j++) + { + const Point3d p = GetPoint(edge.PNum(j)); + outf << p.X() << " " << p.Y() << " " << p.Z() << endl; + } + } +} + + + +STLGeometry * STLTopology :: LoadNaomi (istream & ist) +{ + int i; + STLGeometry * geom = new STLGeometry(); + Array readtrigs; + + PrintFnStart("read NAOMI file format"); + + char buf[100]; + Vec<3> normal; + + //int cntface = 0; + //int cntvertex = 0; + double px, py, pz; + + + int noface, novertex; + Array > readpoints; + + ist >> buf; + if (strcmp (buf, "NODES") == 0) + { + ist >> novertex; + PrintMessage(5,"nuber of vertices = ", novertex); + for (i = 0; i < novertex; i++) + { + ist >> px; + ist >> py; + ist >> pz; + readpoints.Append(Point<3> (px,py,pz)); + } + } + else + { + PrintFileError("no node information"); + } + + + ist >> buf; + if (strcmp (buf, "2D_EDGES") == 0) + { + ist >> noface; + PrintMessage(5,"number of faces=",noface); + int dummy, p1, p2, p3; + Point<3> pts[3]; + + for (i = 0; i < noface; i++) + { + ist >> dummy; //2 + ist >> dummy; //1 + ist >> p1; + ist >> p2; + ist >> p3; + ist >> dummy; //0 + + pts[0] = readpoints.Get(p1); + pts[1] = readpoints.Get(p2); + pts[2] = readpoints.Get(p3); + + normal = Cross (pts[1]-pts[0], pts[2]-pts[0]) . Normalize(); + + readtrigs.Append (STLReadTriangle (pts, normal)); + + } + PrintMessage(5,"read ", readtrigs.Size(), " triangles"); + } + else + { + PrintMessage(5,"read='",buf,"'\n"); + PrintFileError("ERROR: no Triangle information"); + } + + geom->InitSTLGeometry(readtrigs); + + return geom; +} + +void STLTopology :: Save (const char* filename) const +{ + PrintFnStart("Write stl-file '",filename, "'"); + + ofstream fout(filename); + fout << "solid\n"; + + char buf1[50]; + char buf2[50]; + char buf3[50]; + + int i, j; + for (i = 1; i <= GetNT(); i++) + { + const STLTriangle & t = GetTriangle(i); + + fout << "facet normal "; + const Vec3d& n = GetTriangle(i).Normal(); + + sprintf(buf1,"%1.9g",n.X()); + sprintf(buf2,"%1.9g",n.Y()); + sprintf(buf3,"%1.9g",n.Z()); + + fout << buf1 << " " << buf2 << " " << buf3 << "\n"; + fout << "outer loop\n"; + + for (j = 1; j <= 3; j++) + { + const Point3d p = GetPoint(t.PNum(j)); + + sprintf(buf1,"%1.9g",p.X()); + sprintf(buf2,"%1.9g",p.Y()); + sprintf(buf3,"%1.9g",p.Z()); + + fout << "vertex " << buf1 << " " << buf2 << " " << buf3 << "\n"; + } + + fout << "endloop\n"; + fout << "endfacet\n"; + } + fout << "endsolid\n"; + + + // write also NETGEN surface mesh: + ofstream fout2("geom.surf"); + fout2 << "surfacemesh" << endl; + fout2 << GetNP() << endl; + for (i = 1; i <= GetNP(); i++) + { + for (j = 0; j < 3; j++) + { + fout2.width(8); + fout2 << GetPoint(i)(j); + } + + fout2 << endl; + } + + fout2 << GetNT() << endl; + for (i = 1; i <= GetNT(); i++) + { + const STLTriangle & t = GetTriangle(i); + for (j = 1; j <= 3; j++) + { + fout2.width(8); + fout2 << t.PNum(j); + } + fout2 << endl; + } +} + + +STLGeometry * STLTopology ::Load (istream & ist) +{ + STLGeometry * geom = new STLGeometry(); + + Array readtrigs; + + char buf[100]; + Point<3> pts[3]; + Vec<3> normal; + + int cntface = 0; + int vertex = 0; + bool badnormals = false; + + while (ist.good()) + { + ist >> buf; + + int n = strlen (buf); + for (int i = 0; i < n; i++) + buf[i] = tolower (buf[i]); + + if (strcmp (buf, "facet") == 0) + { + cntface++; + } + + if (strcmp (buf, "normal") == 0) + { + ist >> normal(0) + >> normal(1) + >> normal(2); + normal.Normalize(); + } + + if (strcmp (buf, "vertex") == 0) + { + ist >> pts[vertex](0) + >> pts[vertex](1) + >> pts[vertex](2); + + vertex++; + + if (vertex == 3) + { + if (normal.Length() <= 1e-5) + + { + normal = Cross (pts[1]-pts[0], pts[2]-pts[0]); + normal.Normalize(); + } + + else + + { + Vec<3> hnormal = Cross (pts[1]-pts[0], pts[2]-pts[0]); + hnormal.Normalize(); + + if (normal * hnormal < 0.5) + badnormals = true; + } + + vertex = 0; + + if ( (Dist2 (pts[0], pts[1]) > 1e-16) && + (Dist2 (pts[0], pts[2]) > 1e-16) && + (Dist2 (pts[1], pts[2]) > 1e-16) ) + + { + readtrigs.Append (STLReadTriangle (pts, normal)); + + if (readtrigs.Size() % 100000 == 0) + PrintMessageCR (3, readtrigs.Size(), " triangles loaded\r"); + } + else + { + cout << "Skipping flat triangle " + << "l1 = " << Dist(pts[0], pts[1]) + << ", l2 = " << Dist(pts[0], pts[2]) + << ", l3 = " << Dist(pts[2], pts[1]) << endl; + } + + } + } + } + PrintMessage (3, readtrigs.Size(), " triangles loaded"); + + if (badnormals) + { + PrintWarning("File has normal vectors which differ extremly from geometry->correct with stldoctor!!!"); + } + + geom->InitSTLGeometry(readtrigs); + return geom; +} + + + + + + + + + + + + + +void STLTopology :: InitSTLGeometry(const Array & readtrigs) +{ + // const double geometry_tol_fact = 1E6; + // distances lower than max_box_size/tol are ignored + + trias.SetSize(0); + points.SetSize(0); + + PrintMessage(3,"number of triangles = ", readtrigs.Size()); + + if (!readtrigs.Size()) return; + + + boundingbox.Set (readtrigs[0][0]); + for (int i = 0; i < readtrigs.Size(); i++) + for (int k = 0; k < 3; k++) + boundingbox.Add (readtrigs[i][k]); + + PrintMessage(5,"boundingbox: ", Point3d(boundingbox.PMin()), " - ", + Point3d(boundingbox.PMax())); + + Box<3> bb = boundingbox; + bb.Increase (1); + + pointtree = new Point3dTree (bb.PMin(), bb.PMax()); + + Array pintersect; + + pointtol = boundingbox.Diam() * stldoctor.geom_tol_fact; + PrintMessage(5,"point tolerance = ", pointtol); + PrintMessageCR(5,"identify points ..."); + + for(int i = 0; i < readtrigs.Size(); i++) + { + const STLReadTriangle & t = readtrigs[i]; + + STLTriangle st; + st.SetNormal (t.Normal()); + + for (int k = 0; k < 3; k++) + { + Point<3> p = t[k]; + + Point<3> pmin = p - Vec<3> (pointtol, pointtol, pointtol); + Point<3> pmax = p + Vec<3> (pointtol, pointtol, pointtol); + + pointtree->GetIntersecting (pmin, pmax, pintersect); + + if (pintersect.Size() > 1) + PrintError("too many close points"); + int foundpos = -1; + if (pintersect.Size()) + foundpos = pintersect[0]; + + if (foundpos == -1) + { + foundpos = AddPoint(p); + pointtree->Insert (p, foundpos); + } + if (Dist(p, points.Get(foundpos)) > 1e-10) + cout << "identify close points: " << p << " " << points.Get(foundpos) + << ", dist = " << Dist(p, points.Get(foundpos)) + << endl; + st[k] = foundpos; + } + + if ( (st[0] == st[1]) || + (st[0] == st[2]) || + (st[1] == st[2]) ) + { + PrintError("STL Triangle degenerated"); + } + else + { + AddTriangle(st); + } + + } + PrintMessage(5,"identify points ... done"); + FindNeighbourTrigs(); +} + + + + +int STLTopology :: GetPointNum (const Point<3> & p) +{ + Point<3> pmin = p - Vec<3> (pointtol, pointtol, pointtol); + Point<3> pmax = p + Vec<3> (pointtol, pointtol, pointtol); + + Array pintersect; + + pointtree->GetIntersecting (pmin, pmax, pintersect); + if (pintersect.Size() == 1) + return pintersect[0]; + else + return 0; +} + + + +void STLTopology :: FindNeighbourTrigs() +{ + // if (topedges.Size()) return; + + PushStatusF("Find Neighbour Triangles"); + + PrintMessage(5,"build topology ..."); + + // build up topology tables + + int nt = GetNT(); + + INDEX_2_HASHTABLE * oldedges = ht_topedges; + ht_topedges = new INDEX_2_HASHTABLE (GetNP()+1); + topedges.SetSize(0); + + for (int i = 1; i <= nt; i++) + { + STLTriangle & trig = GetTriangle(i); + + + for (int j = 1; j <= 3; j++) + { + int pi1 = trig.PNumMod (j+1); + int pi2 = trig.PNumMod (j+2); + + INDEX_2 i2(pi1, pi2); + i2.Sort(); + + int enr; + int othertn; + + if (ht_topedges->Used(i2)) + { + enr = ht_topedges->Get(i2); + topedges.Elem(enr).TrigNum(2) = i; + + othertn = topedges.Get(enr).TrigNum(1); + STLTriangle & othertrig = GetTriangle(othertn); + + trig.NBTrigNum(j) = othertn; + trig.EdgeNum(j) = enr; + for (int k = 1; k <= 3; k++) + if (othertrig.EdgeNum(k) == enr) + othertrig.NBTrigNum(k) = i; + } + else + { + enr = topedges.Append (STLTopEdge (pi1, pi2, i, 0)); + ht_topedges->Set (i2, enr); + trig.EdgeNum(j) = enr; + } + } + } + + + PrintMessage(5,"topology built, checking"); + + topology_ok = 1; + int ne = GetNTE(); + + for (int i = 1; i <= nt; i++) + GetTriangle(i).flags.toperror = 0; + + for (int i = 1; i <= nt; i++) + for (int j = 1; j <= 3; j++) + { + const STLTopEdge & edge = GetTopEdge (GetTriangle(i).EdgeNum(j)); + if (edge.TrigNum(1) != i && edge.TrigNum(2) != i) + { + topology_ok = 0; + GetTriangle(i).flags.toperror = 1; + } + } + + for (int i = 1; i <= ne; i++) + { + const STLTopEdge & edge = GetTopEdge (i); + if (!edge.TrigNum(2)) + { + topology_ok = 0; + GetTriangle(edge.TrigNum(1)).flags.toperror = 1; + } + } + + if (topology_ok) + { + orientation_ok = 1; + for (int i = 1; i <= nt; i++) + { + const STLTriangle & t = GetTriangle (i); + for (int j = 1; j <= 3; j++) + { + const STLTriangle & nbt = GetTriangle (t.NBTrigNum(j)); + if (!t.IsNeighbourFrom (nbt)) + orientation_ok = 0; + } + } + } + else + orientation_ok = 0; + + + + status = STL_GOOD; + statustext = ""; + if (!topology_ok || !orientation_ok) + { + status = STL_ERROR; + if (!topology_ok) + statustext = "Topology not ok"; + else + statustext = "Orientation not ok"; + } + + + PrintMessage(3,"topology_ok = ",topology_ok); + PrintMessage(3,"orientation_ok = ",orientation_ok); + PrintMessage(3,"topology found"); + + // generate point -> trig table + + trigsperpoint.SetSize(GetNP()); + for (int i = 1; i <= GetNT(); i++) + for (int j = 1; j <= 3; j++) + trigsperpoint.Add1(GetTriangle(i).PNum(j),i); + + + //check trigs per point: + /* + for (i = 1; i <= GetNP(); i++) + { + if (trigsperpoint.EntrySize(i) < 3) + { + (*testout) << "ERROR: Point " << i << " has " << trigsperpoint.EntrySize(i) << " triangles!!!" << endl; + } + } + */ + topedgesperpoint.SetSize (GetNP()); + for (int i = 1; i <= ne; i++) + for (int j = 1; j <= 2; j++) + topedgesperpoint.Add1 (GetTopEdge (i).PNum(j), i); + + PrintMessage(5,"point -> trig table generated"); + + + + // transfer edge data: + // .. to be done + delete oldedges; + + + + for (STLTrigIndex ti = 0; ti < GetNT(); ti++) + { + STLTriangle & trig = trias[ti]; + for (int k = 0; k < 3; k++) + { + STLPointIndex pi = trig[k] - STLBASE; + STLPointIndex pi2 = trig[(k+1)%3] - STLBASE; + STLPointIndex pi3 = trig[(k+2)%3] - STLBASE; + + // vector along edge + Vec<3> ve = points[pi2] - points[pi]; + ve.Normalize(); + + // vector along third point + Vec<3> vt = points[pi3] - points[pi]; + vt -= (vt * ve) * ve; + vt.Normalize(); + + Vec<3> vn = trig.GeomNormal (points); + vn.Normalize(); + + double phimin = 10, phimax = -1; // out of (0, 2 pi) + + for (int j = 0; j < trigsperpoint[pi].Size(); j++) + { + STLTrigIndex ti2 = trigsperpoint[pi][j] - STLBASE; + const STLTriangle & trig2 = trias[ti2]; + + if (ti == ti2) continue; + + bool hasboth = 0; + for (int l = 0; l < 3; l++) + if (trig2[l] - STLBASE == pi2) + { + hasboth = 1; + break; + } + if (!hasboth) continue; + + STLPointIndex pi4(0); + for (int l = 0; l < 3; l++) + if (trig2[l] - STLBASE != pi && trig2[l] - STLBASE != pi2) + pi4 = trig2[l] - STLBASE; + + Vec<3> vt2 = points[pi4] - points[pi]; + + double phi = atan2 (vt2 * vn, vt2 * vt); + if (phi < 0) phi += 2 * M_PI; + + if (phi < phimin) + { + phimin = phi; + trig.NBTrig (0, (k+2)%3) = ti2 + STLBASE; + } + if (phi > phimax) + { + phimax = phi; + trig.NBTrig (1, (k+2)%3) = ti2 + STLBASE; + } + } + } + } + + + + + if (status == STL_GOOD) + { + // for compatibility: + neighbourtrigs.SetSize(GetNT()); + for (int i = 1; i <= GetNT(); i++) + for (int k = 1; k <= 3; k++) + AddNeighbourTrig (i, GetTriangle(i).NBTrigNum(k)); + } + else + { + // assemble neighbourtrigs (should be done only for illegal topology): + + neighbourtrigs.SetSize(GetNT()); + + int tr, found; + int wrongneighbourfound = 0; + for (int i = 1; i <= GetNT(); i++) + { + SetThreadPercent((double)i/(double)GetNT()*100.); + if (multithread.terminate) + { + PopStatus(); + return; + } + + for (int k = 1; k <= 3; k++) + { + for (int j = 1; j <= trigsperpoint.EntrySize(GetTriangle(i).PNum(k)); j++) + { + tr = trigsperpoint.Get(GetTriangle(i).PNum(k),j); + if (i != tr && (GetTriangle(i).IsNeighbourFrom(GetTriangle(tr)) + || GetTriangle(i).IsWrongNeighbourFrom(GetTriangle(tr)))) + { + if (GetTriangle(i).IsWrongNeighbourFrom(GetTriangle(tr))) + { + /*(*testout) << "ERROR: triangle " << i << " has a wrong neighbour triangle!!!" << endl;*/ + wrongneighbourfound ++; + } + + found = 0; + for (int ii = 1; ii <= NONeighbourTrigs(i); ii++) + {if (NeighbourTrig(i,ii) == tr) {found = 1;break;};} + if (! found) {AddNeighbourTrig(i,tr);} + } + } + } + if (NONeighbourTrigs(i) != 3) + { + PrintError("TRIG ",i," has ",NONeighbourTrigs(i)," neighbours!!!!"); + for (int kk=1; kk <= NONeighbourTrigs(i); kk++) + { + PrintMessage(5,"neighbour-trig",kk," = ",NeighbourTrig(i,kk)); + } + }; + } + if (wrongneighbourfound) + { + PrintError("++++++++++++++++++++\n"); + PrintError(wrongneighbourfound, " wrong oriented neighbourtriangles found!"); + PrintError("try to correct it (with stldoctor)!"); + PrintError("++++++++++++++++++++\n"); + + status = STL_ERROR; + statustext = "STL Mesh not consistent"; + + multithread.terminate = 1; +#ifdef STAT_STREAM + (*statout) << "non-conform stl geometry \\hline" << endl; +#endif + } + } + + TopologyChanged(); + + PopStatus(); +} + + + + + + + +void STLTopology :: GetTrianglesInBox (/* + const Point<3> & pmin, + const Point<3> & pmax, + */ + const Box<3> & box, + Array & btrias) const +{ + if (searchtree) + + searchtree -> GetIntersecting (box.PMin(), box.PMax(), btrias); + + else + { + int i; + Box<3> box1 = box; + box1.Increase (1e-4); + + btrias.SetSize(0); + + int nt = GetNT(); + for (i = 1; i <= nt; i++) + { + if (box1.Intersect (GetTriangle(i).box)) + { + btrias.Append (i); + } + } + } +} + + + +void STLTopology :: AddTriangle(const STLTriangle& t) +{ + trias.Append(t); + + const Point<3> & p1 = GetPoint (t.PNum(1)); + const Point<3> & p2 = GetPoint (t.PNum(2)); + const Point<3> & p3 = GetPoint (t.PNum(3)); + + Box<3> box; + box.Set (p1); + box.Add (p2); + box.Add (p3); + /* + // Point<3> pmin(p1), pmax(p1); + pmin.SetToMin (p2); + pmin.SetToMin (p3); + pmax.SetToMax (p2); + pmax.SetToMax (p3); + */ + + trias.Last().box = box; + trias.Last().center = Center (p1, p2, p3); + double r1 = Dist (p1, trias.Last().center); + double r2 = Dist (p2, trias.Last().center); + double r3 = Dist (p3, trias.Last().center); + trias.Last().rad = max2 (max2 (r1, r2), r3); + + if (geomsearchtreeon) + {searchtree->Insert (box.PMin(), box.PMax(), trias.Size());} +} + + + + +int STLTopology :: GetLeftTrig(int p1, int p2) const +{ + int i; + for (i = 1; i <= trigsperpoint.EntrySize(p1); i++) + { + if (GetTriangle(trigsperpoint.Get(p1,i)).HasEdge(p1,p2)) {return trigsperpoint.Get(p1,i);} + } + PrintSysError("ERROR in GetLeftTrig !!!"); + + return 0; +} + +int STLTopology :: GetRightTrig(int p1, int p2) const +{ + return GetLeftTrig(p2,p1); +} + + +int STLTopology :: NeighbourTrigSorted(int trig, int edgenum) const +{ + int i, p1, p2; + int psearch = GetTriangle(trig).PNum(edgenum); + + for (i = 1; i <= 3; i++) + { + GetTriangle(trig).GetNeighbourPoints(GetTriangle(NeighbourTrig(trig,i)),p1,p2); + if (p1 == psearch) {return NeighbourTrig(trig,i);} + } + + PrintSysError("ERROR in NeighbourTrigSorted"); + return 0; +} + + + + + + +int STLTopology :: GetTopEdgeNum (int pi1, int pi2) const +{ + if (!ht_topedges) return 0; + + INDEX_2 i2(pi1, pi2); + i2.Sort(); + + if (!ht_topedges->Used(i2)) return 0; + return ht_topedges->Get(i2); +} + + + + +void STLTopology :: InvertTrig (int trig) +{ + if (trig >= 1 && trig <= GetNT()) + { + GetTriangle(trig).ChangeOrientation(); + FindNeighbourTrigs(); + } + else + { + PrintUserError("no triangle selected!"); + } +} + + + + +void STLTopology :: DeleteTrig (int trig) +{ + if (trig >= 1 && trig <= GetNT()) + { + trias.DeleteElement(trig); + FindNeighbourTrigs(); + } + else + { + PrintUserError("no triangle selected!"); + } +} + + + +void STLTopology :: OrientAfterTrig (int trig) +{ + int starttrig = trig; + + if (starttrig >= 1 && starttrig <= GetNT()) + { + + Array oriented; + oriented.SetSize(GetNT()); + int i; + for (i = 1; i <= oriented.Size(); i++) + { + oriented.Elem(i) = 0; + } + + oriented.Elem(starttrig) = 1; + + int k; + + Array list1; + list1.SetSize(0); + Array list2; + list2.SetSize(0); + list1.Append(starttrig); + + int cnt = 1; + int end = 0; + int nt; + while (!end) + { + end = 1; + for (i = 1; i <= list1.Size(); i++) + { + const STLTriangle& tt = GetTriangle(list1.Get(i)); + for (k = 1; k <= 3; k++) + { + nt = tt.NBTrigNum (k); // NeighbourTrig(list1.Get(i),k); + if (oriented.Get(nt) == 0) + { + if (tt.IsWrongNeighbourFrom(GetTriangle(nt))) + { + GetTriangle(nt).ChangeOrientation(); + } + oriented.Elem(nt) = 1; + list2.Append(nt); + cnt++; + end = 0; + } + } + } + list1.SetSize(0); + for (i = 1; i <= list2.Size(); i++) + { + list1.Append(list2.Get(i)); + } + list2.SetSize(0); + } + + PrintMessage(5,"NO corrected triangles = ",cnt); + if (cnt == GetNT()) + { + PrintMessage(5,"ALL triangles oriented in same way!"); + } + else + { + PrintWarning("NOT ALL triangles oriented in same way!"); + } + + // topedges.SetSize(0); + FindNeighbourTrigs(); + } + else + { + PrintUserError("no triangle selected!"); + } +} + + +} diff --git a/libsrc/stlgeom/stltopology.hpp b/libsrc/stlgeom/stltopology.hpp new file mode 100644 index 00000000..fbb2394f --- /dev/null +++ b/libsrc/stlgeom/stltopology.hpp @@ -0,0 +1,362 @@ +#ifndef FILE_STLTOPOLOGY +#define FILE_STLTOPOLOGY + +/**************************************************************************/ +/* File: stltopology.hpp */ +/* Author: Joachim Schoeberl */ +/* Author2: Johannes Gerstmayr */ +/* Date: 26. Jul. 99 */ +/**************************************************************************/ + +/* + The STLTopology contains topologic information as + triangle->point, point->triangles, triangle->edge, 2-points->edge,... +*/ + + +class STLGeometry; + +#define STLBASE 1 + +class STLPointIndex +{ + int i; +public: + STLPointIndex () { ; } + STLPointIndex (int ai) : i(ai) { ; } + STLPointIndex & operator= (const STLPointIndex & ai) { i = ai.i; return *this; } + STLPointIndex & operator= (int ai) { i = ai; return *this; } + operator int () const { return i; } + STLPointIndex operator++ (int) { return i++; } + STLPointIndex operator-- (int) { return i--; } +}; + + + +class STLTrigIndex +{ + int i; +public: + STLTrigIndex () { ; } + STLTrigIndex (int ai) : i(ai) { ; } + STLTrigIndex & operator= (const STLTrigIndex & ai) { i = ai.i; return *this; } + STLTrigIndex & operator= (int ai) { i = ai; return *this; } + operator int () const { return i; } + STLTrigIndex operator++ (int) { return i++; } + STLTrigIndex operator-- (int) { return i--; } +}; + + + + + +// triangle structure for loading stl files +class STLReadTriangle +{ + Vec<3> normal; + Point<3> pts[3]; +public: + STLReadTriangle (const Point<3> * apts, const Vec<3> & anormal); + STLReadTriangle () {}; + const Point<3> & operator[] (int i) const { return pts[i]; } + const Vec<3> & Normal() const { return normal; } +}; + + + +class STLTriangle +{ + // topology edges of triangle, edge[i] opposite to point[i] + int topedges[3]; + // neighbour triangles, trig[i] opposite to point[i] + int nbtrigs[2][3]; + // normalized stored normal vector ?? + Vec<3> normal; + // point numbers of triangle + int pts[3]; + // front-side and back-side domains + int domains[2]; + + +public: + + Box<3> box; + Point<3> center; + double rad; + int facenum; + + struct + { + unsigned int toperror : 1; + } flags; + + + + + STLTriangle (const int * apts); + STLTriangle () {pts[0]=0;pts[1]=0;pts[2]=0;} + + int operator[] (int i) const { return pts[i]; } + int & operator[] (int i) { return pts[i]; } + + int EdgeNum(int i) const { return topedges[(i-1)]; } + int & EdgeNum(int i) { return topedges[(i-1)]; } + + int NBTrig (bool side, int i) const { return nbtrigs[side][i]; } + int & NBTrig (bool side, int i) { return nbtrigs[side][i]; } + + + int Domain (bool side) const { return domains[side]; } + int & Domain (bool side) { return domains[side]; } + + + + // obsolete: + int PNum(int i) const { return pts[(i-1)]; } + int & PNum(int i) { return pts[(i-1)]; } + int PNumMod(int i) const { return pts[(i-1)%3]; } + int & PNumMod(int i) { return pts[(i-1)%3]; } + + int EdgeNumMod(int i) const { return topedges[(i-1)%3]; } + int & EdgeNumMod(int i) { return topedges[(i-1)%3]; } + + int NBTrigNum(int i) const { return nbtrigs[0][(i-1)]; } + int & NBTrigNum(int i) { return nbtrigs[0][(i-1)]; } + int NBTrigNumMod(int i) const { return nbtrigs[0][(i-1)%3]; } + int & NBTrigNumMod(int i) { return nbtrigs[0][(i-1)%3]; } + + + // consistently oriented neighbour: + int IsNeighbourFrom(const STLTriangle& t) const; + // opposite to consistently oriented neighbour: + int IsWrongNeighbourFrom(const STLTriangle& t) const; + + ///Get the two points of neighbour-Triangles in orientation of this-Triangle + void GetNeighbourPoints(const STLTriangle& t, int& p1, int& p2) const; + int GetNeighbourPointsAndOpposite(const STLTriangle& t, int& p1, int& p2, int& po) const; + + + + // NON-normalized geometry - normal vector + Vec<3> GeomNormal(const Array >& ap) const; + + // Stored normal vector, normalized + void SetNormal (const Vec<3> & n); + const Vec<3> & Normal () const { return normal; } + + + void ChangeOrientation(); + + //project with a certain normal vector in plane + void ProjectInPlain(const Array >& ap, + const Vec<3> & n, Point<3> & pp) const; + //project with the triangle's normal vector in plane + void ProjectInPlain(const Array > & ap, Point<3> & pp) const; + + + /* + Project the point pp along the nproj into the plane of + the triangle. The triangle normal is given by ntrig to + avoid numerical instabilities. + The local coordinates lam are defined by + + pp(input) = P1 + lam1 v1 + lam2 v2 + lam3 n + + the result is + + pp(output) = P1 + lam1 v1 + lam2 v2 + */ + int ProjectInPlain (const Array >& ap, + const Vec<3> & nproj, + Point<3> & pp, Vec<3> & lam) const; + + int PointInside(const Array >& ap, const Point<3> & pp) const; + + //get nearest point on triangle and distance to it + double GetNearestPoint(const Array >& ap, + Point<3> & p3d) const; + + double Area(const Array >& ap) const; + + double MinHeight(const Array >& ap) const; + double MaxLength(const Array >& ap) const; + //max length of a side of triangle + + int GetFaceNum() {return facenum;} + void SetFaceNum(int i) {facenum = i;} + + int HasEdge(int p1, int p2) const; +}; + + +/** + Topology Edge: + Useful unside a face. + A edges sharing more than 2 faces: trigs are undefined + */ +class STLTopEdge +{ + int pts[2]; + int trigs[2]; + double cosangle; + int status; // excluded, confirmed, candidate, undefined +public: + STLTopEdge (); + STLTopEdge (int p1, int p2, int trig1, int trig2); + + int operator[] (int i) const { return pts[i]; } + int & operator[] (int i) { return pts[i]; } + + + int PNum(int i) const { return pts[(i-1)]; } + int & PNum(int i) { return pts[(i-1)]; } + int PNumMod(int i) const { return pts[(i-1)%2]; } + int & PNumMod(int i) { return pts[(i-1)%2]; } + + int TrigNum(int i) const { return trigs[(i-1)]; } + int & TrigNum(int i) { return trigs[(i-1)]; } + int TrigNumMod(int i) const { return trigs[(i-1)%2]; } + int & TrigNumMod(int i) { return trigs[(i-1)%2]; } + + void SetCosAngle (double ca) { cosangle = ca; } + double CosAngle () const { return cosangle; } + double Angle () const { return acos (cosangle); } + + void SetStatus (int stat) { status = stat; } + int GetStatus () const { return status; } +}; + + + +ostream& operator<<(ostream& os, const STLTriangle& t); + + + + + + + +class STLTopology +{ +protected: + Array trias; + Array topedges; + Array > points; + + // mapping of sorted pair of points to topedge + INDEX_2_HASHTABLE * ht_topedges; + // mapping of node to trigs + TABLE trigsperpoint; + // mapping of node to edges + TABLE topedgesperpoint; + + // searchtree for trigs and points + + Box3dTree * searchtree; // ADT + Point3dTree * pointtree; + + Box<3> boundingbox; + double pointtol; + +public: + enum STL_GEOM_STATUS { STL_GOOD, STL_WARNING, STL_ERROR }; + +protected: + STL_GEOM_STATUS status; + string statustext; + + bool topology_ok; + bool orientation_ok; + +public: + STLTopology(); + virtual ~STLTopology(); + + static STLGeometry * LoadNaomi (istream & ist); + static STLGeometry * Load (istream & ist); + static STLGeometry * LoadBinary (istream & ist); + + void Save (const char* filename) const; + void SaveBinary (const char* filename, const char* aname) const; + void SaveSTLE (const char * filename) const; // stores trigs and edges + + virtual void InitSTLGeometry (const Array & readtrigs); + + virtual void TopologyChanged() {}; //do some things, if topology changed! + + /// Generate topology tables + void FindNeighbourTrigs(); + + + void GetTrianglesInBox (const Box<3> & box, + Array & trias) const; + + + int GetNP() const { return points.Size(); } + int AddPoint(const Point<3> & p) { return points.Append(p); } + const Point<3> & GetPoint(int nr) const { return points.Get(nr); } + int GetPointNum (const Point<3> & p); + void SetPoint(int nr, const Point<3> & p) { points.Elem(nr) = p; } + const Array >& GetPoints() const { return points; } + + const Point<3> & operator[] (STLPointIndex i) const { return points[i]; } + Point<3> & operator[] (STLPointIndex i) { return points[i]; } + + + + + int GetNT() const { return trias.Size(); } + void AddTriangle(const STLTriangle& t); + const STLTriangle & GetTriangle (int nr) const { return trias.Get(nr); } + STLTriangle & GetTriangle (int nr) { return trias.Elem(nr); } + + const STLTriangle & operator[] (STLTrigIndex i) const { return trias[i]; } + STLTriangle & operator[] (STLTrigIndex i) { return trias[i]; } + + + int GetNTE() const { return topedges.Size(); } + const STLTopEdge & GetTopEdge (int nr) const { return topedges.Get(nr); } + STLTopEdge & GetTopEdge (int nr) { return topedges.Elem(nr); } + int GetTopEdgeNum (int pi1, int pi2) const; + + + int NOTrigsPerPoint(int pn) { return trigsperpoint.EntrySize(pn); } + int TrigPerPoint(int pn, int i) { return trigsperpoint.Get(pn, i); } + + + int NTopEdgesPerPoint (int pn) const { return topedgesperpoint.EntrySize(pn); } + int TopEdgePerPoint (int pn, int ei) const { return topedgesperpoint.Get(pn, ei); } + + + bool Topology_Ok() const { return topology_ok; } + bool Orientation_Ok() const { return orientation_ok; } + + STL_GEOM_STATUS GetStatus () const { return status; } + const string & GetStatusText () const { return statustext; } + + void InvertTrig (int trig); + void DeleteTrig (int trig); + void OrientAfterTrig (int trig); + + + // Table will be constructed, if topology is not ok + /// neighbourtrigs for surfacetrigs + TABLE neighbourtrigs; + + /// get nr-th neighbour Triangle for triangle trig + int NONeighbourTrigs(int trig) const { return neighbourtrigs.EntrySize(trig); } + int NeighbourTrig(int trig, int nr) const { return neighbourtrigs.Get(trig,nr); } + int NeighbourTrigSorted(int trig, int nr) const; + void AddNeighbourTrig(int i, int nt) { neighbourtrigs.Add1(i, nt); } + + + + + int GetLeftTrig (int p1, int p2) const; + int GetRightTrig (int p1, int p2) const; + + const Box<3> & GetBoundingBox () const { return boundingbox; } +}; + + +#endif diff --git a/libsrc/stlgeom/vsstl.cpp b/libsrc/stlgeom/vsstl.cpp new file mode 100644 index 00000000..338c305d --- /dev/null +++ b/libsrc/stlgeom/vsstl.cpp @@ -0,0 +1,1212 @@ +#include +#include + +#include +#include + +#include +#include + + +#include "vsstl.hpp" + + +namespace netgen +{ + +/* +//mmm +#include "stlgeom/modeller.hpp" +*/ + +/* *********************** Draw STL Geometry **************** */ + +extern STLGeometry * stlgeometry; +extern AutoPtr mesh; + + +// #include "../../ngtcltk/mvdraw.hpp" + + +VisualSceneSTLMeshing :: VisualSceneSTLMeshing () + : VisualScene() +{ + selecttrig = 0; + nodeofseltrig = 1; + stlgeometry->SetSelectTrig(selecttrig); + stlgeometry->SetNodeOfSelTrig(nodeofseltrig); +} + +VisualSceneSTLMeshing :: ~VisualSceneSTLMeshing () +{ + ; +} + +void VisualSceneSTLMeshing :: DrawScene () +{ + int i, j, k; + + if (changeval != stlgeometry->GetNT()) + BuildScene(); + changeval = stlgeometry->GetNT(); + + int colormeshsize = vispar.colormeshsize; + + double hmin = 0.0, hmax = 1.0; + + if (colormeshsize) + { + hmax = -1E50; + hmin = +1E50; + double ms; + + for (i = 1; i <= stlgeometry->GetNP(); i++) + { + ms = mesh->GetH (stlgeometry->GetPoint(i)); + hmin = min2(hmin,ms); + hmax = max2(hmax,ms); + } + + //hmax = mparam.maxh; + //hmin = mesh->GetMinH (stlgeometry->GetBoundingBox().PMin(), + // stlgeometry->GetBoundingBox().PMax()); + + if (hmin == 0) hmin = 0.1 * hmax; + //hmax *= 1.1; + } + + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + + SetLight(); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + SetClippingPlane (); + + glShadeModel (GL_SMOOTH); + glDisable (GL_COLOR_MATERIAL); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + float mat_spec_col[] = { 1, 1, 1, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); + + double shine = vispar.shininess; + // double transp = vispar.transp; + + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); + glLogicOp (GL_COPY); + + float mat_colred[] = { 0.9f, 0.0f, 0.0f, 1.0f }; + float mat_colgreen[] = { 0.0f, 0.9f, 0.0f, 1.0f }; + float mat_colblue[] = { 0.1f, 0.1f, 1.0f, 1.0f }; + + float mat_colbluegreen[] = { 0.1f, 0.5f, 0.9f, 1.0f }; + // float mat_colpink[] = { 1.0f, 0.1f, 0.5f, 1.0f }; + float mat_colviolet[] = { 1.0f, 0.1f, 1.0f, 1.0f }; + float mat_colbrown[] = { 0.8f, 0.6f, 0.1f, 1.0f }; + // float mat_colorange[] = { 0.9f, 0.7f, 0.1f, 1.0f }; + // float mat_colturquis[] = { 0.0f, 1.0f, 0.8f, 1.0f }; + + float mat_colgrey[] = { 0.3f, 0.3f, 0.3f, 1.0f }; + + float mat_collred[] = { 1.0f, 0.5f, 0.5f, 1.0f }; + float mat_collgreen[] = { 0.2f, 1.9f, 0.2f, 1.0f }; + float mat_collbrown[] = { 1.0f, 0.8f, 0.3f, 1.0f }; + + float mat_collgrey[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + // float mat_colmgrey[] = { 0.4f, 0.4f, 0.4f, 1.0f }; + + float mat_colstlbody[] = { 0.0f, 0.0f, 0.8f, 1.0f }; + float mat_colseltrig[] = { 0.7f, 0.7f, 0.3f, 1.0f }; + float mat_colseledge[] = { 0.7f, 0.7f, 1.0f, 1.0f }; + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colblue); + + float pgoff = 0.5f; + + glPolygonOffset (pgoff*1, pgoff*1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glEnable (GL_NORMALIZE); + + /* + { + //mmm + //test modeller + Modeller model; + + //MoZylinder z1(Point3d(0,0,0),Vec3d(100,0,0),20,0.01); + //model.Add(&z1); + //MoZylinder z2(Point3d(50,50,0),Vec3d(0,-100,0),20,0.01); + //model.Add(&z2); + + MoZylinder z1(Point3d(0,0,0),Vec3d(100,0,0),20,0.01); + MoZylinder z2(Point3d(50,50,0),Vec3d(0,-100,0),20,0.01); + MoCombine cb1(&z1,&z2); + model.Add(&cb1); + + Array trigs; + model.GetTriangles(trigs); + int i, k; + glBegin (GL_TRIANGLES); + for (i = 1; i <= trigs.Size(); i++) + { + const MoTriangle & tria = trigs.Get(i); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + + for (k = 0; k < 3; k++) + { + glVertex3f (tria.pts[k].X(), + tria.pts[k].Y(), + tria.pts[k].Z()); + } + } + glEnd (); + + + } + +*/ + + + + + if (!stlgeometry->trigsconverted) + { + glBegin (GL_TRIANGLES); + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + /* + if (j % 10 == seltria) + glMaterialfv (GL_FRONT_AND_BACK, + GL_AMBIENT_AND_DIFFUSE, mat_colred); + */ + + const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + /* + const STLReadTriangle & tria = stlgeometry -> GetReadTriangle(j); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + + + for (k = 1; k <= 3; k++) + { + const Point3d & tp = stlgeometry->GetPoint(stlgeometry->GetTriangle(j).PNum(k)); + glVertex3f (tp.X(), tp.Y(), tp.Z()); + + } + /* + if (j%10 == seltria) + glMaterialfv (GL_FRONT_AND_BACK, + GL_AMBIENT_AND_DIFFUSE, mat_colblue); + */ + } + glEnd (); + + glDisable (GL_POLYGON_OFFSET_FILL); + + int showtrias = vispar.stlshowtrias; + + if (showtrias) + { + float mat_coll[] = { 0.2f, 0.2f, 0.2f, 1.f }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_coll); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + glEnable (GL_NORMALIZE); + + glBegin (GL_TRIANGLES); + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + /* + const STLReadTriangle & tria = stlgeometry -> GetReadTriangle(j); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + + for (k = 1; k <= 3; k++) + { + const Point3d & tp = + stlgeometry->GetPoint(stlgeometry->GetTriangle(j).PNum(k)); + glVertex3f (tp.X(), tp.Y(), tp.Z()); + + } + + /* + for (k = 0; k < 3; k++) + { + glVertex3f (tria.pts[k].X(), + tria.pts[k].Y(), + tria.pts[k].Z()); + } + */ + } + glEnd (); + } + } + else + { + int showfilledtrias = vispar.stlshowfilledtrias; + + //(*mycout) << "in " << showfilledtrias << ", NT=" << stlgeometry -> GetNT() << endl; + + int chartnumber; + if (vispar.stlshowmarktrias) + chartnumber = vispar.stlchartnumber + vispar.stlchartnumberoffset; + else + chartnumber = stlgeometry->GetMeshChartNr(); + + if (showfilledtrias) + { + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + if (colormeshsize) + glEnable (GL_COLOR_MATERIAL); + + glPolygonOffset (pgoff*4, pgoff*4); + glEnable (GL_POLYGON_OFFSET_FILL); + glEnable (GL_NORMALIZE); + + + glBegin (GL_TRIANGLES); + + int selt = stlgeometry -> GetSelectTrig(); + if (stldoctor.selectmode != 0) + {selt = 0; } //do not show selected triangle!!!! + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colstlbody); + + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) {continue;} + + if (j == selt) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colseltrig); + } + else if (j == selt+1) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colstlbody); + } + + const STLTriangle& st = stlgeometry -> GetTriangle(j); + + const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + + /* + const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + for (k = 0; k < 3; k++) + { + const Point3d & p = stlgeometry->GetPoint(st[k]); + if (colormeshsize) + { + SetOpenGlColor (mesh->GetH (p), hmin, hmax, 1); + } + + glVertex3f (p.X(), p.Y(), p.Z()); + } + } + + glEnd (); + } + + int foundseltrig = stlgeometry -> GetSelectTrig(); + if (foundseltrig == 0 || foundseltrig > stlgeometry->GetNT() || + (stldoctor.showvicinity && !stlgeometry->Vicinity(foundseltrig))) + {foundseltrig = 0;} + + if (foundseltrig) + { + + glPolygonOffset (pgoff*0, 0); + glEnable (GL_POLYGON_OFFSET_FILL); + + //glDisable (GL_POLYGON_OFFSET_FILL); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colseledge); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + glEnable (GL_NORMALIZE); + + if (stldoctor.selectmode == 2) + { + //point + const STLTriangle& st = stlgeometry -> GetTriangle(foundseltrig); + const Point3d & p1 = stlgeometry->GetPoint(st[0]); + const Point3d & p2 = stlgeometry->GetPoint(st[1]); + const Point3d & p3 = stlgeometry->GetPoint(st[2]); + + double cs = (Dist(p1,p2)+Dist(p2,p3)+Dist(p3,p1))/100.; + + const Point3d & p = stlgeometry->GetPoint(st[nodeofseltrig-1]); + + glLineWidth (4); + glBegin (GL_LINES); + glVertex3f(p.X()+cs, p.Y()+cs, p.Z()+cs); + glVertex3f(p.X()-cs, p.Y()-cs, p.Z()-cs); + + glVertex3f(p.X()-cs, p.Y()+cs, p.Z()+cs); + glVertex3f(p.X()+cs, p.Y()-cs, p.Z()-cs); + + glVertex3f(p.X()-cs, p.Y()+cs, p.Z()+cs); + glVertex3f(p.X()+cs, p.Y()-cs, p.Z()-cs); + + glVertex3f(p.X()+cs, p.Y()-cs, p.Z()+cs); + glVertex3f(p.X()-cs, p.Y()+cs, p.Z()-cs); + + glEnd (); + glLineWidth (1); + } + else if (stldoctor.selectmode == 1 || + stldoctor.selectmode == 3 || + stldoctor.selectmode == 4) + { + //multiedge + + const Array& me = stlgeometry->SelectedMultiEdge(); + if (stlgeometry->GetSelectTrig() > 0 && + stlgeometry->GetSelectTrig() <= stlgeometry->GetNT() && + me.Size()) + { + + int en = stlgeometry->EdgeDataList().GetEdgeNum(me.Get(1).i1,me.Get(1).i2); + int status = stlgeometry->EdgeDataList().Get(en).GetStatus(); + + switch (status) + { + case ED_CONFIRMED: + glMaterialfv (GL_FRONT_AND_BACK, + GL_AMBIENT_AND_DIFFUSE, mat_collgreen); + break; + case ED_CANDIDATE: + glMaterialfv (GL_FRONT_AND_BACK, + GL_AMBIENT_AND_DIFFUSE, mat_collbrown); + break; + case ED_EXCLUDED: + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_collred); + break; + } + + glLineWidth (2); + glBegin (GL_LINES); + for (j = 1; j <= me.Size(); j++) + { + Point3d p1 = stlgeometry->GetPoint(me.Get(j).i1); + Point3d p2 = stlgeometry->GetPoint(me.Get(j).i2); + + glVertex3f(p1.X(), p1.Y(), p1.Z()); + glVertex3f(p2.X(), p2.Y(), p2.Z()); + } + glEnd (); + glLineWidth (1); + } + } + } + + int showmarktrias = vispar.stlshowmarktrias || vispar.stlshowactivechart; + + if (stldoctor.showmarkedtrigs) + { + //(*mycout) << "marked" << endl; + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); //GL_LINE + glPolygonOffset (pgoff*1, pgoff*1); + glEnable (GL_POLYGON_OFFSET_FILL); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbluegreen); + glEnable (GL_NORMALIZE); + + glBegin (GL_TRIANGLES); + + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) + {continue;} + + if (!stlgeometry->IsMarkedTrig(j)) + {continue;} + + const STLTriangle& st = stlgeometry -> GetTriangle(j); + + const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + /* + const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + for (k = 0; k < 3; k++) + { + const Point3d & p = stlgeometry->GetPoint(st[k]); + glVertex3f (p.X(), p.Y(), p.Z()); + } + } + glEnd (); + + //show OpenSegments on original geometry + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colviolet); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glPolygonOffset (pgoff*1, 1); + + glEnable (GL_NORMALIZE); + + glBegin (GL_LINES); + + if (stlgeometry->GetNMarkedSegs()) + { + Point<3> p1,p2; + for (j = 1; j <= stlgeometry -> GetNMarkedSegs(); j++) + { + stlgeometry->GetMarkedSeg(j,p1,p2); + glVertex3dv(&p1(0)); + glVertex3dv(&p2(0)); + } + } + glEnd (); + } + + + if (stldoctor.showfaces) + { + int facenumber = vispar.stlchartnumber + vispar.stlchartnumberoffset; + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glPolygonOffset (pgoff*3, 3); + glEnable (GL_POLYGON_OFFSET_FILL); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_collgrey); + glEnable (GL_NORMALIZE); + + glBegin (GL_TRIANGLES); + + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) + {continue;} + + //(*mycout) << " facenum = " << stlgeometry->GetTriangle(j).GetFaceNum() << " "; + if (stlgeometry->GetTriangle(j).GetFaceNum() != facenumber) + {continue;} + + const STLTriangle& st = stlgeometry -> GetTriangle(j); + + const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + /* + const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + for (k = 0; k < 3; k++) + { + Point3d p = stlgeometry->GetPoint(st[k]); + glVertex3f (p.X(), p.Y(), p.Z()); + } + } + glEnd (); + } + + if (showmarktrias && stlgeometry->AtlasMade()) + { + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glPolygonOffset (pgoff*3, 3); + glEnable (GL_POLYGON_OFFSET_FILL); + + glBegin (GL_TRIANGLES); + + if (chartnumber >= 1 && chartnumber <= stlgeometry->GetNOCharts()) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbrown); + const STLChart& chart = stlgeometry->GetChart(chartnumber); + for (j = 1; j <= chart.GetNChartT(); j++) + { + /* + if (j == charttrignumber) + {glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred);} + else + {glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colbrown);} + */ + const STLTriangle& st = stlgeometry -> GetTriangle(chart.GetChartTrig(j)); + + + const Vec3d & n = stlgeometry->GetTriangle(chart.GetChartTrig(j)).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + /* + const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(chart.GetChartTrig(j)); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + for (k = 0; k < 3; k++) + { + glVertex3f (stlgeometry->GetPoint(st[k])(0), + stlgeometry->GetPoint(st[k])(1), + stlgeometry->GetPoint(st[k])(2)); + } + } + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); + + for (j = 1; j <= chart.GetNOuterT(); j++) + { + + const STLTriangle& st = stlgeometry -> GetTriangle(chart.GetOuterTrig(j)); + + const Vec3d & n = stlgeometry->GetTriangle(chart.GetOuterTrig(j)).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + + + /* + const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(chart.GetOuterTrig(j)); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + for (k = 0; k < 3; k++) + { + glVertex3f (stlgeometry->GetPoint(st[k])(0), + stlgeometry->GetPoint(st[k])(1), + stlgeometry->GetPoint(st[k])(2)); + } + } + } + glEnd (); + } + + int showtrias = vispar.stlshowtrias; + + if (showtrias) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgrey); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glPolygonOffset (pgoff*2, 2); + glEnable (GL_POLYGON_OFFSET_FILL); + glEnable (GL_NORMALIZE); + + glBegin (GL_TRIANGLES); + + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) {continue;} + + const STLTriangle& st = stlgeometry -> GetTriangle(j); + + const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + /* + const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + */ + for (k = 0; k < 3; k++) + { + glVertex3f (stlgeometry->GetPoint(st[k])(0), + stlgeometry->GetPoint(st[k])(1), + stlgeometry->GetPoint(st[k])(2)); + } + } + glEnd (); + } + + int showedges = vispar.stlshowedges; + + if (showedges) + { + glPolygonOffset (pgoff*1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + //glDisable (GL_POLYGON_OFFSET_FILL); + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + glEnable (GL_NORMALIZE); + + glBegin (GL_LINES); + + /* + if (stldoctor.useexternaledges) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colorange); + for (j = 1; j <= stlgeometry -> NOExternalEdges(); j++) + { + twoint v = stlgeometry->GetExternalEdge(j); + Point3d p1 = stlgeometry->GetPoint(v.i1); + Point3d p2 = stlgeometry->GetPoint(v.i2); + + Vec3d n1 = stlgeometry->GetNormal(v.i1); + Vec3d n2 = stlgeometry->GetNormal(v.i2); + + glNormal3f(n1.X(), n1.Y(), n1.Z()); + glVertex3f(p1.X(), p1.Y(), p1.Z()); + glNormal3f(n2.X(), n2.Y(), n2.Z()); + glVertex3f(p2.X(), p2.Y(), p2.Z()); + } + } + */ + + + if (!stlgeometry->meshlines.Size() || !stldoctor.drawmeshededges) + { + /* + for (j = 1; j <= stlgeometry -> GetNE(); j++) + { + STLEdge v = stlgeometry->GetEdge(j); + Point3d p1 = stlgeometry->GetPoint(v.pts[0]); + Point3d p2 = stlgeometry->GetPoint(v.pts[1]); + + Vec3d n1 = stlgeometry->GetNormal(v.pts[0]); + Vec3d n2 = stlgeometry->GetNormal(v.pts[1]); + + glNormal3f(n1.X(), n1.Y(), n1.Z()); + glVertex3f(p1.X(), p1.Y(), p1.Z()); + glNormal3f(n2.X(), n2.Y(), n2.Z()); + glVertex3f(p2.X(), p2.Y(), p2.Z()); + } + */ + const STLEdgeDataList& ed = stlgeometry->EdgeDataList(); + for (i = 1; i <= ed.Size(); i++) + { + if (ed.Get(i).GetStatus() != ED_UNDEFINED) + { + switch (ed.Get(i).GetStatus()) + { + case ED_CONFIRMED: + glMaterialfv (GL_FRONT_AND_BACK, + GL_AMBIENT_AND_DIFFUSE, mat_colgreen); + break; + case ED_CANDIDATE: + glMaterialfv (GL_FRONT_AND_BACK, + GL_AMBIENT_AND_DIFFUSE, mat_colbrown); + break; + case ED_EXCLUDED: + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred); + break; + } + + if (ed.Get(i).GetStatus() == ED_EXCLUDED && !stldoctor.showexcluded) continue; + + Point3d p1 = stlgeometry->GetPoint(ed.Get(i).PNum(1)); + Point3d p2 = stlgeometry->GetPoint(ed.Get(i).PNum(2)); + glVertex3f(p1.X(), p1.Y(), p1.Z()); + glVertex3f(p2.X(), p2.Y(), p2.Z()); + } + } + } + + /* + else + if (stlgeometry->meshlines.Size() == 0) + { + for (j = 1; j <= stlgeometry->GetNLines(); j++) + { + STLLine* line = stlgeometry->GetLine(j); + int pn1, pn2; + for (int k = 1; k <= line->NP()-1; k++) + { + pn1 = line->PNum(k); + pn2 = line->PNum(k+1); + + Point3d p1 = stlgeometry->GetPoint(pn1); + Point3d p2 = stlgeometry->GetPoint(pn2); + + Vec3d n1 = stlgeometry->GetNormal(pn1); + Vec3d n2 = stlgeometry->GetNormal(pn2); + + glNormal3f(n1.X(), n1.Y(), n1.Z()); + glVertex3f(p1.X(), p1.Y(), p1.Z()); + glNormal3f(n2.X(), n2.Y(), n2.Z()); + glVertex3f(p2.X(), p2.Y(), p2.Z()); + } + } + } + */ + + else if (stlgeometry->meshlines.Size() != 0) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); + for (j = 1; j <= stlgeometry->meshlines.Size(); j++) + { + STLLine* line = stlgeometry->meshlines.Get(j); + int pn1, pn2; + for (int k = 1; k <= line->NP()-1; k++) + { + pn1 = line->PNum(k); + pn2 = line->PNum(k+1); + + Point3d p1 = stlgeometry->meshpoints.Get(pn1); + Point3d p2 = stlgeometry->meshpoints.Get(pn2); + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colgreen); + glVertex3f(p1.X(), p1.Y(), p1.Z()); + glVertex3f(p2.X(), p2.Y(), p2.Z()); + + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred); + double cs = 0.02*Dist(p1,p2); + glVertex3f(p1.X()+cs, p1.Y()+cs, p1.Z()+cs); + glVertex3f(p1.X()-cs, p1.Y()-cs, p1.Z()-cs); + glVertex3f(p2.X()+cs, p2.Y()+cs, p2.Z()+cs); + glVertex3f(p2.X()-cs, p2.Y()-cs, p2.Z()-cs); + + glVertex3f(p1.X()-cs, p1.Y()+cs, p1.Z()+cs); + glVertex3f(p1.X()+cs, p1.Y()-cs, p1.Z()-cs); + glVertex3f(p2.X()-cs, p2.Y()+cs, p2.Z()+cs); + glVertex3f(p2.X()+cs, p2.Y()-cs, p2.Z()-cs); + + } + } + } + + + glEnd (); + } + + if (stldoctor.showedgecornerpoints && stlgeometry->LineEndPointsSet()) + { + glPointSize (5); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_colred); + glBegin (GL_POINTS); + for (i = 1; i <= stlgeometry->GetNP(); i++) + { + if (stlgeometry->IsLineEndPoint(i)) + { + const Point3d p = stlgeometry->GetPoint(i); + glVertex3f (p.X(), p.Y(), p.Z()); + } + } + glEnd(); + + } + + + } + + + glPopMatrix(); + + if (vispar.colormeshsize) + DrawColorBar (hmin, hmax, 1); + + glFinish(); +} + + +void VisualSceneSTLMeshing :: BuildScene (int zoomall) +{ + if (selecttrig && zoomall == 2) + center = stlgeometry -> GetPoint ( stlgeometry->GetTriangle(selecttrig).PNum(nodeofseltrig)); + else + center = stlgeometry -> GetBoundingBox().Center(); + + rad = stlgeometry -> GetBoundingBox().Diam() / 2; + + CalcTransformationMatrices(); +} + + + +void VisualSceneSTLMeshing :: MouseDblClick (int px, int py) +{ + // (*mycout) << "dblclick: " << px << " - " << py << endl; + + + int i, j, k, hits; + + // select surface triangle by mouse click + + GLuint selbuf[10000]; + glSelectBuffer (10000, selbuf); + + + glRenderMode (GL_SELECT); + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + /* + (*mycout) << "viewport = " << viewport[0] << " " + << viewport[1] << " " << viewport[2] << " " << viewport[3] << endl; + */ + + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + + + GLdouble projmat[16]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + + glLoadIdentity(); + gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); + glMultMatrixd (projmat); + + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_MODELVIEW); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + + glInitNames(); + glPushName (1); + + + glEnable (GL_POLYGON_OFFSET_FILL); + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + if (stldoctor.showvicinity && !stlgeometry->Vicinity(j)) {continue;} + + const STLTriangle& st = stlgeometry -> GetTriangle(j); + + //const STLReadTriangle& tria = stlgeometry -> GetReadTriangle(j); + //glNormal3f (tria.normal.X(), tria.normal.Y(), tria.normal.Z()); + + if (stldoctor.selectmode == 0) + { + glLoadName (j); + glBegin (GL_TRIANGLES); + for (k = 0; k < 3; k++) + { + Point3d p = stlgeometry->GetPoint(st[k]); + glVertex3f (p.X(), p.Y(), p.Z()); + } + glEnd (); + } + else if (stldoctor.selectmode == 1 || stldoctor.selectmode == 3 + || stldoctor.selectmode == 4) + { + Point3d pm = Center(stlgeometry->GetPoint(st[0]), + stlgeometry->GetPoint(st[1]), + stlgeometry->GetPoint(st[2])); + + for (k = 0; k < 3; k++) + { + glLoadName (j*3+k-2); + glBegin (GL_TRIANGLES); + + Point3d p1 = stlgeometry->GetPoint(st[k]); + Point3d p2 = stlgeometry->GetPoint(st[(k+1)%3]); + glVertex3f (p1.X(), p1.Y(), p1.Z()); + glVertex3f (p2.X(), p2.Y(), p2.Z()); + glVertex3f (pm.X(), pm.Y(), pm.Z()); + + glEnd (); + } + } + else + { + Point3d pm1 = Center(stlgeometry->GetPoint(st[0]), + stlgeometry->GetPoint(st[1])); + Point3d pm2 = Center(stlgeometry->GetPoint(st[1]), + stlgeometry->GetPoint(st[2])); + Point3d pm3 = Center(stlgeometry->GetPoint(st[2]), + stlgeometry->GetPoint(st[0])); + + Point3d p1 = stlgeometry->GetPoint(st[0]); + Point3d p2 = stlgeometry->GetPoint(st[1]); + Point3d p3 = stlgeometry->GetPoint(st[2]); + + glLoadName (j*4-3); + glBegin (GL_TRIANGLES); + glVertex3f (p1.X(), p1.Y(), p1.Z()); + glVertex3f (pm1.X(), pm1.Y(), pm1.Z()); + glVertex3f (pm3.X(), pm3.Y(), pm3.Z()); + glEnd (); + + glLoadName (j*4-2); + glBegin (GL_TRIANGLES); + glVertex3f (p2.X(), p2.Y(), p2.Z()); + glVertex3f (pm2.X(), pm2.Y(), pm2.Z()); + glVertex3f (pm1.X(), pm1.Y(), pm1.Z()); + glEnd (); + + glLoadName (j*4-1); + glBegin (GL_TRIANGLES); + glVertex3f (p3.X(), p3.Y(), p3.Z()); + glVertex3f (pm3.X(), pm3.Y(), pm3.Z()); + glVertex3f (pm2.X(), pm2.Y(), pm2.Z()); + glEnd (); + + glLoadName (j*4); + glBegin (GL_TRIANGLES); + glVertex3f (pm1.X(), pm1.Y(), pm1.Z()); + glVertex3f (pm2.X(), pm2.Y(), pm2.Z()); + glVertex3f (pm3.X(), pm3.Y(), pm3.Z()); + glEnd (); + } + } + + glPopName(); + + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + + glFlush(); + + + hits = glRenderMode (GL_RENDER); + + // (*mycout) << "hits = " << hits << endl; + + //int minrec = -1; + int minname = 0; + GLuint mindepth = 0; + for (i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + GLuint curdepth = selbuf[4*i+1]; + + /* + (*mycout) << selbuf[4*i] << " " << selbuf[4*i+1] << " " + << selbuf[4*i+2] << " " << selbuf[4*i+3] << endl; + */ + if (curname && + (curdepth < mindepth || !minname)) + { + //minrec = i; + mindepth = curdepth; + minname = curname; + } + } + + if (!minname) {return;} + + if (stldoctor.selectmode == 0) + { + int oldtrig = selecttrig; + selecttrig = minname; + if (selecttrig == oldtrig) + nodeofseltrig = (nodeofseltrig % 3) + 1; + else + nodeofseltrig = 1; + + stlgeometry->SetSelectTrig(selecttrig); + stlgeometry->SetNodeOfSelTrig(nodeofseltrig); + stlgeometry->PrintSelectInfo(); + + } + else if (stldoctor.selectmode == 1 || stldoctor.selectmode == 3 || stldoctor.selectmode == 4) + { + selecttrig = (minname-1) / 3 + 1; + nodeofseltrig = minname-selecttrig*3+3; + + stlgeometry->SetSelectTrig(selecttrig); + stlgeometry->SetNodeOfSelTrig(nodeofseltrig); + stlgeometry->PrintSelectInfo(); + + if (stldoctor.selectmode == 1) + { + stlgeometry->BuildSelectedEdge(twoint(stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig), + stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig+1))); + } + if (stldoctor.selectmode == 3) + { + stlgeometry->BuildSelectedMultiEdge(twoint(stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig), + stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig+1))); + } + else if (stldoctor.selectmode == 4) + { + stlgeometry->BuildSelectedCluster(twoint(stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig), + stlgeometry->GetTriangle(selecttrig).PNumMod(nodeofseltrig+1))); + } + + switch (stldoctor.edgeselectmode) + { + case 1: stlgeometry->STLDoctorUndefinedEdge(); break; + case 2: stlgeometry->STLDoctorConfirmEdge(); break; + case 3: stlgeometry->STLDoctorCandidateEdge(); break; + case 4: stlgeometry->STLDoctorExcludeEdge(); break; + default: break; + } + } + else if (stldoctor.selectmode == 2) + { + selecttrig = (minname-1) / 4 + 1; + nodeofseltrig = minname-selecttrig*4+4; + if (nodeofseltrig == 4) {nodeofseltrig = 1;} + + stlgeometry->SetSelectTrig(selecttrig); + stlgeometry->SetNodeOfSelTrig(nodeofseltrig); + stlgeometry->PrintSelectInfo(); + + } + + if (stldoctor.showtouchedtrigchart && stlgeometry->AtlasMade() && stlgeometry->GetSelectTrig()) + { + vispar.stlchartnumber = stlgeometry->GetChartNr(stlgeometry->GetSelectTrig()); + vispar.stlchartnumberoffset = 0; + } + +} + + + + +// VisualSceneSTLMeshing vsstlmeshing; + + + + + + /* *********************** Draw STL Geometry **************** */ + + + VisualSceneSTLGeometry :: VisualSceneSTLGeometry () + : VisualScene() + { + ; + } + + VisualSceneSTLGeometry :: ~VisualSceneSTLGeometry () + { + ; + } + + void VisualSceneSTLGeometry :: DrawScene () + { + if (changeval != stlgeometry->GetNT()) + BuildScene(); + + changeval = stlgeometry->GetNT(); + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + SetLight(); + + + glPushMatrix(); + glMultMatrixf (transformationmat); + + + + + glShadeModel (GL_SMOOTH); + glDisable (GL_COLOR_MATERIAL); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + + double shine = vispar.shininess; + // double transp = vispar.transp; + + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine); + glLogicOp (GL_COPY); + + + float mat_col[] = { 0.2f, 0.2f, 0.8f, 1.0f}; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glCallList (trilists.Get(1)); + + glDisable (GL_POLYGON_OFFSET_FILL); + + + int showtrias = vispar.showstltrias; + + if (showtrias) + { + float mat_coll[] = { 0.2f, 0.2f, 0.2f, 1.0f }; + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_coll); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + glCallList (trilists.Get(1)); + } + + /* + + glBegin (GL_TRIANGLES); + for (j = 1; j <= stlgeometry -> GetNT(); j++) + { + const STLTriangle & tria = stlgeometry -> GetTriangle(j); + glNormal3f (tria.normal.X(), + tria.normal.Y(), + tria.normal.Z()); + + for (k = 0; k < 3; k++) + { + glVertex3f (tria.pts[k].X(), + tria.pts[k].Y(), + tria.pts[k].Z()); + } + } + glEnd (); + */ + + + + + glPopMatrix(); + glFinish(); + } + + + void VisualSceneSTLGeometry :: BuildScene (int zoomall) + { + // cout << "rebuild stl geometry scene" << endl; + + center = stlgeometry -> GetBoundingBox().Center(); + rad = stlgeometry -> GetBoundingBox().Diam() / 2; + + + CalcTransformationMatrices(); + + for (int i = 1; i <= trilists.Size(); i++) + glDeleteLists (trilists.Elem(i), 1); + trilists.SetSize(0); + + + trilists.Append (glGenLists (1)); + glNewList (trilists.Last(), GL_COMPILE); + + glEnable (GL_NORMALIZE); + + glBegin (GL_TRIANGLES); + for (int j = 1; j <= stlgeometry -> GetNT(); j++) + { + const Vec3d & n = stlgeometry->GetTriangle(j).Normal(); + glNormal3f (n.X(), n.Y(), n.Z()); + + for (int k = 1; k <= 3; k++) + { + const Point3d & p = + stlgeometry->GetPoint (stlgeometry -> GetTriangle(j).PNum(k)); + glVertex3f (p.X(),p.Y(), p.Z()); + } + } + glEnd (); + + glEndList (); + } + +} diff --git a/libsrc/stlgeom/vsstl.hpp b/libsrc/stlgeom/vsstl.hpp new file mode 100644 index 00000000..d3841c81 --- /dev/null +++ b/libsrc/stlgeom/vsstl.hpp @@ -0,0 +1,53 @@ +#ifndef FILE_VSSTL +#define FILE_VSSTL + +/**************************************************************************/ +/* File: vsstl.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 05. Jan. 2011 */ +/**************************************************************************/ + +namespace netgen +{ + + class VisualSceneSTLGeometry : public VisualScene + { + Array trilists; + class STLGeometry * stlgeometry; + + public: + VisualSceneSTLGeometry (); + virtual ~VisualSceneSTLGeometry (); + void SetGeometry (class STLGeometry * astlgeometry) { stlgeometry = astlgeometry; } + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + }; + + + class VisualSceneSTLMeshing : public VisualScene + { + Array trilists; + int selecttrig, nodeofseltrig; + class STLGeometry * stlgeometry; + + public: + VisualSceneSTLMeshing (); + virtual ~VisualSceneSTLMeshing (); + + void SetGeometry (class STLGeometry * astlgeometry) { stlgeometry = astlgeometry; } + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + virtual void MouseDblClick (int px, int py); + + int seltria; + }; + + + +} + + + +#endif diff --git a/libsrc/visualization/Makefile.am b/libsrc/visualization/Makefile.am new file mode 100644 index 00000000..917ba722 --- /dev/null +++ b/libsrc/visualization/Makefile.am @@ -0,0 +1,17 @@ +noinst_HEADERS = meshdoc.hpp mvdraw.hpp vispar.hpp \ +visual.hpp vssolution.hpp + +include_HEADERS = soldata.hpp + +AM_CPPFLAGS = $(MPI_INCLUDES) -I$(top_srcdir)/libsrc/include -DOPENGL -D$(TOGL_WINDOWINGSYSTEM) $(OCCFLAGS) $(TCL_INCLUDES) +METASOURCES = AUTO + +if NGGUI +noinst_LTLIBRARIES = libvisual.la +endif + + +libvisual_la_SOURCES = meshdoc.cpp mvdraw.cpp \ + vsfieldlines.cpp vsmesh.cpp vssolution.cpp importsolution.cpp + + diff --git a/libsrc/visualization/Makefile.in b/libsrc/visualization/Makefile.in new file mode 100644 index 00000000..0d04554e --- /dev/null +++ b/libsrc/visualization/Makefile.in @@ -0,0 +1,598 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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 = libsrc/visualization +DIST_COMMON = $(include_HEADERS) $(noinst_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libvisual_la_LIBADD = +am_libvisual_la_OBJECTS = meshdoc.lo mvdraw.lo vsfieldlines.lo \ + vsmesh.lo vssolution.lo importsolution.lo +libvisual_la_OBJECTS = $(am_libvisual_la_OBJECTS) +@NGGUI_TRUE@am_libvisual_la_rpath = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libvisual_la_SOURCES) +DIST_SOURCES = $(libvisual_la_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) $(noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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_HEADERS = meshdoc.hpp mvdraw.hpp vispar.hpp \ +visual.hpp vssolution.hpp + +include_HEADERS = soldata.hpp +AM_CPPFLAGS = $(MPI_INCLUDES) -I$(top_srcdir)/libsrc/include -DOPENGL -D$(TOGL_WINDOWINGSYSTEM) $(OCCFLAGS) $(TCL_INCLUDES) +METASOURCES = AUTO +@NGGUI_TRUE@noinst_LTLIBRARIES = libvisual.la +libvisual_la_SOURCES = meshdoc.cpp mvdraw.cpp \ + vsfieldlines.cpp vsmesh.cpp vssolution.cpp importsolution.cpp + +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign libsrc/visualization/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign libsrc/visualization/Makefile +.PRECIOUS: 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)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libvisual.la: $(libvisual_la_OBJECTS) $(libvisual_la_DEPENDENCIES) $(EXTRA_libvisual_la_DEPENDENCIES) + $(CXXLINK) $(am_libvisual_la_rpath) $(libvisual_la_OBJECTS) $(libvisual_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/importsolution.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/meshdoc.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mvdraw.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsfieldlines.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vsmesh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vssolution.Plo@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-includeHEADERS + +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: uninstall-includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags 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-includeHEADERS 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 uninstall uninstall-am uninstall-includeHEADERS + + +# 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/libsrc/visualization/importsolution.cpp b/libsrc/visualization/importsolution.cpp new file mode 100644 index 00000000..cf182d71 --- /dev/null +++ b/libsrc/visualization/importsolution.cpp @@ -0,0 +1,129 @@ +// +// Read solution file +// + + +#include + + +#include +#include +#include +#include + +#include + +namespace netgen +{ + + + +void ImportSolution (const char * filename) +{ + ifstream inf (filename); + char buf[100], name[1000]; + int i, size, comps, order; + bool iscomplex; + const char * type; + Flags flags; + + while (1) + { + buf[0] = 0; + inf >> buf; + if (strcmp (buf, "solution") == 0) + { + inf >> name; + + inf >> buf[0]; + flags.DeleteFlags (); + while (buf[0] == '-') + { + inf >> buf[1]; + inf.putback (buf[1]); + if (!isalpha (buf[1])) + { + break; + } + inf >> (buf+1); + flags.SetCommandLineFlag (buf); + buf[0] = 0; + inf >> buf[0]; + } + inf.putback (buf[0]); + + (*testout) << "Flags: " << endl; + flags.PrintFlags (*testout); + (*testout) << "done" << endl; + + size = int(flags.GetNumFlag ("size", Ng_GetNP())); + comps = int(flags.GetNumFlag ("components", 1)); + type = flags.GetStringFlag ("type", "nodal"); + order = int(flags.GetNumFlag ("order", 1)); + iscomplex = flags.GetDefineFlag ("complex"); + + double * sol = new double[size*comps]; + + (*testout) << "import solution " << name << " size = " << size << " comps = " << comps << " order = " << order << endl; + + for (i = 0; i < size*comps; i++) + { + inf >> sol[i]; + // (*testout) << "sol: " << sol[i] << endl; + } + + Ng_SolutionData soldata; + Ng_InitSolutionData (&soldata); + soldata.name = name; + soldata.data = sol; + soldata.dist = comps; + soldata.components = comps; + soldata.order = order; + soldata.iscomplex = iscomplex; + soldata.soltype = NG_SOLUTION_NODAL; + soldata.draw_surface = 1; + soldata.draw_volume = 1; + if (strcmp (type, "element") == 0) + { + soldata.soltype = NG_SOLUTION_ELEMENT; + soldata.draw_surface = 0; + } + if (strcmp (type, "surfaceelement") == 0) + { + soldata.soltype = NG_SOLUTION_SURFACE_ELEMENT; + soldata.draw_volume = 0; + } + if (strcmp (type, "noncontinuous") == 0) + soldata.soltype = NG_SOLUTION_NONCONTINUOUS; + if (strcmp (type, "surfacenoncontinuous") == 0) + soldata.soltype = NG_SOLUTION_SURFACE_NONCONTINUOUS; + + Ng_SetSolutionData (&soldata); + } + else + { + // cout << "kw = (" << buf << ")" << endl; + (*testout) << "kw = (" << buf << ")" << endl; + break; + } + } + /* + struct Ng_SolutionData + { + char * name; // name of gridfunction + double * data; // solution values + int components; // used components in solution vector + int dist; // num of doubles per entry (alignment!) + Ng_SolutionType soltype; // type of solution function + }; + + // initialize solution data with default arguments + void Ng_InitSolutionData (Ng_SolutionData * soldata); + // set solution data + void Ng_SetSolutionData (Ng_SolutionData * soldata); + */ +} + + + +} diff --git a/libsrc/visualization/meshdoc.cpp b/libsrc/visualization/meshdoc.cpp new file mode 100644 index 00000000..c2df277e --- /dev/null +++ b/libsrc/visualization/meshdoc.cpp @@ -0,0 +1,614 @@ +#ifndef NOTCL + +#include + +#include + +// #include "incvis.hpp" + + +#include + + +namespace netgen +{ + // #include "meshdoc.hpp" + + +MeshDoctorParameters meshdoctor; +VisualSceneMeshDoctor vsmeshdoc; + +extern AutoPtr mesh; + + int Ng_MeshDoctor (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) +{ + cout << "Mesh Doctor:" << endl; + int i; + for (i = 0; i < argc; i++) + cout << argv[i] << " "; + cout << endl; + + meshdoctor.active = + atoi (Tcl_GetVar (interp, "::meshdoctor.active", 0)); + + + if (argc >= 2) + { + if (strcmp (argv[1], "markedgedist") == 0) + { + vsmeshdoc.SetMarkEdgeDist (atoi (argv[2])); + } + + if (strcmp (argv[1], "deletemarkedsegments") == 0) + { + for (i = 1; i <= mesh->GetNSeg(); i++) + if (vsmeshdoc.IsSegmentMarked (i)) + mesh->DeleteSegment (i); + + // for (i = 1; i <= mesh->GetNSE(); i++) + // mesh->SurfaceElement(i).SetIndex (1); + mesh->Compress(); + } + } + + + vsmeshdoc.UpdateTables (); + vsmeshdoc.BuildScene(); + return TCL_OK; +} + + + + + +VisualSceneMeshDoctor :: VisualSceneMeshDoctor () + : VisualScene() +{ + filledlist = 0; + outlinelist = 0; + edgelist = 0; + selelement = 0; + locpi = 1; + selpoint = 0; + selpoint2 = 0; + markedgedist = 1; + + UpdateTables (); +} + +VisualSceneMeshDoctor :: ~VisualSceneMeshDoctor () +{ + ; +} + +void VisualSceneMeshDoctor :: DrawScene () +{ + if (!mesh) return; + + int hchval = mesh->GetNP() + mesh->GetNE() + mesh->GetNSE(); + if (changeval != hchval) + { + changeval = hchval; + BuildScene(); + } + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable (GL_COLOR_MATERIAL); + glColor3f (1.0f, 1.0f, 1.0f); + glLineWidth (1.0f); + + SetLight(); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + glInitNames (); + glPushName (0); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + SetClippingPlane (); + + if (vispar.drawfilledtrigs) + glCallList (filledlist); + + glDisable (GL_POLYGON_OFFSET_FILL); + + if (vispar.drawoutline) + glCallList (outlinelist); + + glPolygonOffset (-1, -1); + glEnable (GL_POLYGON_OFFSET_LINE); + + if (vispar.drawedges) + glCallList (edgelist); + + + glDisable (GL_POLYGON_OFFSET_LINE); + + + + glPopName(); + + if (selpoint > 0 && selpoint <= mesh->GetNP()) + { + GLfloat matcolblue[] = { 0, 0, 1, 1 }; + + glPointSize (10); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolblue); + glBegin (GL_POINTS); + + const Point3d p = mesh->Point(selpoint); + glVertex3f (p.X(), p.Y(), p.Z()); + glEnd(); + } + + glDisable(GL_CLIP_PLANE0); + + + glPopMatrix(); + glFinish(); +} + + + + +void VisualSceneMeshDoctor :: BuildScene (int zoomall) +{ + int i, j; + + + if (zoomall) + { + Point3d pmin, pmax; + mesh->GetBox (pmin, pmax, -1); + + if (vispar.centerpoint) + center = mesh->Point (vispar.centerpoint); + else + center = Center (pmin, pmax); + + rad = 0.5 * Dist (pmin, pmax); + + glEnable (GL_NORMALIZE); + + CalcTransformationMatrices(); + } + + + + + if (filledlist) + { + glDeleteLists (filledlist, 1); + glDeleteLists (outlinelist, 1); + glDeleteLists (edgelist, 1); + } + + + filledlist = glGenLists (1); + glNewList (filledlist, GL_COMPILE); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glLineWidth (1.0f); + + glDisable (GL_COLOR_MATERIAL); + + for (i = 1; i <= mesh->GetNSE(); i++) + { + glLoadName (i); + + // copy to be thread-safe + Element2d el = mesh->SurfaceElement (i); + + int drawel = 1; + for (j = 1; j <= el.GetNP(); j++) + { + if (!el.PNum(j)) + drawel = 0; + } + + if (!drawel) + continue; + + GLfloat matcol[] = { 0, 1, 0, 1 }; + GLfloat matcolsel[] = { 1, 0, 0, 1 }; + + if (i == selelement) + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcolsel); + else + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol); + + if (el.GetNP() == 3) + { + glBegin (GL_TRIANGLES); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length()+1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + + if (!vispar.colormeshsize) + { + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + else + { + double h1 = mesh->GetH (lp1); + double h2 = mesh->GetH (lp2); + double h3 = mesh->GetH (lp3); + + SetOpenGlColor (h1, 0.1, 10); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + + SetOpenGlColor (h2, 0.1, 10); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + + SetOpenGlColor (h3, 0.1, 10); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + glEnd(); + } + else if (el.GetNP() == 4) + { + glBegin (GL_QUADS); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(4)); + const Point3d & lp4 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), + Vec3d (lp1, Center (lp3, lp4))); + n /= (n.Length()+1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glEnd(); + } + else if (el.GetNP() == 6) + { + glBegin (GL_TRIANGLES); + static int trigs[4][3] = { + { 1, 6, 5 }, + { 2, 4, 6 }, + { 3, 5, 4 }, + { 4, 5, 6 } }; + + for (j = 0; j < 4; j++) + { + const Point3d & lp1 = mesh->Point (el.PNum(trigs[j][0])); + const Point3d & lp2 = mesh->Point (el.PNum(trigs[j][1])); + const Point3d & lp3 = mesh->Point (el.PNum(trigs[j][2])); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length() + 1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + glEnd(); + } + } + glLoadName (0); + + glEndList (); + + + + outlinelist = glGenLists (1); + glNewList (outlinelist, GL_COMPILE); + + glLineWidth (1.0f); + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + glColor3f (0.0f, 0.0f, 0.0f); + glEnable (GL_COLOR_MATERIAL); + + for (i = 1; i <= mesh->GetNSE(); i++) + { + Element2d el = mesh->SurfaceElement(i); + + int drawel = 1; + for (j = 1; j <= el.GetNP(); j++) + { + if (!el.PNum(j)) + drawel = 0; + } + + if (!drawel) + continue; + + + if (el.GetNP() == 3) + { + glBegin (GL_TRIANGLES); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length() + 1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glEnd(); + } + else if (el.GetNP() == 4) + { + glBegin (GL_QUADS); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(4)); + const Point3d & lp4 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), + Vec3d (lp1, Center (lp3, lp4))); + n /= (n.Length() + 1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glEnd(); + } + else if (el.GetNP() == 6) + { + glBegin (GL_LINES); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(3)); + const Point3d & lp4 = mesh->Point (el.PNum(4)); + const Point3d & lp5 = mesh->Point (el.PNum(5)); + const Point3d & lp6 = mesh->Point (el.PNum(6)); + + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length()+1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp6.X(), lp6.Y(), lp6.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp6.X(), lp6.Y(), lp6.Z()); + + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp5.X(), lp5.Y(), lp5.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glVertex3d (lp5.X(), lp5.Y(), lp5.Z()); + + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); + glEnd(); + } + } + glLoadName (0); + glEndList (); + + + + + + edgelist = glGenLists (1); + glNewList (edgelist, GL_COMPILE); + + glDisable (GL_COLOR_MATERIAL); + + GLfloat matcoledge[] = { 0, 0, 1, 1 }; + GLfloat matcolseledge[] = { 1, 0, 1, 1 }; + + glLineWidth (2.0f); + + for (i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh->LineSegment(i); + const Point3d & p1 = mesh->Point(seg[0]); + const Point3d & p2 = mesh->Point(seg[1]); + + if (edgedist.Get(seg[0]) <= markedgedist && + edgedist.Get(seg[1]) <= markedgedist) + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + matcolseledge); + glLineWidth (4.0f); + } + else + { + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + matcoledge); + glLineWidth (2.0f); + } + glBegin (GL_LINES); + glVertex3f (p1.X(), p1.Y(), p1.Z()); + glVertex3f (p2.X(), p2.Y(), p2.Z()); + glEnd(); + } + + glLineWidth (1.0f); + glEndList (); +} + + + + +void VisualSceneMeshDoctor :: MouseDblClick (int px, int py) +{ + cout << "dblclick: " << px << " - " << py << endl; + + int i, hits; + + // select surface triangle by mouse click + GLuint selbuf[10000]; + glSelectBuffer (10000, selbuf); + + + glRenderMode (GL_SELECT); + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + + GLdouble projmat[16]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + + glLoadIdentity(); + gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); + glMultMatrixd (projmat); + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_MODELVIEW); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + glInitNames(); + glPushName (1); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glCallList (filledlist); + + glDisable (GL_POLYGON_OFFSET_FILL); + + glPopName(); + + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + + glFlush(); + + + hits = glRenderMode (GL_RENDER); + + cout << "hits = " << hits << endl; + + int minname = 0; + GLuint mindepth = 0; + for (i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + GLuint curdepth = selbuf[4*i+1]; + + if (curname && + (curdepth < mindepth || !minname)) + { + mindepth = curdepth; + minname = curname; + } + } + + cout << "clicked element: " << minname << endl; + + ClickElement (minname); + + BuildScene (); +} + + + + +void VisualSceneMeshDoctor :: SetMarkEdgeDist (int dist) +{ + markedgedist = dist; + BuildScene(); +} + +void VisualSceneMeshDoctor :: ClickElement (int elnr) +{ + selelement = elnr; + + int oldlocpi = locpi; + locpi = locpi % 3 + 1; + + if (selelement > 0 && selelement <= mesh->GetNSE()) + { + selpoint = mesh->SurfaceElement(selelement).PNum(locpi); + selpoint2 = mesh->SurfaceElement(selelement).PNum(oldlocpi); + cout << "selpts = " << selpoint << ", " << selpoint2 << endl; + } + + UpdateTables(); +} + + +void VisualSceneMeshDoctor :: UpdateTables () +{ + if (!mesh) return; + + edgedist.SetSize(mesh->GetNP()); + int i, changed; + + for (i = 1; i <= mesh->GetNP(); i++) + edgedist.Elem(i) = 10000; + + for (i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh->LineSegment(i); + if ( (seg[0] == selpoint && seg[1] == selpoint2) || + (seg[1] == selpoint && seg[0] == selpoint2) ) + { + edgedist.Elem(selpoint) = 1; + edgedist.Elem(selpoint2) = 1; + } + } + + do + { + changed = 0; + + for (i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh->LineSegment(i); + + int edist = min2 (edgedist.Get(seg[0]), edgedist.Get(seg[1])); + edist++; + + if (edgedist.Get(seg[0]) > edist) + { + edgedist.Elem(seg[0]) = edist; + changed = 1; + } + if (edgedist.Get(seg[1]) > edist) + { + edgedist.Elem(seg[1]) = edist; + changed = 1; + } + } + } + while (changed); +} + +int VisualSceneMeshDoctor :: IsSegmentMarked (int segnr) const +{ + const Segment & seg = mesh->LineSegment(segnr); + return (edgedist.Get(seg[0]) <= markedgedist && + edgedist.Get(seg[1]) <= markedgedist); +} +} + + +#endif // NOTCL diff --git a/libsrc/visualization/meshdoc.hpp b/libsrc/visualization/meshdoc.hpp new file mode 100644 index 00000000..65763385 --- /dev/null +++ b/libsrc/visualization/meshdoc.hpp @@ -0,0 +1,37 @@ + +class VisualSceneMeshDoctor : public VisualScene +{ + int filledlist; + int outlinelist; + int edgelist; + + int selelement, locpi; + int selpoint, selpoint2; + + // for edgemarking: + Array edgedist; + int markedgedist; + + +public: + VisualSceneMeshDoctor (); + virtual ~VisualSceneMeshDoctor (); + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + virtual void MouseDblClick (int px, int py); + + void SetMarkEdgeDist (int dist); + void ClickElement (int elnr); + void UpdateTables (); + int IsSegmentMarked (int segnr) const; +}; + +class MeshDoctorParameters +{ +public: + int active; +}; + + +extern MeshDoctorParameters meshdoctor; diff --git a/libsrc/visualization/mvdraw.cpp b/libsrc/visualization/mvdraw.cpp new file mode 100644 index 00000000..2b75a88b --- /dev/null +++ b/libsrc/visualization/mvdraw.cpp @@ -0,0 +1,814 @@ +#include +#include +#include + +#include +// #include + + + +#ifndef WIN32 +#define GLX_GLXEXT_LEGACY + +#include +#include +#include /* for XA_RGB_DEFAULT_MAP atom */ +// #include // for parallel GL ??? +#endif + + + + + +namespace netgen +{ + DLL_HEADER Point3d VisualScene :: center; + DLL_HEADER double VisualScene :: rad; + DLL_HEADER GLdouble VisualScene :: backcolor; + + /* +#if TOGL_MAJOR_VERSION!=2 + GLuint VisualScene :: fontbase = 0; +#else + Tcl_Obj * VisualScene :: fontbase = NULL; + Togl * VisualScene :: globtogl; +#endif + */ + + // texture for color decoding + // GLubyte * VisualScene :: colortexture = NULL; + GLuint VisualScene :: coltexname = 1; + int VisualScene :: ntexcols = -1; + + + float VisualScene :: lookatmat[16]; + float VisualScene :: transmat[16]; + float VisualScene :: rotmat[16]; + float VisualScene :: centermat[16]; + float VisualScene :: transformationmat[16]; + + int VisualScene :: selface; + int VisualScene :: selelement; + int VisualScene :: selpoint; + int VisualScene :: selpoint2; + int VisualScene :: locpi; + int VisualScene :: seledge; + + int VisualScene :: selecttimestamp; + + int VisualScene :: viewport[4]; + + VisualizationParameters :: VisualizationParameters() + { + lightamb = 0.3; + lightdiff = 0.7; + lightspec = 1; + shininess = 50; + transp = 0.3; + locviewer = 0; + showstltrias = 0; + centerpoint = 0; + usedispllists = 1; + strcpy (selectvisual, "cross"); + + use_center_coords = false; + }; + VisualizationParameters vispar; + + + + double dist = 0; + // double dist = 6; + // vorher: pnear = 2; + // double pnear = 0.1; + // double pfar = 10; + + + + VisualScene :: VisualScene () + { + changeval = -1; + backcolor = 0; + } + + + VisualScene :: ~VisualScene() + { + ; + } + + + extern DLL_HEADER void Render(); + DLL_HEADER void Render () + { + multithread.redraw = 1; + } + + + void VisualScene :: BuildScene (int zoomall) + { + center = Point3d (0,0,0); + rad = 1; + + CalcTransformationMatrices(); + + glEnable(GL_DEPTH_TEST); + glDisable (GL_DITHER); + + GLfloat ambvals[] = { 0.4f, 0.4f, 0.4f, 1.0f }; + GLfloat diffvals[] = { 0.5f, 0.5f, 0.5f, 1.0f }; + GLfloat specvals[] = { 0.7f, 0.7f, 0.7f, 1.0f }; + glLightfv(GL_LIGHT0, GL_AMBIENT, ambvals); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffvals); + glLightfv(GL_LIGHT0, GL_SPECULAR, specvals); + + GLfloat light_position[] = { 1, 3, 3, 0 }; + glLightfv(GL_LIGHT0, GL_POSITION, light_position); + + glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, 0); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + } + + + void VisualScene :: DrawScene () + { + if (changeval == -1) + BuildScene(); + changeval = 0; + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable (GL_COLOR_MATERIAL); + glColor3f (1.0f, 1.0f, 1.0f); + glLineWidth (1.0f); + + DrawCoordinateCross (); + DrawNetgenLogo (); + glFinish(); + } + + + void VisualScene :: CalcTransformationMatrices() + { + // prepare model view matrix + + glPushMatrix(); + + glLoadIdentity(); + gluLookAt (0, 0, 6, 0, 0, 0, 0, 1, 0); + glGetFloatv (GL_MODELVIEW_MATRIX, lookatmat); + + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -dist); + glGetFloatv (GL_MODELVIEW_MATRIX, transmat); + + glLoadIdentity(); + glGetFloatv (GL_MODELVIEW_MATRIX, rotmat); + + glScalef (1/rad, 1/rad, 1/rad); + glTranslated (-center.X(), -center.Y(), -center.Z()); + glGetFloatv (GL_MODELVIEW_MATRIX, centermat); + + glLoadIdentity(); + glMultMatrixf (lookatmat); + glMultMatrixf (transmat); + glMultMatrixf (rotmat); + glMultMatrixf (centermat); + glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); + + glPopMatrix(); + } + + + void VisualScene :: ArbitraryRotation (const Array & alpha, const Array & vec) + { + glPushMatrix(); + + glLoadIdentity(); + + for(int i=0; i a(1); a[0] = alpha; + Array v(1); v[0] = vec; + + ArbitraryRotation(a,v); + } + + void VisualScene :: StandardRotation (const char * dir) + { + glPushMatrix(); + + glLoadIdentity(); + + if (strcmp (dir, "xy") == 0) + ; + else if (strcmp (dir, "yx") == 0) + glRotatef(180.0, 1.0f, 1.0f, 0.0f); + else if (strcmp (dir, "xz") == 0) + glRotatef(-90.0, 1.0f, 0.0f, 0.0f); + else if (strcmp (dir, "zx") == 0) + { + glRotatef(180.0, 1.0f, 1.0f, 0.0f); + glRotatef(-90.0, 1.0f, 0.0f, 0.0f); + } + else if (strcmp (dir, "yz") == 0) + { + glRotatef(-90.0, 0.0f, 0.0f, 1.0f); + glRotatef(-90.0, 0.0f, 1.0f, 0.0f); + } + else if (strcmp (dir, "zy") == 0) + glRotatef(90.0, 0.0f, 1.0f, 0.0f); + + + glGetFloatv (GL_MODELVIEW_MATRIX, rotmat); + + glLoadIdentity(); + glMultMatrixf (lookatmat); + glMultMatrixf (transmat); + glMultMatrixf (rotmat); + glMultMatrixf (centermat); + glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); + + glPopMatrix(); + } + + void VisualScene :: MouseMove(int oldx, int oldy, + int newx, int newy, + char mode) + { + int deltax = newx - oldx; + int deltay = newy - oldy; + + glPushMatrix(); + glLoadIdentity (); + + switch (mode) + { + case 'r': + { + glRotatef(float(deltax)/2, 0.0f, 1.0f, 0.0f); + glRotatef(float(deltay)/2, 1.0f, 0.0f, 0.0f); + glMultMatrixf (rotmat); + glGetFloatv (GL_MODELVIEW_MATRIX, rotmat); + break; + } + case 'm': + { + GLdouble projmat[16], modelviewmat[16]; + GLint viewport[4]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + glGetDoublev (GL_MODELVIEW_MATRIX, modelviewmat); + glGetIntegerv (GL_VIEWPORT, viewport); + + // vorher pvz1/2 = 0 + GLdouble pvx1 = 0, pvy1 = 0, pvz1 = 0.99; // 0.95; + GLdouble pvx2 = deltax, pvy2 = -deltay, pvz2 = 0.99; // 0.95; + + GLdouble px1, py1, pz1; + GLdouble px2, py2, pz2; + + gluUnProject (pvx1, pvy1, pvz1, + modelviewmat, projmat, viewport, + &px1, &py1, &pz1); + gluUnProject (pvx2, pvy2, pvz2, + modelviewmat, projmat, viewport, + &px2, &py2, &pz2); + /* + gluUnProject (oldx, oldy, 1, + modelviewmat, projmat, viewport, + &px1, &py1, &pz1); + gluUnProject (newx, newy, 1, + modelviewmat, projmat, viewport, + &px2, &py2, &pz2); + */ + + /* + cout << "pv1 = " << pvx1 << ", " << pvy1 << ", " << pvz1 << endl; + cout << "p1 = " << px1 << ", " << py1 << ", " << pz1 << endl; + */ + + glTranslated (px2-px1, py2-py1, pz2-pz1); + + glMultMatrixf (transmat); + glGetFloatv (GL_MODELVIEW_MATRIX, transmat); + break; + } + case 'z': + { + // glTranslatef(0.0f, 0.0f, -dist); + + // cout << "deltay = " << deltay << endl; + // cout << "float_bug = " << (float(deltay)/100) << endl; gives wrong result with icc 9.0.021 + glScaled (exp (double (-deltay)/100), + exp (double (-deltay)/100), + exp (double (-deltay)/100)); + // glTranslatef(0.0f, 0.0f, dist); + glMultMatrixf (transmat); + glGetFloatv (GL_MODELVIEW_MATRIX, transmat); + break; + } + } + + glLoadIdentity(); + glMultMatrixf (lookatmat); + glMultMatrixf (transmat); + glMultMatrixf (rotmat); + glMultMatrixf (centermat); + glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); + + glPopMatrix(); + } + + + void VisualScene :: LookAt (const Point<3> & cam, const Point<3> & obj, + const Point<3> & camup) + { + glPushMatrix(); + glLoadIdentity (); + gluLookAt (cam(0), cam(1), cam(2), + obj(0), obj(1), obj(2), + camup(0), camup(1), camup(2)); + glMultMatrixf (centermat); + glGetFloatv (GL_MODELVIEW_MATRIX, transformationmat); + glPopMatrix(); + } + + + void VisualScene :: SetClippingPlane () + { + if (vispar.clipping.enable) + { + Vec3d n = vispar.clipping.normal; + n /= (n.Length()+1e-10); + clipplane[0] = n.X(); + clipplane[1] = n.Y(); + clipplane[2] = n.Z(); + clipplane[3] = -(Vec3d(center) * n) + rad * vispar.clipping.dist; + + double clipplane2[4]; + clipplane2[0] = n.X(); + clipplane2[1] = n.Y(); + clipplane2[2] = n.Z(); + clipplane2[3] = -(Vec3d(center) * n) + + rad * (vispar.clipping.dist + vispar.clipping.dist2); + + glClipPlane(GL_CLIP_PLANE0, clipplane2); + glEnable(GL_CLIP_PLANE0); + } + else + glDisable (GL_CLIP_PLANE0); + } + + + + + void VisualScene :: MouseDblClick (int /* px */, int /* py */) + { + ; + } + + + + void VisualScene :: SetLight() + { + GLfloat vals[3]; + double lightamb = vispar.lightamb; + vals[0] = vals[1] = vals[2] = lightamb; + glLightfv(GL_LIGHT0, GL_AMBIENT, vals); + + double lightdiff = vispar.lightdiff; + vals[0] = vals[1] = vals[2] = lightdiff; + glLightfv(GL_LIGHT0, GL_DIFFUSE, vals); + + double lightspec = vispar.lightspec; + vals[0] = vals[1] = vals[2] = lightspec; + glLightfv(GL_LIGHT0, GL_SPECULAR, vals); + + glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, vispar.shininess); + glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, vispar.locviewer); + + float mat_spec_col[] = { 1, 1, 1, 1 }; + glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, mat_spec_col); + + glEnable (GL_LIGHTING); + glEnable (GL_LIGHT0); + } + + + + + void VisualScene :: SetOpenGlColor(double val, double valmin, double valmax, + int logscale) + { + double value; + + if (!logscale) + value = (val - valmin) / (valmax - valmin); + else + { + if (valmax <= 0) valmax = 1; + if (valmin <= 0) valmin = 1e-4 * valmax; + value = (log(fabs(val)) - log(valmin)) / (log(valmax) - log(valmin)); + } + + if (!invcolor) + value = 1 - value; + + glTexCoord1f ( 0.998 * value + 0.001); + // glTexCoord1f ( val ); + + glTexCoord2f ( 0.998 * value + 0.001, 1.5); + // glTexCoord1f ( value ); + + if (value > 1) value = 1; + if (value < 0) value = 0; + + value *= 4; + + static const double colp[][3] = + { + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 1, 1 }, + { 0, 0, 1 }, + // { 1, 0, 1 }, + // { 1, 0, 0 }, + }; + + int i = int(value); + double r = value - i; + + GLdouble col[3]; + for (int j = 0; j < 3; j++) + col[j] = (1-r) * colp[i][j] + r * colp[i+1][j]; + + glColor3d (col[0], col[1], col[2]); + } + + + + void VisualScene :: CreateTexture (int ncols, int linear, double alpha, int typ) + { + if (linear) ncols = 32; + else ncols = 8; + + + if (ntexcols != ncols) + { + ntexcols = ncols; + + GLubyte colortexture[4*32]; + + const double colp[][3] = + { + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 1, 1 }, + { 0, 0, 1 }, + }; + + for (int i = 0; i < ncols; i++) + { + double value = 4.0 * i / (ncols-1); + + int iv = int(value); + double r = value - iv; + + GLdouble col[3]; + + if(r > 1e-3) + for (int j = 0; j < 3; j++) + col[j] = (1.-r) * colp[iv][j] + r * colp[iv+1][j]; + else + for (int j = 0; j < 3; j++) + col[j] = colp[iv][j]; + + colortexture[4*i] = GLubyte (255 * col[0]); + colortexture[4*i+1] = GLubyte (255 * col[1]); + colortexture[4*i+2] = GLubyte (255 * col[2]); + colortexture[4*i+3] = GLubyte(255*alpha); + } + + // glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + + glTexImage1D (GL_TEXTURE_1D, 0, 4, ncols, 0, GL_RGBA, GL_UNSIGNED_BYTE, colortexture); + glTexImage2D (GL_TEXTURE_2D, 0, 4, ncols, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, colortexture); + + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, typ); // DECAL or MODULATE + + GLfloat bcol[] = { 1, 1, 1, 1.0 }; + glTexParameterfv (GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR, bcol); + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + + glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, bcol); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + + if (linear) + { + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + } + } + + + + + void VisualScene :: DrawColorBar (double minval, double maxval, int logscale, bool linear) + { + if (!vispar.drawcolorbar) return; + + CreateTexture (8, linear, 1, GL_DECAL); + + if (logscale && maxval <= 0) maxval = 1; + if (logscale && minval <= 0) minval = 1e-4 * maxval; + + double minx = -1; + double maxx = 1; + double miny = 0.75; + double maxy = 0.8; + + glDisable (GL_LIGHTING); + glEnable (GL_COLOR_MATERIAL); + glEnable (GL_TEXTURE_1D); + glNormal3d (0, 0, 1); + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glDisable (GL_DEPTH_TEST); + glBegin (GL_QUAD_STRIP); + + for (double x = minx; x <= maxx; x += (maxx - minx) / 50) + { + SetOpenGlColor (x, minx, maxx); + glVertex3d (x, miny, -5); + glVertex3d (x, maxy, -5); + } + glEnd(); + + glDisable (GL_TEXTURE_1D); + + glEnable (GL_COLOR_MATERIAL); + GLfloat textcol[3] = { 1 - backcolor, 1 - backcolor, 1 - backcolor }; + glColor3fv (textcol); + + glPushAttrib (GL_LIST_BIT); + // glListBase (fontbase); + + char buf[20]; + for (int i = 0; i <= 4; i++) + { + double x = minx + i * (maxx-minx) / 4; + glRasterPos3d (x, 0.7,-5); + + double val; + if (logscale) + val = minval * pow (maxval / minval, i / 4.0); + else + val = minval + i * (maxval-minval) / 4; + + sprintf (buf, "%8.3e", val); + // glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + } + + glPopAttrib (); + glEnable (GL_DEPTH_TEST); + } + + + void VisualScene :: DrawCoordinateCross () + { + if (!vispar.drawcoordinatecross) return; + + glDisable (GL_DEPTH_TEST); + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode (GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + glTranslatef (-1, -1, 0.0); + glScalef (40.0 / viewport[2], 40.0 / viewport[3], 1); + glTranslatef (2.0, 2.0, 0.0); + glMultMatrixf (rotmat); + + glEnable (GL_COLOR_MATERIAL); + glDisable (GL_LIGHTING); + + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + + GLfloat textcol[3] = { 1 - backcolor, + 1 - backcolor, + 1 - backcolor }; + glColor3fv (textcol); + + glLineWidth (1.0f); + + double len = 1; + + glBegin(GL_LINES); + glVertex3d (0, 0, 0); + glVertex3d (len, 0, 0); + glVertex3d (0.0f, 0.0f, 0.0f); + glVertex3d (0.0f, len, 0.0f); + glVertex3d (0.0f, 0.0f, 0.0f); + glVertex3d (0.0f, 0.0f, len); + glEnd (); + + glPushAttrib (GL_LIST_BIT); + // glListBase (fontbase); + + char buf[20]; + + glRasterPos3d (len, 0.0f, 0.0f); + sprintf (buf, "x"); + // glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + glRasterPos3d (0.0f, len, 0.0f); + sprintf (buf, "y"); + // glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + glRasterPos3d (0.0f, 0.0f, len); + sprintf (buf, "z"); + // glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + + glPopAttrib (); + + glEnable (GL_LIGHTING); + + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + glEnable (GL_DEPTH_TEST); + } + + + void VisualScene :: DrawNetgenLogo () + { + if (!vispar.drawnetgenlogo) return; + + glDisable (GL_DEPTH_TEST); + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode (GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + glTranslatef (1, -1, 0.0); + glScalef (40.0 / viewport[2], 40.0 / viewport[3], 1); + glTranslatef (-7.0, 2.0, 0.0); + + glDisable (GL_CLIP_PLANE0); + glDisable (GL_LIGHTING); + + glEnable (GL_COLOR_MATERIAL); + GLfloat textcol[3] = { 1 - backcolor, + 1 - backcolor, + 1 - backcolor }; + glColor3fv (textcol); + glLineWidth (1.0f); + + glPushAttrib (GL_LIST_BIT); + // glListBase (fontbase); + + char buf[] = "Netgen " PACKAGE_VERSION; + + glRasterPos3d (0.0f, 0.0f, 0.0f); + // glCallLists (GLsizei(strlen (buf)), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + + glPopAttrib (); + + glEnable (GL_LIGHTING); + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + glEnable (GL_DEPTH_TEST); + } + + + + + + + +#ifdef PARALLELGL + void VisualScene :: InitParallelGL () + { + static int init = 0; + + if (!init) + { + init = 1; + + if (id == 0) + { + string displname; + + // Display * dpy = glXGetCurrentDisplay(); + GLXDrawable drawable = glXGetCurrentDrawable(); + GLXContext ctx = glXGetCurrentContext(); + GLXContextID xid = glXGetContextIDEXT (ctx); + + displname = XDisplayName (0); + + /* + cout << "Init Parallel GL" << endl; + cout << "DisplayName = " << displname << endl; + cout << "current display = " << dpy << endl; + cout << "current drawable = " << drawable << endl; + cout << "current context = " << ctx << endl; + + cout << "contextid = " << xid << endl; + cout << "isdirect = " << glXIsDirect ( dpy, ctx ) << endl; + cout << "extensionstring = " << glXQueryExtensionsString( dpy, 0 ) << endl; + */ + + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("init"); + + for (int dest = 1; dest < ntasks; dest++) + { + MyMPI_Send (displname, dest, MPI_TAG_VIS); + MyMPI_Send (int (drawable), dest, MPI_TAG_VIS); + MyMPI_Send (int (xid), dest, MPI_TAG_VIS); + } + } + } + } + + + void VisualScene :: Broadcast () + { + if (ntasks == 1) return; + + if (id == 0) + { + /* + for (int dest = 1; dest < ntasks; dest++) + { + MyMPI_Send ("redraw", dest, MPI_TAG_CMD); + MyMPI_Send ("broadcast", dest, MPI_TAG_VIS); + } + */ + + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("broadcast"); + } + + MyMPI_Bcast (selface); + + vssolution.Broadcast (); + } +#endif + +} diff --git a/libsrc/visualization/mvdraw.hpp b/libsrc/visualization/mvdraw.hpp new file mode 100644 index 00000000..621a7ac5 --- /dev/null +++ b/libsrc/visualization/mvdraw.hpp @@ -0,0 +1,251 @@ +#ifndef FILE_MVDRAW +#define FILE_MVDRAW + + +namespace netgen +{ + + /* + extern void InitDrawMesh (); + extern void DrawMesh (); + extern void MouseMove(int oldx, int oldy, + int newx, int newy, + char mode); + + extern void Render (); + */ + + + class VisualScene + { + protected: + static DLL_HEADER Point3d center; + static DLL_HEADER double rad; + + static float lookatmat[16]; + static float transmat[16]; + static float rotmat[16]; + static float centermat[16]; + + static DLL_HEADER float transformationmat[16]; + + GLdouble clipplane[4]; + + int changeval; + static DLL_HEADER GLdouble backcolor; + + static int selface; + static int selelement; + static int selpoint; + static int selpoint2; + static int locpi; + static int seledge; + + static int selecttimestamp; + + public: + static int viewport[4]; + // static GLubyte * colortexture; + static GLuint coltexname; + static int ntexcols; + // static bool linear_colors; + int invcolor; + + + public: + DLL_HEADER VisualScene (); + DLL_HEADER virtual ~VisualScene(); + + DLL_HEADER virtual void BuildScene (int zoomall = 0); + DLL_HEADER virtual void DrawScene (); + + DLL_HEADER void CalcTransformationMatrices(); + DLL_HEADER void StandardRotation (const char * dir); + DLL_HEADER void ArbitraryRotation (const Array & alpha, const Array & vec); + DLL_HEADER void ArbitraryRotation (const double alpha, const Vec3d & vec); + + DLL_HEADER void MouseMove(int oldx, int oldy, + int newx, int newy, + char mode); + + DLL_HEADER void LookAt (const Point<3> & cam, const Point<3> & obj, + const Point<3> & camup); + + DLL_HEADER void SetClippingPlane (); + + DLL_HEADER virtual void MouseDblClick (int px, int py); + + DLL_HEADER void SetLight (); + static void SetBackGroundColor (double col) + { backcolor = col; } + + DLL_HEADER void CreateTexture (int ncols, int linear, double alpha, int typ); + DLL_HEADER void DrawColorBar (double minval, double maxval, int logscale = 0, bool linear = 1); + DLL_HEADER void DrawCoordinateCross (); + DLL_HEADER void DrawNetgenLogo (); + DLL_HEADER void SetOpenGlColor(double val, double valmin, double valmax, int logscale = 0); + + +#ifdef PARALLELGL + DLL_HEADER void InitParallelGL (); + DLL_HEADER void Broadcast (); +#endif + }; + + + DLL_HEADER extern void MyOpenGLText (const char * text); + + + + + + + + + + + + class VisualSceneSurfaceMeshing : public VisualScene + { + public: + VisualSceneSurfaceMeshing (); + virtual ~VisualSceneSurfaceMeshing (); + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + }; + + + + + + + + class VisualSceneMesh : public VisualScene + { + int filledlist; + int linelist; + int edgelist; + int pointnumberlist; + + int tetlist; + int prismlist; + int pyramidlist; + int hexlist; + + int badellist; + int identifiedlist; + int domainsurflist; + + int vstimestamp;//, selecttimestamp; + int filledtimestamp; + int linetimestamp; + int edgetimestamp; + int pointnumbertimestamp; + + int tettimestamp; + int prismtimestamp; + int pyramidtimestamp; + int hextimestamp; + + int badeltimestamp; + int identifiedtimestamp; + int domainsurftimestamp; + + +#ifdef PARALLELGL + Array par_linelists; + Array par_filledlists; +#endif + + MouseEventHandler * user_me_handler; + + NgLock *lock; + + // int selface, selelement; + // int selpoint, selpoint2, locpi; + // int seledge; + + double minh, maxh; // for meshsize coloring + + public: + VisualSceneMesh (); + virtual ~VisualSceneMesh (); + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + virtual void MouseDblClick (int px, int py); + + void SetMouseEventHandler (MouseEventHandler * handler) + { user_me_handler = handler; } + + + int SelectedFace () const + { return selface; } + void SetSelectedFace (int asf); + // { selface = asf; selecttimestamp = GetTimeStamp(); } + + int SelectedEdge () const + { return seledge; } + int SelectedElement () const + { return selelement; } + int SelectedPoint () const + { return selpoint; } + void BuildFilledList (bool names); + // private: + void BuildLineList(); + void BuildEdgeList(); + void BuildPointNumberList(); + + void BuildTetList(); + void BuildPrismList(); + void BuildPyramidList(); + void BuildHexList(); + + void BuildBadelList(); + void BuildIdentifiedList(); + void BuildDomainSurfList(); + }; + + + + class VisualSceneSpecPoints : public VisualScene + { + public: + VisualSceneSpecPoints (); + virtual ~VisualSceneSpecPoints (); + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + + double len; + }; + + + + + + + + // extern struct Tcl_Interp * hinterp; + + + extern void AddVisualizationScene (const string & name, + VisualScene * vs); + + + void MouseDblClickSelect (const int px, const int py, + const GLdouble * clipplane, const GLdouble backcolor, + const float * transformationmat, + const Point3d & center, + const double rad, + const int displaylist, + int & selelement, int & selface, int & seledge, int & selpoint, + int & selpoint2, int & locpi); + + +} + + +#endif + diff --git a/libsrc/visualization/soldata.hpp b/libsrc/visualization/soldata.hpp new file mode 100644 index 00000000..48989c7b --- /dev/null +++ b/libsrc/visualization/soldata.hpp @@ -0,0 +1,122 @@ +#ifndef FILE_SOLDATA +#define FILE_SOLDATA + + +namespace netgen +{ + + using namespace std; + + class SolutionData + { + protected: + + string name; + int components; + bool iscomplex; + + int multidimcomponent; + + public: + SolutionData (const string & aname, + int acomponents = 1, bool aiscomplex = 0) + : name(aname), components(acomponents), iscomplex(aiscomplex) + { ; } + + virtual ~SolutionData () + { ; } + + int GetComponents() + { + return components; + } + + bool IsComplex() + { + return iscomplex; + } + + virtual bool GetValue (int /* elnr */, + double /* lam1 */, double /* lam2 */, double /* lam3 */, + double * /* values */) + { + return false; + } + + virtual bool GetValue (int selnr, + const double xref[], const double x[], const double dxdxref[], + double * values) + { + return GetValue (selnr, xref[0], xref[1], xref[2], values); + } + + virtual bool GetMultiValue (int elnr, int facetnr, int npts, + const double * xref, int sxref, + const double * x, int sx, + const double * dxdxref, int sdxdxref, + double * values, int svalues) + { + bool res = false; + for (int i = 0; i < npts; i++) + res = GetValue (elnr, &xref[i*sxref], &x[i*sx], &dxdxref[i*sdxdxref], &values[i*svalues]); + return res; + } + + + + virtual bool GetSurfValue (int /* selnr */, int facetnr, + double /* lam1 */, double /* lam2 */, + double * /* values */) + { + return false; + } + + + virtual bool GetSurfValue (int selnr, int facetnr, + const double xref[], const double x[], const double dxdxref[], + double * values) + { + return GetSurfValue (selnr, facetnr, xref[0], xref[1], values); + } + + + virtual bool GetMultiSurfValue (int selnr, int facetnr, int npts, + const double * xref, int sxref, + const double * x, int sx, + const double * dxdxref, int sdxdxref, + double * values, int svalues) + { + bool res = false; + for (int i = 0; i < npts; i++) + res = GetSurfValue (selnr, facetnr, &xref[i*sxref], &x[i*sx], &dxdxref[i*sdxdxref], &values[i*svalues]); + return res; + } + + virtual bool GetSegmentValue (int segnr, double xref, double * values) + { return false; } + + + virtual int GetNumMultiDimComponents () + { + return 1; + } + + void SetMultiDimComponent (int mc) + { + if (mc >= GetNumMultiDimComponents()) mc = GetNumMultiDimComponents()-1; + if (mc < 0) mc = 0; + multidimcomponent = mc; + } + }; + + + class DLL_HEADER MouseEventHandler + { + public: + virtual void DblClick (int elnr) { ; } + }; + +} + +#endif + diff --git a/libsrc/visualization/vispar.hpp b/libsrc/visualization/vispar.hpp new file mode 100644 index 00000000..4ee65335 --- /dev/null +++ b/libsrc/visualization/vispar.hpp @@ -0,0 +1,126 @@ +#ifndef FILE_VISPAR +#define FILE_VISPAR + +namespace netgen +{ + +class VisualizationParameters +{ +public: + double lightamb; + double lightdiff; + double lightspec; + double shininess; + double transp; + int locviewer; + char selectvisual[20]; + int showstltrias; + + /* + Vec3d clipnormal; + double clipdist; + int clipenable; + int clipplanetimestamp; + */ + class Clipping + { + public: + Vec3d normal; + double dist; + double dist2; + int enable; + int timestamp; + bool operator== (Clipping & clip2) + { + return + (normal == clip2.normal) && + (dist == clip2.dist) && + // (dist2 == clip2.dist2) && + (enable == clip2.enable); + } + }; + Clipping clipping; + + int colormeshsize; + + int drawfilledtrigs; + int drawbadels; + int drawoutline; + int drawedges; + int subdivisions; + + int drawprisms; + int drawpyramids; + int drawhexes; + double shrink; + int drawidentified; + int drawpointnumbers; + int drawedgenumbers; + int drawfacenumbers; + int drawelementnumbers; + int drawdomainsurf; + int drawtets; + int drawtetsdomain; + + int clipdomain; + int donotclipdomain; + + int drawededges; + int drawedpoints; + int drawedpointnrs; + int drawedtangents; + int drawededgenrs; + int drawmetispartition; + + int drawcurveproj; + int drawcurveprojedge; + + + int centerpoint; + int drawelement; + + // stl: + int stlshowtrias; + int stlshowfilledtrias; + int stlshowedges; + int stlshowmarktrias; + int stlshowactivechart; + int stlchartnumber; + int stlchartnumberoffset; + + // occ: + int occshowvolumenr; + bool occshowsurfaces; + bool occshowedges; + bool occvisproblemfaces; + bool occzoomtohighlightedentity; + double occdeflection; + + // ACIS + + bool ACISshowfaces; + bool ACISshowedges; + int ACISshowsolidnr; + int ACISshowsolidnr2; + + bool whitebackground; + int stereo; + bool usedispllists; + bool drawcoordinatecross; + bool drawcolorbar; + bool drawnetgenlogo; + + bool use_center_coords; + double centerx,centery,centerz; + + bool drawspecpoint; + double specpointx,specpointy,specpointz; + + +public: + VisualizationParameters(); +}; +extern VisualizationParameters vispar; +} + +#endif diff --git a/libsrc/visualization/visual.hpp b/libsrc/visualization/visual.hpp new file mode 100644 index 00000000..15966c90 --- /dev/null +++ b/libsrc/visualization/visual.hpp @@ -0,0 +1,35 @@ +#ifndef FILE_VISUAL +#define FILE_VISUAL + +/* *************************************************************************/ +/* File: visual.hpp */ +/* Author: Joachim Schoeberl */ +/* Date: 02. Dec. 01 */ +/* *************************************************************************/ + +/* + +Visualization + +*/ + +#ifdef PARALLEL +#define PARALLELGL +#endif + +#include "../include/incvis.hpp" + +#include "vispar.hpp" +#include "soldata.hpp" +#include "mvdraw.hpp" + +#include + +namespace netgen +{ +#include "vssolution.hpp" +#include "meshdoc.hpp" +} + + +#endif diff --git a/libsrc/visualization/vsfieldlines.cpp b/libsrc/visualization/vsfieldlines.cpp new file mode 100644 index 00000000..910b5c28 --- /dev/null +++ b/libsrc/visualization/vsfieldlines.cpp @@ -0,0 +1,729 @@ +#ifndef NOTCL + +#include +#include "incvis.hpp" + + +#include +#include +#include +#include + +#include + + +namespace netgen +{ + + extern AutoPtr mesh; + + + + RKStepper :: ~RKStepper() + { + delete a; + } + + RKStepper :: RKStepper(int type) : a(NULL), tolerance(1e100) + { + notrestarted = 0; + + if (type == 0) // explicit Euler + { + c.SetSize(1); c[0] = 0; + b.SetSize(1); b[0] = 1; + steps = order = 1; + } + else if (type == 1) // Euler-Cauchy + { + c.SetSize(2); c[0] = 0; c[1] = 0.5; + b.SetSize(2); b[0] = 0; b[1] = 1; + Array size(2); + size[0] = 0; size[1] = 1; + a = new TABLE(size); + a->Set(2,1,0.5); // Set, Get: 1-based! + steps = order = 2; + } + else if (type == 2) // Simpson + { + c.SetSize(3); c[0] = 0; c[1] = 1; c[2] = 0.5; + b.SetSize(3); b[0] = b[1] = 1./6.; b[2] = 2./3.; + Array size(3); + size[0] = 0; size[1] = 1; size[2] = 2; + a = new TABLE(size); + a->Set(2,1,1); + a->Set(3,1,0.25); a->Set(3,2,0.25); + steps = order = 3; + } + else if (type == 3) // classical Runge-Kutta + { + c.SetSize(4); c[0] = 0; c[1] = c[2] = 0.5; c[3] = 1; + b.SetSize(4); b[0] = b[3] = 1./6.; b[1] = b[2] = 1./3.; + Array size(4); + size[0] = 0; size[1] = 1; size[2] = 2; size[3] = 3; + a = new TABLE(size); + a->Set(2,1,0.5); + a->Set(3,1,0); a->Set(3,2,0.5); + a->Set(4,1,0); a->Set(4,2,0); a->Set(4,3,1); + steps = order = 4; + } + + K.SetSize(steps); + } + + void RKStepper :: StartNextValCalc(const Point3d & astartval, const double astartt, const double ah, const bool aadaptive) + { + //cout << "Starting RK-Step with h=" << ah << endl; + + stepcount = 0; + h = ah; + startt = astartt; + startval = astartval; + adaptive = aadaptive; + adrun = 0; + } + + bool RKStepper :: GetNextData(Point3d & val, double & t, double & ah) + { + bool finished(false); + + + //cout << "stepcount " << stepcount << endl; + + if(stepcount <= steps) + { + t = startt + c[stepcount-1]*h; + val = startval; + for(int i=0; iGet(stepcount,i+1) * K[i]; + } + + + if(stepcount == steps) + { + val = startval; + for(int i=0; i 1.3) fac = 1.3; + + if(fac < 1 || notrestarted >= 2) + ah = 2.*h * fac; + + if(err < tolerance) + { + finished = true; + notrestarted++; + //(*testout) << "finished RK-Step, new h=" << ah << " tolerance " << tolerance << " err " << err << endl; + } + else + { + //ah *= 0.9; + notrestarted = 0; + //(*testout) << "restarting h " << 2.*h << " ah " << ah << " tolerance " << tolerance << " err " << err << endl; + StartNextValCalc(startval_bak,startt_bak, ah, adaptive); + } + } + } + else + { + t = startt + h; + finished = true; + } + + } + + if(stepcount == 0) + { + t = startt + c[stepcount]*h; + val = startval; + for(int i=0; iGet(stepcount,i) * K[i]; + } + + return finished; + } + + + bool RKStepper :: FeedNextF(const Vec3d & f) + { + K[stepcount] = f; + stepcount++; + return true; + } + + + + void FieldLineCalc :: GenerateFieldLines(Array & potential_startpoints, const int numlines, const int gllist, + const double minval, const double maxval, const int logscale, double phaser, double phasei) + { + + + Array points; + Array values; + Array drawelems; + Array dirstart; + + + if(vsol -> iscomplex) + SetPhase(phaser,phasei); + + double crit = 1.0; + + if(randomized) + { + double sum = 0; + double lami[3]; + double values[6]; + Vec3d v; + + for(int i=0; iiscomplex, phaser, phasei); + + sum += v.Length(); + } + + crit = sum/double(numlines); + } + + + int calculated = 0; + + cout << endl; + + + + + for(int i=0; i= numlines) break; + + Calc(potential_startpoints[i],points,values,drawelems,dirstart); + + bool usable = false; + + for(int j=1; j 0) ? rel_length : 0.5; + maxlength *= 2.*rad; + + thickness = (rel_thickness > 0) ? rel_thickness : 0.0015; + thickness *= 2.*rad; + + double auxtolerance = (rel_tolerance > 0) ? rel_tolerance : 1.5e-3; + auxtolerance *= 2.*rad; + + stepper.SetTolerance(auxtolerance); + + direction = adirection; + + + maxpoints = amaxpoints; + + if(direction == 0) + { + maxlength *= 0.5; + maxpoints /= 2; + } + + + phaser = 1; + phasei = 0; + + critical_value = -1; + + randomized = false; + + } + + + + + void FieldLineCalc :: Calc(const Point3d & startpoint, Array & points, Array & vals, Array & drawelems, Array & dirstart) + { + double lami[3], startlami[3]; + double values[6]; + double dummyt(0); + Vec3d v; + Vec3d startv; + Point3d newp; + double h; + + double startval; + bool startdraw; + bool drawelem = false; + int elnr; + + for (int i=0; i<6; i++) values[i]=0.0; + for (int i=0; i<3; i++) lami[i]=0.0; + for (int i=0; i<3; i++) startlami[i]=0.0; + + points.SetSize(0); + vals.SetSize(0); + drawelems.SetSize(0); + + dirstart.SetSize(0); + dirstart.Append(0); + + + int startelnr = mesh.GetElementOfPoint(startpoint,startlami,true) - 1; + (*testout) << "p = " << startpoint << "; elnr = " << startelnr << endl; + if (startelnr == -1) + return; + + mesh.SetPointSearchStartElement(startelnr); + + if (mesh.GetDimension()==3) + startdraw = vss.GetValues ( vsol, startelnr, startlami[0], startlami[1], startlami[2], values); + else + startdraw = vss.GetSurfValues ( vsol, startelnr, -1, startlami[0], startlami[1], values); + + VisualSceneSolution::RealVec3d ( values, startv, vsol->iscomplex, phaser, phasei); + + startval = startv.Length(); + + if(critical_value > 0 && fabs(startval) < critical_value) + return; + + //cout << "p = " << startpoint << "; elnr = " << startelnr << endl; + + + + for(int dir = 1; dir >= -1; dir -= 2) + { + if(dir*direction < 0) continue; + + points.Append(startpoint); + vals.Append(startval); + drawelems.Append(startdraw); + + h = 0.001*rad/startval; // otherwise no nice lines; should be made accessible from outside + + v = startv; + if(dir == -1) v *= -1.; + + elnr = startelnr; + lami[0] = startlami[0]; lami[1] = startlami[1]; lami[2] = startlami[2]; + + + for(double length = 0; length < maxlength; length += h*vals.Last()) + { + if(v.Length() < 1e-12*rad) + { + (*testout) << "Current fieldlinecalculation came to a stillstand at " << points.Last() << endl; + break; + } + + stepper.StartNextValCalc(points.Last(),dummyt,h,true); + stepper.FeedNextF(v); + + while(!stepper.GetNextData(newp,dummyt,h) && elnr != -1) + { + elnr = mesh.GetElementOfPoint(newp,lami,true) - 1; + if(elnr != -1) + { + mesh.SetPointSearchStartElement(elnr); + if (mesh.GetDimension()==3) + drawelem = vss.GetValues (vsol, elnr, lami[0], lami[1], lami[2], values); + else + drawelem = vss.GetSurfValues (vsol, elnr, -1, lami[0], lami[1], values); + + VisualSceneSolution::RealVec3d (values, v, vsol->iscomplex, phaser, phasei); + if(dir == -1) v *= -1.; + stepper.FeedNextF(v); + } + } + + if (elnr == -1) + { + //cout << "direction " < 1) + (*testout) << "Points in current fieldline: " << points.Size() << ", current position: " << newp << endl; + + if(maxpoints > 0 && points.Size() >= maxpoints) + { + break; + } + + //cout << "length " << length << " h " << h << " vals.Last() " << vals.Last() << " maxlength " << maxlength << endl; + } + dirstart.Append(points.Size()); + } + } + + + + + + void VisualSceneSolution :: BuildFieldLinesFromBox(Array & startpoints) + { + if(fieldlines_startarea_parameter[0] > fieldlines_startarea_parameter[3] || + fieldlines_startarea_parameter[1] > fieldlines_startarea_parameter[4] || + fieldlines_startarea_parameter[2] > fieldlines_startarea_parameter[5]) + { + Point3d pmin, pmax; + mesh->GetBox (pmin, pmax); + + fieldlines_startarea_parameter[0] = pmin.X(); + fieldlines_startarea_parameter[1] = pmin.Y(); + fieldlines_startarea_parameter[2] = pmin.Z(); + fieldlines_startarea_parameter[3] = pmax.X(); + fieldlines_startarea_parameter[4] = pmax.Y(); + fieldlines_startarea_parameter[5] = pmax.Z(); + } + + for (int i = 1; i <= startpoints.Size(); i++) + { + Point3d p (fieldlines_startarea_parameter[0] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[3]-fieldlines_startarea_parameter[0]), + fieldlines_startarea_parameter[1] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[4]-fieldlines_startarea_parameter[1]), + fieldlines_startarea_parameter[2] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[5]-fieldlines_startarea_parameter[2])); + + startpoints[i-1] = p; + } + } + + void VisualSceneSolution :: BuildFieldLinesFromLine(Array & startpoints) + { + for (int i = 1; i <= startpoints.Size(); i++) + { + double s = double (rand()) / RAND_MAX; + + Point3d p (fieldlines_startarea_parameter[0] + s * (fieldlines_startarea_parameter[3]-fieldlines_startarea_parameter[0]), + fieldlines_startarea_parameter[1] + s * (fieldlines_startarea_parameter[4]-fieldlines_startarea_parameter[1]), + fieldlines_startarea_parameter[2] + s * (fieldlines_startarea_parameter[5]-fieldlines_startarea_parameter[2])); + + startpoints[i-1] = p; + } + } + + + void VisualSceneSolution :: BuildFieldLinesFromFile(Array & startpoints) + { + ifstream * infile; + + infile = new ifstream(fieldlines_filename.c_str()); + + //cout << "reading from file " << fieldlines_filename << endl; + + int numpoints = 0; + + string keyword; + + + double dparam; + int iparam; + + while(infile->good()) + { + (*infile) >> keyword; + + if(keyword == "point") numpoints++; + else if(keyword == "line" || keyword == "box") + { + for(int i=0; i<6; i++) (*infile) >> dparam; + (*infile) >> iparam; + numpoints += iparam; + } + } + + delete infile; + + + //cout << numpoints << " startpoints" << endl; + + startpoints.SetSize(numpoints); + + infile = new ifstream(fieldlines_filename.c_str()); + + numpoints = 0; + + while(infile->good()) + { + (*infile) >> keyword; + + if (keyword == "point") + { + (*infile) >> startpoints[numpoints].X(); (*infile) >> startpoints[numpoints].Y(); (*infile) >> startpoints[numpoints].Z(); + numpoints++; + } + else if (keyword == "line" || keyword == "box") + { + for(int i=0; i<6; i++) (*infile) >> fieldlines_startarea_parameter[i]; + (*infile) >> iparam; + + Array auxpoints(iparam); + + if (keyword == "box") + BuildFieldLinesFromBox(auxpoints); + else if (keyword == "line") + BuildFieldLinesFromLine(auxpoints); + + for(int i=0; i & startpoints) + { + Array elements_2d; + + //cout << "fieldlines_startface " << fieldlines_startface << endl; + mesh->GetSurfaceElementsOfFace(fieldlines_startface,elements_2d); + if(elements_2d.Size() == 0) + { + cerr << "No Elements on selected face (?)" << endl; + return; + } + Vec3d v1,v2,cross; + + double area = 0; + + int i; + for(i=0; iSurfaceElement(elements_2d[i]); + + v1 = mesh->Point(elem[1]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + area += cross.Length(); + + if(elem.GetNV() == 4) + { + v1 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[3]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + area += cross.Length(); + } + } + + int startpointsp = 0; + i = 0; + + while(startpointsp < startpoints.Size()) + { + const Element2d & elem = mesh->SurfaceElement(elements_2d[i]); + + int numtri = (elem.GetNV() == 3) ? 1 : 2; + + for(int tri = 0; startpointsp < startpoints.Size() && triPoint(elem[1]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + } + else if(tri == 1) + { + v1 = mesh->Point(elem[2]) - mesh->Point(elem[0]); + v2 = mesh->Point(elem[3]) - mesh->Point(elem[0]); + cross = Cross(v1,v2); + } + + double thisarea = cross.Length(); + + int numloc = int(startpoints.Size()*thisarea/area); + if(double (rand()) / RAND_MAX < startpoints.Size()*thisarea/area - numloc) + numloc++; + + for(int j=0; startpointsp < startpoints.Size() && j 1) + { + s = 1.-s; t = 1.-t; + } + startpoints[startpointsp] = mesh->Point(elem[0]) + s*v1 +t*v2; + startpointsp++; + } + } + i++; + if(i == elements_2d.Size()) i = 0; + } + + } + + + void VisualSceneSolution :: BuildFieldLinesPlot () + { + if (fieldlinestimestamp >= solutiontimestamp) + return; + fieldlinestimestamp = solutiontimestamp; + + + if (fieldlineslist) + glDeleteLists (fieldlineslist, num_fieldlineslists); + + if (vecfunction == -1) + return; + + const SolData * vsol = soldata[fieldlines_vecfunction]; + + num_fieldlineslists = (vsol -> iscomplex && !fieldlines_fixedphase) ? 100 : 1; + + + FieldLineCalc linecalc(*mesh,*this,vsol, + fieldlines_rellength,fieldlines_maxpoints,fieldlines_relthickness,fieldlines_reltolerance,fieldlines_rktype); + + if(fieldlines_randomstart) + linecalc.Randomized(); + + fieldlineslist = glGenLists (num_fieldlineslists); + + int num_startpoints = num_fieldlines / num_fieldlineslists; + if (num_fieldlines % num_fieldlineslists != 0) num_startpoints++; + + if(fieldlines_randomstart) + num_startpoints *= 10; + + + Array startpoints(num_startpoints); + + + for (int ln = 0; ln < num_fieldlineslists; ln++) + { + if(fieldlines_startarea == 0) + BuildFieldLinesFromBox(startpoints); + else if(fieldlines_startarea == 1) + BuildFieldLinesFromFile(startpoints); + else if(fieldlines_startarea == 2) + BuildFieldLinesFromFace(startpoints); + + + + double phi; + + if(vsol -> iscomplex) + { + if(fieldlines_fixedphase) + phi = fieldlines_phase; + else + phi = 2*M_PI*ln / num_fieldlineslists; + } + else + phi = 0; + + cout << "phi = " << phi << endl; + + double phaser = cos(phi), phasei = sin(phi); + + + glNewList(fieldlineslist+ln, GL_COMPILE); + + SetTextureMode (usetexture); + linecalc.GenerateFieldLines(startpoints,num_fieldlines / num_fieldlineslists+1, + fieldlineslist+ln,minval,maxval,logscale,phaser,phasei); + + glEndList (); + + } + } + + + + +} + + +#endif // NOTCL diff --git a/libsrc/visualization/vsmesh.cpp b/libsrc/visualization/vsmesh.cpp new file mode 100644 index 00000000..23408838 --- /dev/null +++ b/libsrc/visualization/vsmesh.cpp @@ -0,0 +1,3465 @@ +#include + +#include +#include +// #include + +#ifdef STLGEOM +#include +#endif + + +// #include + +#include + +namespace netgen +{ + extern AutoPtr mesh; + extern NetgenGeometry * ng_geometry; + + VisualSceneMesh vsmesh; + + VisualSceneMesh :: VisualSceneMesh () + : VisualScene() + { + filledlist = 0; + linelist = 0; + edgelist = 0; + badellist = 0; + tetlist = 0; + prismlist = 0; + hexlist = 0; + pyramidlist = 0; + identifiedlist = 0; + pointnumberlist = 0; + domainsurflist = 0; + + vstimestamp = GetTimeStamp(); + selecttimestamp = GetTimeStamp(); + filledtimestamp = GetTimeStamp(); + linetimestamp = GetTimeStamp(); + edgetimestamp = GetTimeStamp(); + pointnumbertimestamp = GetTimeStamp(); + + tettimestamp = GetTimeStamp(); + prismtimestamp = GetTimeStamp(); + hextimestamp = GetTimeStamp(); + pyramidtimestamp = GetTimeStamp(); + + badeltimestamp = GetTimeStamp(); + identifiedtimestamp = GetTimeStamp(); + domainsurftimestamp = GetTimeStamp(); + + + selface = -1; + selelement = -1; + locpi = 1; + selpoint = -1; + selpoint2 = -1; + seledge = -1; + + minh = 0.0; + maxh = 0.0; + user_me_handler = NULL; + + } + + VisualSceneMesh :: ~VisualSceneMesh () + { + ; + } + + + void VisualSceneMesh :: DrawScene () + { + if (!mesh) + { + VisualScene::DrawScene(); + return; + } + + lock = NULL; + + static int timer = NgProfiler::CreateTimer ("VSMesh::DrawScene"); + + NgProfiler::RegionTimer reg (timer); + + BuildScene(); + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable (GL_COLOR_MATERIAL); + glColor3f (1.0f, 1.0f, 1.0f); + glLineWidth (1.0f); + + SetLight(); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + GLdouble projmat[16]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + + +#ifdef PARALLEL + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#endif + + + glInitNames (); + glPushName (0); + + // glEnable (GL_LINE_SMOOTH); + // glEnable (GL_BLEND); + // glEnable (GL_POLYGON_SMOOTH); + // glDisable (GL_DEPTH_TEST); + // glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE); + + glDisable (GL_COLOR_MATERIAL); + + GLfloat matcol0[] = { 0, 0, 0, 1 }; + GLfloat matcol1[] = { 1, 1, 1, 1 }; + GLfloat matcolf[] = { 0, 1, 0, 1 }; + GLfloat matcolb[] = { 0.5, 0, 0, 1 }; + // GLfloat matcolblue[] = { 0, 0, 1, 1 }; + + glMatrixMode (GL_MODELVIEW); + + glMaterialfv(GL_FRONT, GL_EMISSION, matcol0); + glMaterialfv(GL_BACK, GL_EMISSION, matcol0); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matcol1); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcolf); + glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, matcolb); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + // glPolygonOffset (1,10); + glPolygonOffset (2,2); + glEnable (GL_POLYGON_OFFSET_FILL); + + SetClippingPlane (); + + if (vispar.drawfilledtrigs) + { + if (filledtimestamp < mesh->GetTimeStamp () || + filledtimestamp < selecttimestamp) + { + BuildFilledList (false); + } + + +#ifdef PARALLELGL + if (ntasks > 1 && vispar.drawtetsdomain > 0 && vispar.drawtetsdomain < ntasks) + glCallList (par_filledlists[vispar.drawtetsdomain]); + else +#endif + glCallList (filledlist); + } + + if (vispar.drawbadels) + glCallList (badellist); + + if (vispar.drawprisms) + { + BuildPrismList (); + glCallList (prismlist); + } + + if (vispar.drawpyramids) + { + BuildPyramidList (); + glCallList (pyramidlist); + } + + if (vispar.drawhexes) + { + BuildHexList (); + glCallList (hexlist); + } + + if (vispar.drawtets) + { + BuildTetList (); + glCallList (tetlist); + } + + if (vispar.drawdomainsurf) + { + BuildDomainSurfList(); + glCallList (domainsurflist); + } + + glDisable (GL_POLYGON_OFFSET_FILL); + + // draw lines + + glMatrixMode (GL_MODELVIEW); + + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol0); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, matcol0); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matcol0); + + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glLineWidth (1.0f); + glColor3f (0.0f, 0.0f, 0.0f); + glDisable (GL_LINE_SMOOTH); + + + if (vispar.drawoutline) + { + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_LINE); + + if (linetimestamp < mesh->GetTimeStamp ()) + BuildLineList (); + +#ifdef PARALLELGL + if (ntasks > 1 && vispar.drawtetsdomain > 0 && vispar.drawtetsdomain < ntasks) + glCallList (par_linelists[vispar.drawtetsdomain]); + else +#endif + glCallList (linelist); + + + glDisable (GL_POLYGON_OFFSET_LINE); + } + + if (vispar.drawidentified) + { + glPolygonOffset (1, -1); + glEnable (GL_POLYGON_OFFSET_LINE); + glCallList (identifiedlist); + glDisable (GL_POLYGON_OFFSET_LINE); + } + + if (vispar.drawpointnumbers || + vispar.drawedgenumbers || + vispar.drawfacenumbers || + vispar.drawelementnumbers) + glCallList (pointnumberlist); + + + glPopName(); + + if (vispar.drawedges) + { + BuildEdgeList(); + glCallList (edgelist); + } + + if (selpoint > 0 && selpoint <= mesh->GetNP()) + { + /* + glPointSize (3.0); + glColor3d (0, 0, 1); + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolblue); + glBegin (GL_POINTS); + + const Point3d p = mesh->Point(selpoint); + glVertex3f (p.X(), p.Y(), p.Z()); + glEnd(); + */ + + glColor3d (0, 0, 1); + + static GLubyte cross[] = + { + 0xc6, 0xee, 0x7c, 0x38, 0x7c, 0xee, 0xc6 + }; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glDisable (GL_COLOR_MATERIAL); + glDisable (GL_LIGHTING); + glDisable (GL_CLIP_PLANE0); + + const Point3d p = mesh->Point(selpoint); + glRasterPos3d (p.X(), p.Y(), p.Z()); + glBitmap (7, 7, 3, 3, 0, 0, &cross[0]); + } + + + glDisable(GL_CLIP_PLANE0); + + glPopMatrix(); + + if (vispar.colormeshsize) + DrawColorBar (minh, maxh, 1); + + DrawCoordinateCross (); + DrawNetgenLogo (); + + + if (lock) + { + lock -> UnLock(); + delete lock; + lock = NULL; + } + + glFinish(); + } + + + void VisualSceneMesh :: BuildScene (int zoomall) + { + if (!mesh) + { + VisualScene::BuildScene (zoomall); + return; + } + + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + static int timer = NgProfiler::CreateTimer ("VSMesh::BuildScene"); + NgProfiler::RegionTimer reg (timer); + + + + Point3d pmin, pmax; + static double oldrad = 0; + + Array faces; + + int meshtimestamp = mesh->GetTimeStamp(); + if (meshtimestamp > vstimestamp || zoomall) + { + if (mesh->GetDimension() == 2) + { + // works in NGSolve, mesh view + mesh->GetBox (pmin, pmax); + } + else + { + // otherwise strange zooms douring mesh generation + mesh->GetBox (pmin, pmax, SURFACEPOINT); + } + + if (vispar.use_center_coords && zoomall == 2) + { + center.X() = vispar.centerx; center.Y() = vispar.centery; center.Z() = vispar.centerz; + } + else if (selpoint >= 1 && zoomall == 2) + center = mesh->Point (selpoint); + else if (vispar.centerpoint >= 1 && zoomall == 2) + center = mesh->Point (vispar.centerpoint); + else + center = Center (pmin, pmax); + rad = 0.5 * Dist (pmin, pmax); + if(rad == 0) rad = 1e-6; + + if (rad > 1.2 * oldrad || + mesh->GetMajorTimeStamp() > vstimestamp || + zoomall) + { + CalcTransformationMatrices(); + oldrad = rad; + } + } + + glEnable (GL_NORMALIZE); + + if (pointnumberlist) + { + glDeleteLists (pointnumberlist, 1); + pointnumberlist = 0; + } + + if (badellist) + { + glDeleteLists (badellist, 1); + badellist = 0; + } + /* + if (prismlist) + { + glDeleteLists (prismlist, 1); + prismlist = 0; + } + + if (pyramidlist) + { + glDeleteLists (pyramidlist, 1); + pyramidlist = 0; + } + + if (hexlist) + { + glDeleteLists (hexlist, 1); + hexlist = 0; + } + */ + if (identifiedlist) + { + glDeleteLists (identifiedlist, 1); + identifiedlist = 0; + } + + pointnumberlist = glGenLists (1); + glNewList (pointnumberlist, GL_COMPILE); + + if (vispar.drawpointnumbers || + vispar.drawedgenumbers || + vispar.drawfacenumbers || + vispar.drawelementnumbers) + { + // glEnable (GL_COLOR_MATERIAL); + GLfloat textcol[3] = { 1 - backcolor, + 1 - backcolor, + 1 - backcolor }; + glColor3fv (textcol); + glNormal3d (0, 0, 1); + glPushAttrib (GL_LIST_BIT); + // glListBase (fontbase); + + char buf[30]; + + if (vispar.drawpointnumbers) + for (int i = 1; i <= mesh->GetNP(); i++) + { + const Point3d & p = mesh->Point(i); + glRasterPos3d (p.X(), p.Y(), p.Z()); + + sprintf (buf, "%d", i); + + // glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + } + + if (vispar.drawedgenumbers) + { + /* + for (SegmentIndex i = 0; i < mesh->GetNSeg(); i++) + { + const Segment & seg = (*mesh)[i]; + + const Point3d & p1 = mesh->Point(seg[0]); + const Point3d & p2 = mesh->Point(seg[1]); + const Point3d p = Center (p1, p2); + glRasterPos3d (p.X(), p.Y(), p.Z()); + + sprintf (buf, "%d", seg.edgenr); + glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); + } + */ + + const MeshTopology & top = mesh->GetTopology(); + for (int i = 1; i <= top.GetNEdges(); i++) + { + int v1, v2; + top.GetEdgeVertices (i, v1, v2); + const Point3d & p1 = mesh->Point(v1); + const Point3d & p2 = mesh->Point(v2); + const Point3d p = Center (p1, p2); + glRasterPos3d (p.X(), p.Y(), p.Z()); + + sprintf (buf, "%d", i); + // glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + + } + + } + + + if (vispar.drawfacenumbers) + { + const MeshTopology & top = mesh->GetTopology(); + Array v; + for (int i = 1; i <= top.GetNFaces(); i++) + { + top.GetFaceVertices (i, v); + const Point3d & p1 = mesh->Point(v.Elem(1)); + const Point3d & p2 = mesh->Point(v.Elem(2)); + const Point3d & p3 = mesh->Point(v.Elem(3)); + Point3d p; + if (v.Elem(4) == 0) + { + p = Center (p1, p2, p3); + } + else + { + const Point3d & p4 = mesh->Point(v.Elem(4)); + Point3d hp1 = Center (p1, p2); + Point3d hp2 = Center (p3, p4); + p = Center (hp1, hp2); + } + + glRasterPos3d (p.X(), p.Y(), p.Z()); + sprintf (buf, "%d", i); + // glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + } + } + + + + if (vispar.drawelementnumbers) + { + Array v; + for (int i = 1; i <= mesh->GetNE(); i++) + { + // const ELEMENTTYPE & eltype = mesh->ElementType(i); + Array pnums; + + Point3d p; + const Element & el = mesh->VolumeElement (i); + + if ( ! el.PNum(5)) // eltype == TET ) + { + + pnums.SetSize(4); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p4 = mesh->Point(pnums[3]); + p = Center (p1, p2, p3, p4); + } + else if ( ! el.PNum(6)) // eltype == PYRAMID + { + pnums.SetSize(5); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p4 = mesh->Point(pnums[3]); + const Point3d & p5 = mesh->Point(pnums[4]); + + p.X() = 0.3 * p5.X() + 0.7 * Center ( Center(p1, p3) , Center(p2, p4) ) . X(); + p.Y() = 0.3 * p5.Y() + 0.7 * Center ( Center(p1, p3) , Center(p2, p4) ) . Y(); + p.Z() = 0.3 * p5.Z() + 0.7 * Center ( Center(p1, p3) , Center(p2, p4) ) . Z(); + + } + else if ( ! el.PNum(7) ) // eltype == PRISM + { + pnums.SetSize(6); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p11 = mesh->Point(pnums[3]); + const Point3d & p12 = mesh->Point(pnums[4]); + const Point3d & p13 = mesh->Point(pnums[5]); + p = Center ( Center (p1, p2, p3) , Center(p11, p12, p13) ) ; + + } + else if (! el.PNum(9) ) // eltype == HEX + { + pnums.SetSize(8); + for( int j = 0; j < pnums.Size(); j++) + pnums[j] = mesh->VolumeElement(i).PNum(j+1); + + const Point3d & p1 = mesh->Point(pnums[0]); + const Point3d & p2 = mesh->Point(pnums[1]); + const Point3d & p3 = mesh->Point(pnums[2]); + const Point3d & p4 = mesh->Point(pnums[3]); + const Point3d & p5 = mesh->Point(pnums[4]); + const Point3d & p6 = mesh->Point(pnums[5]); + const Point3d & p7 = mesh->Point(pnums[6]); + const Point3d & p8 = mesh->Point(pnums[7]); + + p = Center ( Center ( Center(p1, p3), Center(p2, p4) ) , Center( Center(p5, p7) , Center(p6, p8 ) ) ); + } + + glRasterPos3d (p.X(), p.Y(), p.Z()); + sprintf (buf, "%d", i); + // glCallLists (strlen (buf), GL_UNSIGNED_BYTE, buf); + MyOpenGLText (buf); + + } + } + + + glPopAttrib (); + // glDisable (GL_COLOR_MATERIAL); + } + glEndList (); + + + + + + + badellist = glGenLists (1); + glNewList (badellist, GL_COMPILE); + + if (vispar.drawbadels) + { + // SetClippingPlane (); + + static float badelcol[] = { 1.0f, 0.0f, 1.0f, 1.0f }; + glLineWidth (1.0f); + + for (int i = 1; i <= mesh->GetNE(); i++) + { + if (mesh->VolumeElement(i).flags.badel || + mesh->VolumeElement(i).flags.illegal || + (i == vispar.drawelement)) + { + // copy to be thread-safe + Element el = mesh->VolumeElement (i); + el.GetSurfaceTriangles (faces); + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, badelcol); + + + // if ( (el.GetNP() == 4) || (el.GetNP() == 10)) + if (el.PNum(1)) + { + glBegin (GL_TRIANGLES); + + for (int j = 1; j <= faces.Size(); j++) + { + Element2d & face = faces.Elem(j); + const Point3d & lp1 = mesh->Point (el.PNum(face.PNum(1))); + const Point3d & lp2 = mesh->Point (el.PNum(face.PNum(2))); + const Point3d & lp3 = mesh->Point (el.PNum(face.PNum(3))); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length()+1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + + glEnd(); + } + } + } + + + + for (int i = 1; i <= mesh->GetNE(); i++) + { + if (mesh->VolumeElement(i).flags.badel) + { + // copy to be thread-safe + Element el = mesh->VolumeElement (i); + if ( (el.GetNP() == 4) || (el.GetNP() == 10)) + { + glBegin (GL_LINES); + glVertex3d (0,0,0); + const Point3d & p = mesh->Point(el.PNum(1)); + glVertex3d (p.X(), p.Y(), p.Z()); + glEnd(); + } + } + } + + + for (int i = 1; i <= mesh->GetNE(); i++) + { + Element el = mesh->VolumeElement (i); + int hascp = 0; + for (int j = 1; j <= el.GetNP(); j++) + if (el.PNum(j) == vispar.centerpoint) + hascp = 1; + + if (hascp) + { + (*testout) << "draw el " << i << " : "; + for (int j = 1; j <= el.GetNP(); j++) + (*testout) << el.PNum(j) << " "; + (*testout) << endl; + + if (el.GetNP() == 4) + { + int et[6][2] = + { { 1, 2 }, + { 1, 3 }, + { 1, 4 }, + { 2, 3 }, + { 2, 4 }, + { 3, 4 } } ; + + for (int j = 0; j < 6; j++) + { + glBegin (GL_LINES); + const Point3d & p1 = mesh->Point (el.PNum(et[j][0])); + const Point3d & p2 = mesh->Point (el.PNum(et[j][1])); + glVertex3d (p1.X(), p1.Y(), p1.Z()); + glVertex3d (p2.X(), p2.Y(), p2.Z()); + glEnd (); + } + } + + + if (el.GetNP() == 10) + { + int et[12][2] = + { { 1, 5 }, + { 2, 5 }, + { 1, 6 }, + { 3, 6 }, + { 1, 7 }, + { 4, 7 }, + { 2, 8 }, + { 3, 8 }, + { 2, 9 }, + { 4, 9 }, + { 3, 10 }, + { 4, 10 } }; + + for (int j = 0; j < 12; j++) + { + glBegin (GL_LINES); + const Point3d & p1 = mesh->Point (el.PNum(et[j][0])); + const Point3d & p2 = mesh->Point (el.PNum(et[j][1])); + glVertex3d (p1.X(), p1.Y(), p1.Z()); + glVertex3d (p2.X(), p2.Y(), p2.Z()); + glEnd (); + } + } + } + } + + + for (int i = 1; i <= mesh->GetNSE(); i++) + { + Element2d el = mesh->SurfaceElement(i); + if (!el.BadElement()) + continue; + + int drawel = 1; + for (int j = 1; j <= el.GetNP(); j++) + if (!el.PNum(j)) + drawel = 0; + + if (!drawel) + continue; + + // cout << int (el.GetType()) << " " << flush; + switch (el.GetType()) + { + case TRIG: + { + glBegin (GL_TRIANGLES); + + Point3d lp1 = mesh->Point (el.PNum(1)); + Point3d lp2 = mesh->Point (el.PNum(2)); + Point3d lp3 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length() + 1e-12); + glNormal3dv (&n.X()); + glVertex3dv (&lp1.X()); + glVertex3dv (&lp2.X()); + glVertex3dv (&lp3.X()); + glEnd(); + break; + } + case QUAD: + { + glBegin (GL_QUADS); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(4)); + const Point3d & lp4 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), + Vec3d (lp1, Center (lp3, lp4))); + n /= (n.Length() + 1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glEnd(); + break; + } + case TRIG6: + { + int lines[6][2] = { + { 1, 6 }, { 2, 6 }, + { 1, 5 }, { 3, 5 }, + { 2, 4 }, { 3, 4 } }; + + glBegin (GL_LINES); + for (int j = 0; j < 6; j++) + { + glVertex3dv ( mesh->Point (el.PNum(lines[j][0])) ); + glVertex3dv ( mesh->Point (el.PNum(lines[j][0])) ); + } + glEnd(); + break; + } + + case QUAD6: + { + int lines[6][2] = { + { 1, 5 }, { 2, 5 }, + { 3, 6 }, { 4, 6 }, + { 1, 4 }, { 2, 3 } }; + + glBegin (GL_LINES); + + for (int j = 0; j < 6; j++) + { + const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); + const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); + + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + } + glEnd (); + break; + } + default: + PrintSysError ("Cannot draw surface element of type ", + int(el.GetType())); + } + } + glLoadName (0); + + } + glEndList (); + + + if (1) + { + + identifiedlist = glGenLists (1); + glNewList (identifiedlist, GL_COMPILE); + + GLfloat identifiedcol[] = { 1, 0, 1, 1 }; + + glLineWidth (3); + + // for (i = 1; i <= mesh->GetNSeg(); i++) + + if (& mesh -> GetIdentifications() ) + { + INDEX_2_HASHTABLE & idpts = + mesh->GetIdentifications().GetIdentifiedPoints(); + if (&idpts) + { + for (int i = 1; i <= idpts.GetNBags(); i++) + for (int j = 1; j <= idpts.GetBagSize(i); j++) + { + INDEX_2 pts; + int val; + + idpts.GetData (i, j, pts, val); + const Point3d & p1 = mesh->Point(pts.I1()); + const Point3d & p2 = mesh->Point(pts.I2()); + + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + identifiedcol); + + glBegin (GL_LINES); + glVertex3f (p1.X(), p1.Y(), p1.Z()); + glVertex3f (p2.X(), p2.Y(), p2.Z()); + glEnd(); + } + } + } + + glEndList (); + } + + if (lock) + { + lock -> UnLock(); + delete lock; + lock = NULL; + } + + vstimestamp = meshtimestamp; + } + + + + + void VisualSceneMesh :: BuildFilledList (bool names) + { + static int timer = NgProfiler::CreateTimer ("Mesh::BuildFilledList"); + NgProfiler::RegionTimer reg (timer); + +#ifdef PARALLELGL + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + par_filledlists.SetSize (ntasks); + + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("filledlist"); + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (par_filledlists[dest], dest, MPI_TAG_VIS); + + if (filledlist) + glDeleteLists (filledlist, 1); + + filledlist = glGenLists (1); + glNewList (filledlist, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (par_filledlists[dest]); + + glEndList(); + + filledtimestamp = NextTimeStamp(); + return; + } + +#endif + + + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + filledtimestamp = NextTimeStamp(); + + if (filledlist) + glDeleteLists (filledlist, 1); + + filledlist = glGenLists (1); + glNewList (filledlist, GL_COMPILE); + + +#ifdef STLGEOM + STLGeometry * stlgeometry = dynamic_cast (ng_geometry); + bool checkvicinity = (stlgeometry != NULL) && stldoctor.showvicinity; +#endif + glEnable (GL_NORMALIZE); + + glLineWidth (1.0f); + + Vector locms; + + if (vispar.colormeshsize) + { + glEnable (GL_COLOR_MATERIAL); + glShadeModel (GL_SMOOTH); + locms.SetSize (mesh->GetNP()); + maxh = -1; + minh = 1e99; + for (int i = 1; i <= locms.Size(); i++) + { + Point3d p = mesh->Point(i); + locms(i-1) = mesh->GetH (p); + if (locms(i-1) > maxh) maxh = locms(i-1); + if (locms(i-1) < minh) minh = locms(i-1); + } + if (!locms.Size()) + { + minh = 1; + maxh = 10; + } + } + else + glDisable (GL_COLOR_MATERIAL); + + + GLfloat matcol[] = { 0, 1, 0, 1 }; + GLfloat matcolsel[] = { 1, 0, 0, 1 }; + + GLint rendermode; + glGetIntegerv (GL_RENDER_MODE, &rendermode); + + CurvedElements & curv = mesh->GetCurvedElements(); + + int hoplotn = 1 << vispar.subdivisions; + + Array seia; + + + for (int faceindex = 1; faceindex <= mesh->GetNFD(); faceindex++) + { + mesh->GetSurfaceElementsOfFace (faceindex, seia); + + // Philippose - 06/07/2009 + // Modified the colour system to integrate the face colours into + // the mesh data structure, rather than limit it to the OCC geometry + // structure... allows other geometry types to use face colours too + + matcol[0] = mesh->GetFaceDescriptor(faceindex).SurfColour().X(); + matcol[1] = mesh->GetFaceDescriptor(faceindex).SurfColour().Y(); + matcol[2] = mesh->GetFaceDescriptor(faceindex).SurfColour().Z(); + matcol[3] = 1.0; + + if (faceindex == selface) + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolsel); + else + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol); + + + + for (int hi = 0; hi < seia.Size(); hi++) + { + SurfaceElementIndex sei = seia[hi]; + const Element2d & el = (*mesh)[sei]; + + bool drawel = (!el.IsDeleted() & el.IsVisible()); + +#ifdef STLGEOM + if (checkvicinity) + for (int j = 0; j < el.GetNP(); j++) + if (!stlgeometry->Vicinity(el.GeomInfoPi(j+1).trignum)) + drawel = 0; +#endif + + if (!drawel) + continue; + + if (names) + glLoadName (sei+1); + + switch (el.GetType()) + { + case TRIG: + { + if (curv.IsHighOrder()) // && curv.IsSurfaceElementCurved(sei)) + { + if (hoplotn > 128) hoplotn = 128; + Point<3> xa[129]; + Vec<3> na[129]; + + for (int i = 0; i < hoplotn; i++) + { + glBegin (GL_TRIANGLE_STRIP); + + for (int j = 0; j <= hoplotn-i; j++) + for (int k = 0; k < 2; k++) + { + if (j == hoplotn-i && k == 1) continue; + + if (i > 0 && k == 0) + { + glNormal3dv (na[j]); + glVertex3dv (xa[j]); + continue; + } + + Point<2> xref (double(j) / hoplotn, double(i+k) / hoplotn); + Point<3> xglob; + Mat<3,2> dxdxi; + Vec<3> dx, dy, n; + + curv.CalcSurfaceTransformation (xref, sei, xglob, dxdxi); + for (int i = 0; i < 3; i++) + { + dx(i) = dxdxi(i,0); + dy(i) = dxdxi(i,1); + } + n = Cross (dx, dy); + glNormal3dv (n); + glVertex3dv (xglob); + + if (k == 1) + { + na[j] = n; + xa[j] = xglob; + } + } + glEnd(); + } + } + else // not high order + { + glBegin (GL_TRIANGLES); + + const Point<3> & lp0 = (*mesh) [el[0]]; + const Point<3> & lp1 = (*mesh) [el[1]]; + const Point<3> & lp2 = (*mesh) [el[2]]; + + Vec<3> n = Cross (lp1-lp0, lp2-lp0).Normalize(); + glNormal3dv (n); + + for (int j = 0; j < 3; j++) + { + if (vispar.colormeshsize) + SetOpenGlColor (locms(el[0]-1), minh, maxh, 0); + glVertex3dv ( (*mesh)[el[j]] ); + } + + glEnd(); + } + + break; + } + case QUAD: + { + if (curv.IsHighOrder()) // && curv.IsSurfaceElementCurved(sei)) + { + Point<2> xr[4]; + Point<3> xg; + Vec<3> dx, dy, n; + + glBegin (GL_QUADS); + + for (int i = 0; i < hoplotn; i++) + for (int j = 0; j < hoplotn; j++) + { + xr[0](0) = (double) i/hoplotn; xr[0](1) = (double) j/hoplotn; + xr[1](0) = (double)(i+1)/hoplotn; xr[1](1) = (double) j/hoplotn; + xr[2](0) = (double)(i+1)/hoplotn; xr[2](1) = (double)(j+1)/hoplotn; + xr[3](0) = (double) i/hoplotn; xr[3](1) = (double)(j+1)/hoplotn; + + for (int l=0; l<4; l++) + { + Mat<3,2> dxdxi; + + curv.CalcSurfaceTransformation (xr[l], sei, xg, dxdxi); + for (int i = 0; i < 3; i++) + { + dx(i) = dxdxi(i,0); + dy(i) = dxdxi(i,1); + } + + n = Cross (dx, dy); + n.Normalize(); + glNormal3d (n(0), n(1), n(2)); + glVertex3d (xg(0), xg(1), xg(2)); + } + + } + + glEnd(); + } + + else // not high order + + { + glBegin (GL_QUADS); + + const Point<3> & lp1 = mesh->Point (el.PNum(1)); + const Point<3> & lp2 = mesh->Point (el.PNum(2)); + const Point<3> & lp3 = mesh->Point (el.PNum(4)); + const Point<3> & lp4 = mesh->Point (el.PNum(3)); + + Vec<3> n = Cross (lp2-lp1, Center (lp3, lp4)-lp1); + n.Normalize(); + glNormal3dv (n); + + glVertex3dv (lp1); + glVertex3dv (lp2); + glVertex3dv (lp4); + glVertex3dv (lp3); + + glEnd (); + } + break; + } + + case TRIG6: + { + glBegin (GL_TRIANGLES); + + static int trigs[4][3] = { + { 1, 6, 5 }, + { 2, 4, 6 }, + { 3, 5, 4 }, + { 4, 5, 6 } }; + + for (int j = 0; j < 4; j++) + { + const Point<3> & lp1 = mesh->Point (el.PNum(trigs[j][0])); + const Point<3> & lp2 = mesh->Point (el.PNum(trigs[j][1])); + const Point<3> & lp3 = mesh->Point (el.PNum(trigs[j][2])); + // Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + Vec<3> n = Cross (lp2-lp1, lp3-lp1); + glNormal3dv (n); + + glVertex3dv (lp1); + glVertex3dv (lp2); + glVertex3dv (lp3); + } + glEnd(); + break; + } + + case QUAD6: + { + glBegin (GL_QUADS); + static int quads[2][4] = { + { 1, 5, 6, 4 }, + { 5, 2, 3, 6 } }; + + for (int j = 0; j < 2; j++) + { + Point3d lp1 = mesh->Point (el.PNum(quads[j][0])); + Point3d lp2 = mesh->Point (el.PNum(quads[j][1])); + Point3d lp3 = mesh->Point (el.PNum(quads[j][2])); + Point3d lp4 = mesh->Point (el.PNum(quads[j][3])); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length() + 1e-12); + glNormal3dv (&n.X()); + glVertex3dv (&lp1.X()); + glVertex3dv (&lp2.X()); + glVertex3dv (&lp3.X()); + glVertex3dv (&lp4.X()); + } + glEnd(); + break; + } + + case QUAD8: + { + glBegin (GL_TRIANGLES); + static int boundary[] = + { 1, 5, 2, 8, 3, 6, 4, 7, 1 }; + + Point3d c(0,0,0); + for (int j = 0; j < 4; j++) + { + const Point3d & hp = mesh->Point (el[j]); + c.X() -= 0.25 * hp.X(); + c.Y() -= 0.25 * hp.Y(); + c.Z() -= 0.25 * hp.Z(); + } + for (int j = 4; j < 8; j++) + { + const Point3d & hp = mesh->Point (el[j]); + c.X() += 0.5 * hp.X(); + c.Y() += 0.5 * hp.Y(); + c.Z() += 0.5 * hp.Z(); + } + + for (int j = 0; j < 8; j++) + { + Point3d lp1 = mesh->Point (el.PNum(boundary[j])); + Point3d lp2 = mesh->Point (el.PNum(boundary[j+1])); + + Vec3d n = Cross (Vec3d (c, lp1), Vec3d (c, lp2)); + n /= (n.Length() + 1e-12); + glNormal3dv (&n.X()); + glVertex3dv (&lp1.X()); + glVertex3dv (&lp2.X()); + glVertex3dv (&c.X()); + } + glEnd(); + break; + } + + + default: + PrintSysError ("Cannot draw (2) surface element of type ", + int(el.GetType())); + } + + + + } + } + + + glLoadName (0); + glEndList (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (filledlist, 0, MPI_TAG_VIS); +#endif + } + + + void VisualSceneMesh :: BuildLineList() + { + static int timer = NgProfiler::CreateTimer ("Mesh::BuildLineList"); + NgProfiler::RegionTimer reg (timer); + +#ifdef PARALLELGL + + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + + par_linelists.SetSize (ntasks); + + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("linelist"); + + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (par_linelists[dest], dest, MPI_TAG_VIS); + + if (linelist) + glDeleteLists (linelist, 1); + + linelist = glGenLists (1); + glNewList (linelist, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (par_linelists[dest]); + + glEndList(); + + + linetimestamp = NextTimeStamp(); + return; + } + +#endif + + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + linetimestamp = NextTimeStamp(); + +#ifdef STLGEOM + STLGeometry * stlgeometry = dynamic_cast (ng_geometry); + bool checkvicinity = (stlgeometry != NULL) && stldoctor.showvicinity; +#endif + + if (linelist) + glDeleteLists (linelist, 1); + + linelist = glGenLists (1); + glNewList (linelist, GL_COMPILE); + + // cout << "linelist = " << linelist << endl; + + glLineWidth (1.0f); + + + int hoplotn = 1 << vispar.subdivisions; + + // PrintMessage (3, "nse = ", mesh->GetNSE()); + for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) + { + const Element2d & el = (*mesh)[sei]; + + bool drawel = (!el.IsDeleted() & el.IsVisible()); + +#ifdef STLGEOM + if (checkvicinity) + for (int j = 0; j < el.GetNP(); j++) + if (!stlgeometry->Vicinity(el.GeomInfoPi(j+1).trignum)) + drawel = 0; +#endif + + if (!drawel) + continue; + + switch (el.GetType()) + { + case TRIG: + { + CurvedElements & curv = mesh->GetCurvedElements(); + if (curv.IsHighOrder()) // && curv.IsSurfaceElementCurved(sei)) + { + Point<3> xg; + glBegin (GL_LINE_LOOP); + for (int i = 0; i < hoplotn; i++) + { + Point<2> xr (double(i) / hoplotn, 0); + curv.CalcSurfaceTransformation (xr, sei, xg); + glVertex3dv (xg); + } + for (int i = 0; i < hoplotn; i++) + { + Point<2> xr (double(hoplotn-i) / hoplotn, double(i)/hoplotn); + curv.CalcSurfaceTransformation (xr, sei, xg); + glVertex3dv (xg); + } + for (int i = 0; i < hoplotn; i++) + { + Point<2> xr (0, double(hoplotn-i) / hoplotn); + curv.CalcSurfaceTransformation (xr, sei, xg); + glVertex3dv (xg); + } + + glEnd(); + } + else + { + glBegin (GL_TRIANGLES); + + for (int j = 0; j < 3; j++) + glVertex3dv ( (*mesh) [el[j]] ); + /* + const Point<3> & lp0 = (*mesh) [el[0]]; + const Point<3> & lp1 = (*mesh) [el[1]]; + const Point<3> & lp2 = (*mesh) [el[2]]; + + glVertex3dv (lp0); + glVertex3dv (lp1); + glVertex3dv (lp2); + */ + glEnd(); + } + + break; + + } + + case QUAD: + { + CurvedElements & curv = mesh->GetCurvedElements(); + if (curv.IsHighOrder()) // && curv.IsSurfaceElementCurved(sei)) + { + Point<2> xr; + Point<3> xg; + + glBegin (GL_LINE_STRIP); + + for (int side = 0; side < 4; side++) + { + for (int i = 0; i <= hoplotn; i++) + { + switch (side) + { + case 0: + xr(0) = (double) i/hoplotn; + xr(1) = 0.; + break; + case 1: + xr(0) = 1.; + xr(1) = (double) i/hoplotn; + break; + case 2: + xr(0) = (double) (hoplotn-i)/hoplotn; + xr(1) = 1.; + break; + case 3: + xr(0) = 0.; + xr(1) = (double) (hoplotn-i)/hoplotn; + break; + } + + curv.CalcSurfaceTransformation (xr, sei, xg); + glVertex3d (xg(0), xg(1), xg(2)); + + } + + } + glEnd(); + + } else { + + glBegin (GL_QUADS); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(4)); + const Point3d & lp4 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), + Vec3d (lp1, Center (lp3, lp4))); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glEnd(); + + } + + break; + + } + + case TRIG6: + { + int lines[6][2] = { + { 1, 6 }, { 2, 6 }, + { 1, 5 }, { 3, 5 }, + { 2, 4 }, { 3, 4 } }; + + glBegin (GL_LINES); + for (int j = 0; j < 6; j++) + { + const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); + const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); + + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + } + + glEnd(); + break; + } + + case QUAD6: + { + int lines[6][2] = { + { 1, 5 }, { 2, 5 }, + { 3, 6 }, { 4, 6 }, + { 1, 4 }, { 2, 3 } }; + + glBegin (GL_LINES); + + for (int j = 0; j < 6; j++) + { + const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); + const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); + + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + } + glEnd (); + break; + } + + case QUAD8: + { + int lines[8][2] = { + { 1, 5 }, { 2, 5 }, { 3, 6 }, { 4, 6 }, + { 1, 7 }, { 4, 7 }, { 2, 8 }, { 3, 8 } + }; + + glBegin (GL_LINES); + + for (int j = 0; j < 8; j++) + { + const Point3d & lp1 = mesh->Point (el.PNum(lines[j][0])); + const Point3d & lp2 = mesh->Point (el.PNum(lines[j][1])); + + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + } + glEnd (); + break; + } + + + + default: + PrintSysError ("Cannot draw (4) surface element of type ", + int(el.GetType())); + } + } + + glEndList (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (linelist, 0, MPI_TAG_VIS); +#endif + } + + + + void VisualSceneMesh :: BuildEdgeList() + { + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + if (edgetimestamp > mesh->GetTimeStamp () && vispar.shrink == 1) + return; + + edgetimestamp = NextTimeStamp(); + + if (edgelist) + glDeleteLists (edgelist, 1); + + edgelist = glGenLists (1); + glNewList (edgelist, GL_COMPILE); + + + GLfloat matcoledge[] = { 0, 0, 1, 1 }; + GLfloat matcolsingedge[] = { 1, 0, 1, 1 }; + + glEnable (GL_POLYGON_OFFSET_LINE); + glPolygonOffset (1, -1); + + glEnable (GL_COLOR_MATERIAL); + glDisable (GL_LIGHTING); + + for (int i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh->LineSegment(i); + const Point3d & p1 = (*mesh)[seg[0]]; + const Point3d & p2 = (*mesh)[seg[1]]; + + if (seg.singedge_left || seg.singedge_right) + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + matcolsingedge); + else + glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, + matcoledge); + + if (seg.singedge_left || seg.singedge_right) + glColor3fv (matcolsingedge); + else + glColor3fv (matcoledge); + + if (seg.edgenr == seledge) + glLineWidth(5); + else + glLineWidth(2); + + if (mesh->GetCurvedElements().IsHighOrder()) + { + int hoplotn = 1 << vispar.subdivisions; + // mesh->GetCurvedElements().GetNVisualSubsecs(); + + Point<3> x; + glBegin (GL_LINE_STRIP); + + for (int j = 0; j <= hoplotn; j++) + { + mesh->GetCurvedElements().CalcSegmentTransformation ((double) j/hoplotn, i-1, x); + glVertex3d (x(0), x(1), x(2)); + /* + cout << "x = " << x(0) << ", " << x(1) << ", " << x(2) + << ", norm = 1+" << sqrt(x(0)*x(0)+x(1)*x(1))-1 + << ", phi = " << atan2(x(1), x(0))/M_PI << endl; + */ + } + + glEnd(); + + } + else + { + glBegin (GL_LINES); + Point<3> hp1 = p1; + Point<3> hp2 = p2; + Point<3> c = Center(p1, p2); + if (vispar.shrink < 1) + { + hp1 = c + vispar.shrink * (hp1 - c); + hp2 = c + vispar.shrink * (hp2 - c); + } + glVertex3dv (hp1); + glVertex3dv (hp2); // p2.X(), p2.Y(), p2.Z()); + glEnd(); + } + } + + glLineWidth (2); + glDisable (GL_POLYGON_OFFSET_LINE); + + glDisable (GL_COLOR_MATERIAL); + glEnable (GL_LIGHTING); + + glEndList(); + } + + + + + void VisualSceneMesh :: BuildPointNumberList() + { + ; + } + + + + // Bernstein Pol B_{n,i}(x) = n! / i! / (n-i)! (1-x)^{n-i} x^i + static inline double Bernstein (int n, int i, double x) + { + double val = 1; + for (int j = 1; j <= i; j++) + val *= x; + for (int j = 1; j <= n-i; j++) + val *= (1-x) * (j+i) / j; + return val; + } + + void ToBernstein (int order, Point<3> * pts, int stride) + { + static DenseMatrix mat, inv; + static Vector vec1, vec2; + + if (mat.Height () != order+1) + { + mat.SetSize (order+1); + inv.SetSize (order+1); + vec1.SetSize (order+1); + vec2.SetSize (order+1); + for (int i = 0; i <= order; i++) + { + double x = double(i) / order; + for (int j = 0; j <= order; j++) + mat(i,j) = Bernstein (order, j, x); + } + + CalcInverse (mat, inv); + } + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j <= order; j++) + vec1(j) = pts[j*stride](i); + + inv.Mult (vec1, vec2); + + for (int j = 0; j <= order; j++) + pts[j*stride](i) = vec2(j); + } + } + + + + + + + + + + + + + + + void VisualSceneMesh :: BuildTetList() + { + + if (tettimestamp > mesh->GetTimeStamp () && + tettimestamp > vispar.clipping.timestamp ) + return; + + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + tettimestamp = NextTimeStamp(); + + if (tetlist) + glDeleteLists (tetlist, 1); + + + tetlist = glGenLists (1); + glNewList (tetlist, GL_COMPILE); + + + Vector locms; + + // Philippose - 16/02/2010 + // Add Mesh size based coloring of + // meshes also for the volume elements + if (vispar.colormeshsize) + { + glEnable (GL_COLOR_MATERIAL); + locms.SetSize (mesh->GetNP()); + maxh = -1; + minh = 1e99; + for (int i = 1; i <= locms.Size(); i++) + { + Point3d p = mesh->Point(i); + locms(i-1) = mesh->GetH (p); + if (locms(i-1) > maxh) maxh = locms(i-1); + if (locms(i-1) < minh) minh = locms(i-1); + } + if (!locms.Size()) + { + minh = 1; + maxh = 10; + } + } + else + glDisable (GL_COLOR_MATERIAL); + + + + Array faces; + + BitArray shownode(mesh->GetNP()); + if (vispar.clipping.enable) + { + shownode.Clear(); + for (int i = 1; i <= shownode.Size(); i++) + { + Point<3> p = mesh->Point(i); + + double val = + p[0] * clipplane[0] + + p[1] * clipplane[1] + + p[2] * clipplane[2] + + clipplane[3]; + + if (val > 0) shownode.Set (i); + } + } + else + shownode.Set(); + + + static float tetcols[][4] = + { + { 1.0f, 1.0f, 0.0f, 1.0f }, + { 1.0f, 0.0f, 0.0f, 1.0f }, + { 0.0f, 1.0f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f, 1.0f } + /* + { 1.0f, 1.0f, 0.0f, 0.3f }, + { 1.0f, 0.0f, 0.0f, 0.3f }, + { 0.0f, 1.0f, 0.0f, 0.3f }, + { 0.0f, 0.0f, 1.0f, 0.3f } + */ + }; + + static float tetcols_ghost[4][4]; + + for (int j = 0; j < 4; j++) + { + for (int i = 0; i < 3; i++) + tetcols_ghost[j][i] = tetcols[j][i]; + tetcols_ghost[j][3] = 0.3; + } + + + CurvedElements & curv = mesh->GetCurvedElements(); + + + if (!curv.IsHighOrder()) + glShadeModel (GL_FLAT); + else + glShadeModel (GL_SMOOTH); + + int hoplotn = max (2, 1 << vispar.subdivisions); + + + + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + if (vispar.drawtetsdomain > 0) + { + int tetid = vispar.drawmetispartition ? + (*mesh)[ei].GetPartition() : (*mesh)[ei].GetIndex(); + + if (vispar.drawtetsdomain != tetid) continue; + } + + const Element & el = (*mesh)[ei]; + + if ((el.GetType() == TET || el.GetType() == TET10) && !el.IsDeleted()) + { + + bool drawtet = 1; + for (int j = 0; j < 4; j++) + if (!shownode.Test(el[j])) + drawtet = 0; + if (!drawtet) continue; + + int ind = el.GetIndex() % 4; + + if (vispar.drawmetispartition && el.GetPartition()!=-1) + ind = el.GetPartition() % 4; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, tetcols[ind]); + + + if (curv.IsHighOrder()) // && curv.IsElementCurved(ei)) + { + const ELEMENT_FACE * faces = MeshTopology :: GetFaces1 (TET); + const Point3d * vertices = MeshTopology :: GetVertices (TET); + + /* + Point<3> grid[11][11]; + Point<3> fpts[3]; + int order = vispar.subdivisions+1; + + for (int trig = 0; trig < 4; trig++) + { + for (int j = 0; j < 3; j++) + fpts[j] = vertices[faces[trig][j]-1]; + + static Point<3> c(0.25, 0.25, 0.25); + if (vispar.shrink < 1) + for (int j = 0; j < 3; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + for (int ix = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++) + { + double lami[3] = + { (1-double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * (1-double(iy)/order), + double(iy)/order }; + + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l); + + curv.CalcElementTransformation (xl, i-1, grid[ix][iy]); + } + + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); + + glMap2d(GL_MAP2_VERTEX_3, + 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, + 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, + &grid[0][0](0)); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_AUTO_NORMAL); + + glMapGrid2f(8, 0.0, 0.999, 8, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, 8, 0, 8); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + */ + + + + int order = curv.GetOrder(); + + Array > ploc ( (order+1)*(order+1) ); + Array > pglob ( (order+1)*(order+1) ); + Point<3> fpts[3]; + + for (int trig = 0; trig < 4; trig++) + { + for (int j = 0; j < 3; j++) + fpts[j] = vertices[faces[trig][j]-1]; + + static Point<3> c(0.25, 0.25, 0.25); + if (vispar.shrink < 1) + for (int j = 0; j < 3; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + for (int ix = 0, ii = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++, ii++) + { + double lami[3] = + { (1-double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * (1-double(iy)/order), + double(iy)/order }; + + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l); + + ploc[ii] = xl; + } + + curv.CalcMultiPointElementTransformation (&ploc, ei, &pglob, 0); + + Point<3> grid[11][11]; + for (int ix = 0, ii = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++, ii++) + grid[ix][iy] = pglob[ii]; + + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); + + glMap2d(GL_MAP2_VERTEX_3, + 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, + 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, + &grid[0][0](0)); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_AUTO_NORMAL); + + glMapGrid2f(hoplotn, 0.0, 0.9999f, hoplotn, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, hoplotn, 0, hoplotn); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + } + + else // Not High Order + + { + Point<3> pts[4]; + for (int j = 0; j < 4; j++) + pts[j] = (*mesh)[el[j]]; + + if (vispar.shrink < 1) + { + Point<3> c = Center (pts[0], pts[1], pts[2], pts[3]); + for (int j = 0; j < 4; j++) + pts[j] = c + vispar.shrink * (pts[j]-c); + } + + + Vec<3> n; + + + // Philippose - 16/02/2010 + // Add Mesh size based coloring of + // meshes also for the volume elements + if(vispar.colormeshsize) + { + glBegin (GL_TRIANGLE_STRIP); + n = Cross (pts[1]-pts[0], pts[2]-pts[0]); + glNormal3dv (n); + + SetOpenGlColor (locms(el[0]-1), minh, maxh, 0); + glVertex3dv (pts[0]); + + SetOpenGlColor (locms(el[1]-1), minh, maxh, 0); + glVertex3dv (pts[1]); + + SetOpenGlColor (locms(el[2]-1), minh, maxh, 0); + glVertex3dv (pts[2]); + + n = Cross (pts[3]-pts[1], pts[2]-pts[1]); + glNormal3dv (n); + + SetOpenGlColor (locms(el[3]-1), minh, maxh, 0); + glVertex3dv (pts[3]); + + n = Cross (pts[3]-pts[2], pts[0]-pts[2]); + glNormal3dv (n); + + SetOpenGlColor (locms(el[0]-1), minh, maxh, 0); + glVertex3dv (pts[0]); + + n = Cross (pts[1]-pts[3], pts[0]-pts[3]); + glNormal3dv (n); + + SetOpenGlColor (locms(el[1]-1), minh, maxh, 0); + glVertex3dv (pts[1]); + glEnd(); + } + else // Do not color mesh based on mesh size + { + GLubyte ind[4][3] = { { 0,1,2 }, { 3,1,0 }, + { 1,3,2 }, { 2,3,0 } }; + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_DOUBLE, 0, &pts[0](0)); + + for (int j = 0; j < 4; j++) + { + glNormal3dv (Cross (pts[ind[j][1]]-pts[ind[j][0]], + pts[ind[j][2]]-pts[ind[j][0]])); + + glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, &ind[j][0]); + } + glDisableClientState(GL_VERTEX_ARRAY); + + /* + glBegin (GL_TRIANGLE_STRIP); + glNormal3dv (Cross (pts[1]-pts[0], pts[2]-pts[0])); + + glVertex3dv (pts[0]); + glVertex3dv (pts[1]); + glVertex3dv (pts[2]); + + glNormal3dv (Cross (pts[3]-pts[1], pts[2]-pts[1])); + glVertex3dv (pts[3]); + + glNormal3dv (Cross (pts[3]-pts[2], pts[0]-pts[2])); + glVertex3dv (pts[0]); + + glNormal3dv (Cross (pts[1]-pts[3], pts[0]-pts[3])); + glVertex3dv (pts[1]); + glEnd(); + */ + } + + } + } + } + + glEndList (); + } + + + + + void VisualSceneMesh :: BuildPrismList() + { + if (prismtimestamp > mesh->GetTimeStamp () && + prismtimestamp > vispar.clipping.timestamp ) + return; + + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + prismtimestamp = NextTimeStamp(); + + + + if (prismlist) + glDeleteLists (prismlist, 1); + + prismlist = glGenLists (1); + glNewList (prismlist, GL_COMPILE); + + static float prismcol[] = { 0.0f, 1.0f, 1.0f, 1.0f }; + glLineWidth (1.0f); + + Array faces; + + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, prismcol); + + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + const Element & el = (*mesh)[ei]; + if (el.GetType() == PRISM && !el.IsDeleted()) + { + int j; + int i = ei + 1; + + CurvedElements & curv = mesh->GetCurvedElements(); + if (curv.IsHighOrder()) // && curv.IsElementCurved(ei)) + { + const ELEMENT_FACE * faces = MeshTopology :: GetFaces1 (PRISM); + const Point3d * vertices = MeshTopology :: GetVertices (PRISM); + + Point<3> grid[11][11]; + Point<3> fpts[4]; + int order = vispar.subdivisions+1; + + for (int trig = 0; trig < 2; trig++) + { + for (int j = 0; j < 3; j++) + fpts[j] = vertices[faces[trig][j]-1]; + + static Point<3> c(1.0/3.0, 1.0/3.0, 0.5); + if (vispar.shrink < 1) + for (int j = 0; j < 3; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + for (int ix = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++) + { + double lami[3] = + { (1-double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * (1-double(iy)/order), + double(iy)/order }; + + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l); + + curv.CalcElementTransformation (xl, i-1, grid[ix][iy]); + } + + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); + + glMap2d(GL_MAP2_VERTEX_3, + 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, + 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, + &grid[0][0](0)); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_AUTO_NORMAL); + + glMapGrid2f(8, 0.0, 0.999f, 8, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, 8, 0, 8); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + + for (int quad = 2; quad < 5; quad++) + { + for (int j = 0; j < 4; j++) + fpts[j] = vertices[faces[quad][j]-1]; + + static Point<3> c(1.0/3.0, 1.0/3.0, 0.5); + if (vispar.shrink < 1) + for (int j = 0; j < 4; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + for (int ix = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++) + { + double lami[4] = + { (1-double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * ( double(iy)/order), + (1-double(ix)/order) * ( double(iy)/order) }; + + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = + lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l) + lami[3] * fpts[3](l); + + curv.CalcElementTransformation (xl, ei, grid[ix][iy]); + } + + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); + + glMap2d(GL_MAP2_VERTEX_3, + 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, + 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, + &grid[0][0](0)); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_AUTO_NORMAL); + + glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, 8, 0, 8); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + + + + + + /* + int hoplotn = 1 << vispar.subdivisions; + // int hoplotn = curv.GetNVisualSubsecs(); + + const Point3d * facepoint = MeshTopology :: GetVertices (TRIG); + const ELEMENT_FACE * elface = MeshTopology :: GetFaces(TRIG); + + glBegin (GL_TRIANGLES); + + for (int trig = 0; trig<2; trig++) + { + + Vec<3> x0,x1,d0,d1; + x0 = facepoint[1] - facepoint[2]; + x1 = facepoint[0] - facepoint[2]; + x0.Normalize(); + x1.Normalize(); + if (trig == 1) swap (x0,x1); + + Point<3> xr[3]; + Point<3> xg; + Vec<3> dx, dy, dz, n; + + for (int i1 = 0; i1 < hoplotn; i1++) + for (int j1 = 0; j1 < hoplotn-i1; j1++) + for (int k = 0; k < 2; k++) + { + if (k == 0) + { + xr[0](0) = (double) i1/hoplotn; xr[0](1) = (double) j1/hoplotn; + xr[1](0) = (double)(i1+1)/hoplotn; xr[1](1) = (double) j1/hoplotn; + xr[2](0) = (double) i1/hoplotn; xr[2](1) = (double)(j1+1)/hoplotn; + } else + { + if (j1 == hoplotn-i1-1) continue; + xr[0](0) = (double)(i1+1)/hoplotn; xr[0](1) = (double) j1/hoplotn; + xr[1](0) = (double)(i1+1)/hoplotn; xr[1](1) = (double)(j1+1)/hoplotn; + xr[2](0) = (double) i1/hoplotn; xr[2](1) = (double)(j1+1)/hoplotn; + }; + + for (int l=0; l<3; l++) + { + Mat<3,3> dxdxi; + xr[l](2) = (double) trig; + curv.CalcElementTransformation (xr[l], i-1, xg, dxdxi); + for (int i = 0; i < 3; i++) + { + dx(i) = dxdxi(i,0); + dy(i) = dxdxi(i,1); + dz(i) = dxdxi(i,2); + } + + Vec<3> d0 = x0(0)*dx + x0(1)*dy + x0(2)*dz; + Vec<3> d1 = x1(0)*dx + x1(1)*dy + x1(2)*dz; + n = Cross (d1, d0); + glNormal3d (n(0), n(1), n(2)); + glVertex3d (xg(0), xg(1), xg(2)); + } + } + + } + + glEnd (); + + glBegin (GL_QUADS); + + for (int quad = 0; quad<3; quad++) + { + const Point3d * facepoint = MeshTopology :: GetVertices (PRISM); + + Vec<3> x0,x1; + int xyz; + + switch (quad) + { + case 0: + x0 = facepoint[5] - facepoint[2]; + x1 = facepoint[0] - facepoint[2]; + xyz = 0; + break; + case 1: + x0 = facepoint[4] - facepoint[0]; + x1 = facepoint[1] - facepoint[0]; + xyz = 0; + break; + case 2: + x0 = facepoint[1] - facepoint[2]; + x1 = facepoint[5] - facepoint[2]; + xyz = 1; + break; + } + + x0.Normalize(); + x1.Normalize(); + + swap (x0,x1); + + Point<3> xr[4]; + Point<3> xg; + Vec<3> dx, dy, dz, n; + + for (int i1 = 0; i1 < hoplotn; i1++) + for (int j1 = 0; j1 < hoplotn; j1++) + { + xr[0](xyz) = (double) i1/hoplotn; xr[0](2) = (double) j1/hoplotn; + xr[1](xyz) = (double)(i1+1)/hoplotn; xr[1](2) = (double) j1/hoplotn; + xr[2](xyz) = (double)(i1+1)/hoplotn; xr[2](2) = (double)(j1+1)/hoplotn; + xr[3](xyz) = (double) i1/hoplotn; xr[3](2) = (double)(j1+1)/hoplotn; + + for (int l=0; l<4; l++) + { + switch (quad) + { + case 0: xr[l](1) = 0; break; + case 1: xr[l](1) = 1-xr[l](0); break; + case 2: xr[l](0) = 0; break; + } + + Mat<3,3> dxdxi; + curv.CalcElementTransformation (xr[l], i-1, xg, dxdxi); + for (int i = 0; i < 3; i++) + { + dx(i) = dxdxi(i,0); + dy(i) = dxdxi(i,1); + dz(i) = dxdxi(i,2); + } + + Vec<3> d0 = x0(0)*dx + x0(1)*dy + x0(2)*dz; + Vec<3> d1 = x1(0)*dx + x1(1)*dy + x1(2)*dz; + n = Cross (d1, d0); + glNormal3d (n(0), n(1), n(2)); + glVertex3d (xg(0), xg(1), xg(2)); + } + } + } + glEnd (); + */ + } + else + { + Point3d c(0,0,0); + if (vispar.shrink < 1) + { + for (j = 1; j <= 6; j++) + { + Point3d p = mesh->Point(el.PNum(j)); + c.X() += p.X() / 6; + c.Y() += p.Y() / 6; + c.Z() += p.Z() / 6; + } + } + + el.GetSurfaceTriangles (faces); + glBegin (GL_TRIANGLES); + for (j = 1; j <= faces.Size(); j++) + { + Element2d & face = faces.Elem(j); + Point3d lp1 = mesh->Point (el.PNum(face.PNum(1))); + Point3d lp2 = mesh->Point (el.PNum(face.PNum(2))); + Point3d lp3 = mesh->Point (el.PNum(face.PNum(3))); + Vec3d n = Cross (Vec3d (lp1, lp3), Vec3d (lp1, lp2)); + n /= (n.Length()+1e-12); + glNormal3d (n.X(), n.Y(), n.Z()); + if (vispar.shrink < 1) + { + lp1 = c + vispar.shrink * (lp1 - c); + lp2 = c + vispar.shrink * (lp2 - c); + lp3 = c + vispar.shrink * (lp3 - c); + } + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + + glEnd(); + } + } + } + glEndList (); + } + + + + + void VisualSceneMesh :: BuildHexList() + { + if (hextimestamp > mesh->GetTimeStamp () && + hextimestamp > vispar.clipping.timestamp ) + return; + + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + hextimestamp = NextTimeStamp(); + + if (hexlist) glDeleteLists (hexlist, 1); + + hexlist = glGenLists (1); + glNewList (hexlist, GL_COMPILE); + + + static float hexcol[] = { 1.0f, 1.0f, 0.0f, 1.0f }; + glLineWidth (1.0f); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, hexcol); + + Array faces; + // int hoplotn = 1 << vispar.subdivisions; + + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + const Element & el = (*mesh)[ei]; + if (el.GetType() == HEX && !el.IsDeleted()) + { + CurvedElements & curv = mesh->GetCurvedElements(); + if (curv.IsHighOrder()) // && curv.IsElementCurved(ei)) + { + /* // classical + glBegin (GL_QUADS); + + const ELEMENT_FACE * faces = MeshTopology :: GetFaces (HEX); + const Point3d * vertices = MeshTopology :: GetVertices (HEX); + + Point<3> grid[33][33]; + Vec<3> gridn[33][33]; + Point<3> fpts[4]; + for (int quad = 0; quad<6; quad++) + { + for (int j = 0; j < 4; j++) + fpts[j] = vertices[faces[quad][j]-1]; + + static Point<3> c(0.5, 0.5, 0.5); + if (vispar.shrink < 1) + for (int j = 0; j < 4; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + Vec<3> taux = fpts[1]-fpts[0]; + Vec<3> tauy = fpts[3]-fpts[0]; + + for (int ix = 0; ix <= hoplotn; ix++) + for (int iy = 0; iy <= hoplotn; iy++) + { + Point<3> xl; + Mat<3,3> dxdxi; + double lami[4] = + { (1-double(ix)/hoplotn) * (1-double(iy)/hoplotn), + ( double(ix)/hoplotn) * (1-double(iy)/hoplotn), + ( double(ix)/hoplotn) * ( double(iy)/hoplotn), + (1-double(ix)/hoplotn) * ( double(iy)/hoplotn) }; + for (int l = 0; l < 3; l++) + xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l) + lami[3] * fpts[3](l); + + curv.CalcElementTransformation (xl, ei, grid[ix][iy], dxdxi); + + Vec<3> gtaux = dxdxi * taux; + Vec<3> gtauy = dxdxi * tauy; + gridn[ix][iy] = Cross (gtauy, gtaux).Normalize(); + } + + for (int ix = 0; ix < hoplotn; ix++) + for (int iy = 0; iy < hoplotn; iy++) + { + glNormal3dv (gridn[ix][iy]); + glVertex3dv (grid[ix][iy]); + + glNormal3dv (gridn[ix+1][iy]); + glVertex3dv (grid[ix+1][iy]); + + glNormal3dv (gridn[ix+1][iy+1]); + glVertex3dv (grid[ix+1][iy+1]); + + glNormal3dv (gridn[ix][iy+1]); + glVertex3dv (grid[ix][iy+1]); + } + } + + glEnd (); + */ + + const ELEMENT_FACE * faces = MeshTopology :: GetFaces1 (HEX); + const Point3d * vertices = MeshTopology :: GetVertices (HEX); + + Point<3> grid[11][11]; + Point<3> fpts[4]; + int order = vispar.subdivisions+1; + + for (int quad = 0; quad<6; quad++) + { + for (int j = 0; j < 4; j++) + fpts[j] = vertices[faces[quad][j]-1]; + + static Point<3> c(0.5, 0.5, 0.5); + if (vispar.shrink < 1) + for (int j = 0; j < 4; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + for (int ix = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++) + { + double lami[4] = + { (1-double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * ( double(iy)/order), + (1-double(ix)/order) * ( double(iy)/order) }; + + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l) + lami[3] * fpts[3](l); + + curv.CalcElementTransformation (xl, ei, grid[ix][iy]); + } + + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); + + glMap2d(GL_MAP2_VERTEX_3, + 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, + 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, + &grid[0][0](0)); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_AUTO_NORMAL); + + glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, 8, 0, 8); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + } + else + { + Point3d c(0,0,0); + if (vispar.shrink < 1) + { + for (int j = 1; j <= 8; j++) + { + Point3d p = mesh->Point(el.PNum(j)); + c.X() += p.X(); + c.Y() += p.Y(); + c.Z() += p.Z(); + } + c.X() /= 8; + c.Y() /= 8; + c.Z() /= 8; + } + + glBegin (GL_TRIANGLES); + + el.GetSurfaceTriangles (faces); + for (int j = 1; j <= faces.Size(); j++) + { + Element2d & face = faces.Elem(j); + Point<3> lp1 = mesh->Point (el.PNum(face.PNum(1))); + Point<3> lp2 = mesh->Point (el.PNum(face.PNum(2))); + Point<3> lp3 = mesh->Point (el.PNum(face.PNum(3))); + Vec<3> n = Cross (lp3-lp1, lp2-lp1); + n.Normalize(); + glNormal3dv (n); + + if (vispar.shrink < 1) + { + lp1 = c + vispar.shrink * (lp1 - c); + lp2 = c + vispar.shrink * (lp2 - c); + lp3 = c + vispar.shrink * (lp3 - c); + } + + glVertex3dv (lp1); + glVertex3dv (lp2); + glVertex3dv (lp3); + } + + glEnd(); + } + } + } + glEndList (); + } + + + + + + + + + + void VisualSceneMesh :: BuildPyramidList() + { + if (pyramidtimestamp > mesh->GetTimeStamp () && + pyramidtimestamp > vispar.clipping.timestamp ) + return; + + if (!lock) + { + lock = new NgLock (mesh->Mutex()); + lock -> Lock(); + } + + pyramidtimestamp = NextTimeStamp(); + + + if (pyramidlist) + glDeleteLists (pyramidlist, 1); + + + pyramidlist = glGenLists (1); + glNewList (pyramidlist, GL_COMPILE); + + static float pyramidcol[] = { 1.0f, 0.0f, 1.0f, 1.0f }; + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, pyramidcol); + + glLineWidth (1.0f); + Array faces; + + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + const Element & el = (*mesh)[ei]; + if (el.GetType() == PYRAMID && !el.IsDeleted()) + { + int i = ei + 1; + + CurvedElements & curv = mesh->GetCurvedElements(); + if (curv.IsHighOrder()) // && curv.IsElementCurved(ei)) + { + + const ELEMENT_FACE * faces = MeshTopology :: GetFaces1 (PYRAMID); + const Point3d * vertices = MeshTopology :: GetVertices (PYRAMID); + + Point<3> grid[11][11]; + Point<3> fpts[4]; + int order = vispar.subdivisions+1; + + for (int trig = 0; trig < 4; trig++) + { + for (int j = 0; j < 3; j++) + fpts[j] = vertices[faces[trig][j]-1]; + + static Point<3> c(0.375, 0.375, 0.25); + if (vispar.shrink < 1) + for (int j = 0; j < 3; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + for (int ix = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++) + { + double lami[3] = + { (1-double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * (1-double(iy)/order), + double(iy)/order }; + + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l); + + curv.CalcElementTransformation (xl, i-1, grid[ix][iy]); + } + + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); + + glMap2d(GL_MAP2_VERTEX_3, + 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, + 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, + &grid[0][0](0)); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_AUTO_NORMAL); + + glMapGrid2f(8, 0.0, 0.999f, 8, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, 8, 0, 8); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + + for (int quad = 4; quad < 5; quad++) + { + for (int j = 0; j < 4; j++) + fpts[j] = vertices[faces[quad][j]-1]; + + static Point<3> c(0.375, 0.375, 0.25); + if (vispar.shrink < 1) + for (int j = 0; j < 4; j++) + fpts[j] += (1-vispar.shrink) * (c-fpts[j]); + + for (int ix = 0; ix <= order; ix++) + for (int iy = 0; iy <= order; iy++) + { + double lami[4] = + { (1-double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * (1-double(iy)/order), + ( double(ix)/order) * ( double(iy)/order), + (1-double(ix)/order) * ( double(iy)/order) }; + + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = + lami[0] * fpts[0](l) + lami[1] * fpts[1](l) + + lami[2] * fpts[2](l) + lami[3] * fpts[3](l); + + curv.CalcElementTransformation (xl, ei, grid[ix][iy]); + } + + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[j][0], &grid[0][1]-&grid[0][0]); + for (int j = 0; j <= order; j++) + ToBernstein (order, &grid[0][j], &grid[1][0]-&grid[0][0]); + + glMap2d(GL_MAP2_VERTEX_3, + 0.0, 1.0, &grid[0][1](0)-&grid[0][0](0), order+1, + 0.0, 1.0, &grid[1][0](0)-&grid[0][0](0), order+1, + &grid[0][0](0)); + glEnable(GL_MAP2_VERTEX_3); + glEnable(GL_AUTO_NORMAL); + + glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0); + glEvalMesh2(GL_FILL, 0, 8, 0, 8); + + glDisable (GL_AUTO_NORMAL); + glDisable (GL_MAP2_VERTEX_3); + } + + + + + + + /* + int hoplotn = 1 << vispar.subdivisions; + + const ELEMENT_FACE * faces = MeshTopology :: GetFaces (PYRAMID); + const Point3d * vertices = MeshTopology :: GetVertices (PYRAMID); + + Point<3> grid[33][33]; + Vec<3> gridn[33][33]; + + + glBegin (GL_TRIANGLES); + + for (int trig = 0; trig < 4; trig++) + { + Point<3> p0 = vertices[faces[trig][0]-1]; + Point<3> p1 = vertices[faces[trig][1]-1]; + Point<3> p2 = vertices[faces[trig][2]-1]; + + if (vispar.shrink < 1) + { + static Point<3> c(0.375, 0.375, 0.25); + p0 = c + vispar.shrink * (p0 - c); + p1 = c + vispar.shrink * (p1 - c); + p2 = c + vispar.shrink * (p2 - c); + } + + + Vec<3> taux = p0-p2; + Vec<3> tauy = p1-p2; + Vec<3> gtaux, gtauy; + + Point<3> xl; + Mat<3,3> dxdxi; + + for (int ix = 0; ix <= hoplotn; ix++) + for (int iy = 0; iy <= hoplotn-ix; iy++) + { + for (int l = 0; l < 3; l++) + xl(l) = + (1-double(ix+iy)/hoplotn) * p2(l) + + (double(ix)/hoplotn) * p0(l) + + (double(iy)/hoplotn) * p1(l); + + curv.CalcElementTransformation (xl, i-1, grid[ix][iy], dxdxi); + + gtaux = dxdxi * taux; + gtauy = dxdxi * tauy; + gridn[ix][iy] = Cross (gtauy, gtaux).Normalize(); + } + + for (int ix = 0; ix < hoplotn; ix++) + for (int iy = 0; iy < hoplotn-ix; iy++) + { + glNormal3dv (gridn[ix][iy]); + glVertex3dv (grid[ix][iy]); + + glNormal3dv (gridn[ix+1][iy]); + glVertex3dv (grid[ix+1][iy]); + + glNormal3dv (gridn[ix][iy+1]); + glVertex3dv (grid[ix][iy+1]); + + if (iy < hoplotn-ix-1) + { + glNormal3dv (gridn[ix][iy+1]); + glVertex3dv (grid[ix][iy+1]); + + glNormal3dv (gridn[ix+1][iy]); + glVertex3dv (grid[ix+1][iy]); + + glNormal3dv (gridn[ix+1][iy+1]); + glVertex3dv (grid[ix+1][iy+1]); + } + } + } + + glEnd (); + + + + + glBegin (GL_QUADS); + + for (int quad = 4; quad < 5; quad++) + { + Point<3> p0 = vertices[faces[quad][0]-1]; + Point<3> p1 = vertices[faces[quad][1]-1]; + Point<3> p2 = vertices[faces[quad][2]-1]; + Point<3> p3 = vertices[faces[quad][3]-1]; + + if (vispar.shrink < 1) + { + static Point<3> c(0.375, 0.375, 0.25); + p0 = c + vispar.shrink * (p0 - c); + p1 = c + vispar.shrink * (p1 - c); + p2 = c + vispar.shrink * (p2 - c); + p3 = c + vispar.shrink * (p3 - c); + } + + Vec<3> taux = p1-p0; + Vec<3> tauy = p3-p0; + Vec<3> gtaux, gtauy; + + Point<3> xl, xg; + Mat<3,3> dxdxi; + + for (int ix = 0; ix <= hoplotn; ix++) + for (int iy = 0; iy <= hoplotn; iy++) + { + Point<3> xl; + for (int l = 0; l < 3; l++) + xl(l) = + (1-double(ix)/hoplotn)*(1-double(iy)/hoplotn) * p0(l) + + ( double(ix)/hoplotn)*(1-double(iy)/hoplotn) * p1(l) + + ( double(ix)/hoplotn)*( double(iy)/hoplotn) * p2(l) + + (1-double(ix)/hoplotn)*( double(iy)/hoplotn) * p3(l); + + curv.CalcElementTransformation (xl, i-1, grid[ix][iy], dxdxi); + + gtaux = dxdxi * taux; + gtauy = dxdxi * tauy; + gridn[ix][iy] = Cross (gtauy, gtaux).Normalize(); + } + + for (int ix = 0; ix < hoplotn; ix++) + for (int iy = 0; iy < hoplotn; iy++) + { + glNormal3dv (gridn[ix][iy]); + glVertex3dv (grid[ix][iy]); + + glNormal3dv (gridn[ix+1][iy]); + glVertex3dv (grid[ix+1][iy]); + + glNormal3dv (gridn[ix+1][iy+1]); + glVertex3dv (grid[ix+1][iy+1]); + + glNormal3dv (gridn[ix][iy+1]); + glVertex3dv (grid[ix][iy+1]); + } + } + + glEnd (); + */ + + + } + else + { + + + + Point3d c(0,0,0); + if (vispar.shrink < 1) + { + for (int j = 1; j <= 5; j++) + { + Point3d p = mesh->Point(el.PNum(j)); + c.X() += p.X() / 5; + c.Y() += p.Y() / 5; + c.Z() += p.Z() / 5; + } + } + + + el.GetSurfaceTriangles (faces); + + if (el.PNum(1)) + { + glBegin (GL_TRIANGLES); + + for (int j = 1; j <= faces.Size(); j++) + { + Element2d & face = faces.Elem(j); + Point3d lp1 = mesh->Point (el.PNum(face.PNum(1))); + Point3d lp2 = mesh->Point (el.PNum(face.PNum(2))); + Point3d lp3 = mesh->Point (el.PNum(face.PNum(3))); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (n.Length()+1e-12); + n *= -1; + glNormal3d (n.X(), n.Y(), n.Z()); + + if (vispar.shrink < 1) + { + lp1 = c + vispar.shrink * (lp1 - c); + lp2 = c + vispar.shrink * (lp2 - c); + lp3 = c + vispar.shrink * (lp3 - c); + } + + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + + glEnd(); + } + } + } + } + glEndList (); + } + + void VisualSceneMesh :: BuildBadelList() + { + ; + } + + void VisualSceneMesh :: BuildIdentifiedList() + { + ; + } + + void VisualSceneMesh :: BuildDomainSurfList() + { + if (domainsurflist) + glDeleteLists (domainsurflist, 1); + + domainsurflist = glGenLists (1); + glNewList (domainsurflist, GL_COMPILE); + + int i, j; + glLineWidth (1.0f); + + glDisable (GL_COLOR_MATERIAL); + + for (i = 1; i <= mesh->GetNSE(); i++) + { + Element2d el = mesh->SurfaceElement (i); + + int drawel = 1; + for (j = 1; j <= el.GetNP(); j++) + { + if (!el.PNum(j)) + drawel = 0; + } + + if (!drawel) + continue; + + if (el.GetIndex() < 1 || el.GetIndex() > mesh->GetNFD()) + continue; + int domin = mesh->GetFaceDescriptor(el.GetIndex()).DomainIn(); + int domout = mesh->GetFaceDescriptor(el.GetIndex()).DomainOut(); + + int fac; + if (domin == vispar.drawdomainsurf) + fac = 1; + else if (domout == vispar.drawdomainsurf) + fac = -1; + else + continue; + + + GLfloat matcol[] = { 1, 0, 0, 1 }; + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol); + + + if (el.GetNP() == 3) + { + glBegin (GL_TRIANGLES); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= ( fac * (n.Length()+1e-12)); + glNormal3d (n.X(), n.Y(), n.Z()); + + if (!vispar.colormeshsize) + { + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + glEnd(); + } + else if (el.GetNP() == 4) + { + glBegin (GL_QUADS); + + const Point3d & lp1 = mesh->Point (el.PNum(1)); + const Point3d & lp2 = mesh->Point (el.PNum(2)); + const Point3d & lp3 = mesh->Point (el.PNum(4)); + const Point3d & lp4 = mesh->Point (el.PNum(3)); + Vec3d n = Cross (Vec3d (lp1, lp2), + Vec3d (lp1, Center (lp3, lp4))); + n /= (fac * (n.Length()+1e-12)); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp4.X(), lp4.Y(), lp4.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + glEnd(); + } + else if (el.GetNP() == 6) + { + glBegin (GL_TRIANGLES); + static int trigs[4][3] = { + { 1, 6, 5 }, + { 2, 4, 6 }, + { 3, 5, 4 }, + { 4, 5, 6 } }; + + for (j = 0; j < 4; j++) + { + const Point3d & lp1 = mesh->Point (el.PNum(trigs[j][0])); + const Point3d & lp2 = mesh->Point (el.PNum(trigs[j][1])); + const Point3d & lp3 = mesh->Point (el.PNum(trigs[j][2])); + Vec3d n = Cross (Vec3d (lp1, lp2), Vec3d (lp1, lp3)); + n /= (fac * (n.Length() + 1e-12)); + glNormal3d (n.X(), n.Y(), n.Z()); + glVertex3d (lp1.X(), lp1.Y(), lp1.Z()); + glVertex3d (lp2.X(), lp2.Y(), lp2.Z()); + glVertex3d (lp3.X(), lp3.Y(), lp3.Z()); + } + glEnd(); + } + } + glEndList (); + } + + + + + + + + + void VisualSceneMesh :: MouseDblClick (int px, int py) + { + BuildFilledList (true); + + MouseDblClickSelect(px,py,clipplane,backcolor,transformationmat,center,rad, + filledlist,selelement,selface,seledge,selpoint,selpoint2,locpi); + + + if (user_me_handler) + { + if (selelement != -1) + user_me_handler -> DblClick (selelement-1); + } + + selecttimestamp = NextTimeStamp(); + + if(lock) + { + lock->UnLock(); + delete lock; + lock = NULL; + } + + /* + int i, hits; + + // select surface triangle by mouse click + + GLuint selbuf[10000]; + glSelectBuffer (10000, selbuf); + + + glRenderMode (GL_SELECT); + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + + GLdouble projmat[16]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + + glLoadIdentity(); + gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); + glMultMatrixd (projmat); + + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_MODELVIEW); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + + // SetClippingPlane(); + + glInitNames(); + glPushName (1); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glDisable(GL_CLIP_PLANE0); + + if (vispar.clipenable) + { + Vec<3> n(clipplane[0], clipplane[1], clipplane[2]); + double len = Abs(n); + double mu = -clipplane[3] / (len*len); + Point<3> p (mu * n); + n /= len; + Vec<3> t1 = n.GetNormal (); + Vec<3> t2 = Cross (n, t1); + + double xi1mid = (center - p) * t1; + double xi2mid = (center - p) * t2; + + glLoadName (0); + glBegin (GL_QUADS); + glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2); + glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2); + glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2); + glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2); + glEnd (); + } + + // SetClippingPlane(); + + glCallList (filledlist); + + glDisable (GL_POLYGON_OFFSET_FILL); + + glPopName(); + + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + + glFlush(); + + + hits = glRenderMode (GL_RENDER); + + // cout << "hits = " << hits << endl; + + int minname = 0; + GLuint mindepth = 0; + + // find clippingplane + GLuint clipdepth = 0; // GLuint(-1); + + for (i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + if (!curname) clipdepth = selbuf[4*i+1]; + } + + for (i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + GLuint curdepth = selbuf[4*i+1]; + + if (curname && (curdepth > clipdepth) && + (curdepth < mindepth || !minname)) + { + mindepth = curdepth; + minname = curname; + } + } + + seledge = -1; + if (minname) + { + const Element2d & sel = mesh->SurfaceElement(minname); + + + cout << "select element " << minname + << " on face " << sel.GetIndex() << endl; + cout << "Nodes: "; + for (i = 1; i <= sel.GetNP(); i++) + cout << sel.PNum(i) << " "; + cout << endl; + + selelement = minname; + selface = mesh->SurfaceElement(minname).GetIndex(); + + locpi = (locpi % sel.GetNP()) + 1; + selpoint2 = selpoint; + selpoint = sel.PNum(locpi); + cout << "selected point " << selpoint + << ", pos = " << mesh->Point (selpoint) + << endl; + + for (i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh->LineSegment(i); + if (seg[0] == selpoint && seg[1] == selpoint2 || + seg[1] == selpoint && seg[0] == selpoint2) + { + seledge = seg.edgenr; + cout << "seledge = " << seledge << endl; + } + } + + } + else + { + selface = -1; + selelement = -1; + selpoint = -1; + selpoint2 = -1; + } + + glDisable(GL_CLIP_PLANE0); + + selecttimestamp = NextTimeStamp(); + */ + + } + + + + + + void MouseDblClickSelect (const int px, const int py, + const GLdouble * clipplane, const GLdouble backcolor, + const float * transformationmat, + const Point3d & center, + const double rad, + const int displaylist, + int & selelement, int & selface, int & seledge, int & selpoint, + int & selpoint2, int & locpi) + { + int i, hits; + + // select surface triangle by mouse click + + GLuint selbuf[10000]; + glSelectBuffer (10000, selbuf); + + + glRenderMode (GL_SELECT); + + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + + glMatrixMode (GL_PROJECTION); + glPushMatrix(); + + GLdouble projmat[16]; + glGetDoublev (GL_PROJECTION_MATRIX, projmat); + + glLoadIdentity(); + gluPickMatrix (px, viewport[3] - py, 1, 1, viewport); + glMultMatrixd (projmat); + + + + glClearColor(backcolor, backcolor, backcolor, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode (GL_MODELVIEW); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + + // SetClippingPlane(); + + glInitNames(); + glPushName (1); + + glPolygonOffset (1, 1); + glEnable (GL_POLYGON_OFFSET_FILL); + + glDisable(GL_CLIP_PLANE0); + + if (vispar.clipping.enable) + { + Vec<3> n(clipplane[0], clipplane[1], clipplane[2]); + double len = Abs(n); + double mu = -clipplane[3] / (len*len); + Point<3> p (mu * n); + n /= len; + Vec<3> t1 = n.GetNormal (); + Vec<3> t2 = Cross (n, t1); + + double xi1mid = (center - p) * t1; + double xi2mid = (center - p) * t2; + + glLoadName (0); + glBegin (GL_QUADS); + glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2); + glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2); + glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2); + glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2); + glEnd (); + } + + // SetClippingPlane(); + glCallList (displaylist); + + glDisable (GL_POLYGON_OFFSET_FILL); + + glPopName(); + + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); + + glFlush(); + + + hits = glRenderMode (GL_RENDER); + //cout << "hits = " << hits << endl; + + int minname = 0; + GLuint mindepth = 0; + + // find clippingplane + GLuint clipdepth = 0; // GLuint(-1); + + for (i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + if (!curname) clipdepth = selbuf[4*i+1]; + } + + for (i = 0; i < hits; i++) + { + int curname = selbuf[4*i+3]; + GLuint curdepth = selbuf[4*i+1]; + /* + cout << selbuf[4*i] << " " << selbuf[4*i+1] << " " + << selbuf[4*i+2] << " " << selbuf[4*i+3] << endl; + */ + if (curname && (curdepth > clipdepth) && + (curdepth < mindepth || !minname)) + { + mindepth = curdepth; + minname = curname; + } + } + + seledge = -1; + if (minname) + { + const Element2d & sel = mesh->SurfaceElement(minname); + + + cout << "select element " << minname + << " on face " << sel.GetIndex() << endl; + cout << "Nodes: "; + for (i = 1; i <= sel.GetNP(); i++) + cout << sel.PNum(i) << " "; + cout << endl; + + selelement = minname; + selface = mesh->SurfaceElement(minname).GetIndex(); + + locpi = (locpi % sel.GetNP()) + 1; + selpoint2 = selpoint; + selpoint = sel.PNum(locpi); + cout << "selected point " << selpoint + << ", pos = " << mesh->Point (selpoint) + << endl; + + for (i = 1; i <= mesh->GetNSeg(); i++) + { + const Segment & seg = mesh->LineSegment(i); + if ( (seg[0] == selpoint && seg[1] == selpoint2) || + (seg[1] == selpoint && seg[0] == selpoint2) ) + { + seledge = seg.edgenr; + cout << "seledge = " << seledge << endl; + } + } + } + else + { + selface = -1; + selelement = -1; + selpoint = -1; + selpoint2 = -1; + } + + glDisable(GL_CLIP_PLANE0); + + + +#ifdef PARALLELGL + vsmesh.Broadcast (); +#endif + } + + + void VisualSceneMesh :: SetSelectedFace (int asf) + { + selface = asf; + selecttimestamp = NextTimeStamp(); + } + + + + +} + + diff --git a/libsrc/visualization/vssolution.cpp b/libsrc/visualization/vssolution.cpp new file mode 100644 index 00000000..8564b6fc --- /dev/null +++ b/libsrc/visualization/vssolution.cpp @@ -0,0 +1,4850 @@ +#ifndef NOTCL +#include +#include "incvis.hpp" + + +#include +#include +#include +#include + + +// #include +#include + +#include + +namespace netgen +{ + extern AutoPtr mesh; + extern VisualSceneMesh vsmesh; + + + VisualSceneSolution :: SolData :: SolData () + : name (0), data (0), solclass(0) + { ; } + + VisualSceneSolution :: SolData :: ~SolData () + { + delete [] name; + delete data; + delete solclass; + } + + + VisualSceneSolution :: VisualSceneSolution () + : VisualScene() + { + surfellist = 0; + linelist = 0; + element1dlist = 0; + clipplanelist_scal = 0; + clipplanelist_vec = 0; + isolinelist = 0; + clipplane_isolinelist = 0; + surface_vector_list = 0; + isosurface_list = 0; + + fieldlineslist = 0; + pointcurvelist = 0; + + num_fieldlineslists = 0; + + + surfeltimestamp = GetTimeStamp(); + surfellinetimestamp = GetTimeStamp(); + clipplanetimestamp = GetTimeStamp(); + solutiontimestamp = GetTimeStamp(); + fieldlinestimestamp = GetTimeStamp(); + pointcurve_timestamp = GetTimeStamp(); + surface_vector_timestamp = GetTimeStamp(); + isosurface_timestamp = GetTimeStamp(); + timetimestamp = GetTimeStamp(); + AddVisualizationScene ("solution", &vssolution); + } + + VisualSceneSolution :: ~VisualSceneSolution () + { + ClearSolutionData(); + } + + void VisualSceneSolution :: AddSolutionData (SolData * sd) + { + NgLock meshlock1 (mesh->MajorMutex(), 1); + int funcnr = -1; + for (int i = 0; i < soldata.Size(); i++) + { + if (strcmp (soldata[i]->name, sd->name) == 0) + { + delete soldata[i]; + soldata[i] = sd; + funcnr = i; + break; + } + } + + if (funcnr == -1) + { + soldata.Append (sd); + funcnr = soldata.Size()-1; + } + + SolData * nsd = soldata[funcnr]; + + nsd->size = 0; + if (mesh) + { + switch (nsd->soltype) + { + case SOL_NODAL: nsd->size = mesh->GetNV(); break; + case SOL_ELEMENT: nsd->size = mesh->GetNE(); break; + case SOL_SURFACE_ELEMENT: nsd->size = mesh->GetNSE(); break; + case SOL_NONCONTINUOUS: + { + switch (nsd->order) + { + case 0: nsd->size = mesh->GetNE(); break; + case 1: nsd->size = 6 * mesh->GetNE(); break; + case 2: nsd->size = 18 * mesh->GetNE(); break; + } + break; + } + case SOL_SURFACE_NONCONTINUOUS: + { + switch (nsd->order) + { + case 0: nsd->size = mesh->GetNSE(); break; + case 1: nsd->size = 4 * mesh->GetNSE(); break; + case 2: nsd->size = 9 * mesh->GetNSE(); break; + } + break; + } + default: + nsd->size = 0; + } + solutiontimestamp = NextTimeStamp(); + } + } + + + void VisualSceneSolution :: ClearSolutionData () + { + for (int i = 0; i < soldata.Size(); i++) + delete soldata[i]; + soldata.SetSize (0); + } + + void VisualSceneSolution :: UpdateSolutionTimeStamp () + { + solutiontimestamp = NextTimeStamp(); + } + + VisualSceneSolution::SolData * VisualSceneSolution :: GetSolData (int i) + { + if (i >= 0 && i < soldata.Size()) + return soldata[i]; + else + return NULL; + } + + + + + void VisualSceneSolution :: SaveSolutionData (const char * filename) + { + PrintMessage (1, "Write solution data to file ", filename); + + + if (strcmp (&filename[strlen(filename)-3], "sol") == 0) + { + ofstream ost(filename); + for (int i = 0; i < soldata.Size(); i++) + { + const SolData & sol = *soldata[i]; + + ost << "solution " + << sol.name + << " -size=" << sol.size + << " -components=" << sol.components + << " -order=" << sol.order; + if (sol.iscomplex) + ost << " -complex"; + + switch (sol.soltype) + { + case SOL_NODAL: + ost << " -type=nodal"; break; + case SOL_ELEMENT: + ost << " -type=element"; break; + case SOL_SURFACE_ELEMENT: + ost << " -type=surfaceelement"; break; + case SOL_NONCONTINUOUS: + ost << " -type=noncontinuous"; break; + case SOL_SURFACE_NONCONTINUOUS: + ost << " -type=surfacenoncontinuous"; break; + default: + cerr << "save solution data, case not handeld" << endl; + } + + ost << endl; + for (int j = 0; j < sol.size; j++) + { + for (int k = 0; k < sol.components; k++) + ost << sol.data[j*sol.dist+k] << " "; + ost << "\n"; + } + } + } + + + if (strcmp (&filename[strlen(filename)-3], "vtk") == 0) + { + string surf_fn = filename; + surf_fn.erase (strlen(filename)-4); + surf_fn += "_surf.vtk"; + + cout << "surface mesh = " << surf_fn << endl; + + ofstream surf_ost(surf_fn.c_str()); + + surf_ost << "# vtk DataFile Version 1.0\n" + << "NGSolve surface mesh\n" + << "ASCII\n" + << "DATASET UNSTRUCTURED_GRID\n\n"; + + surf_ost << "POINTS " << mesh->GetNP() << " float\n"; + for (PointIndex pi = PointIndex::BASE; pi < mesh->GetNP()+PointIndex::BASE; pi++) + { + const MeshPoint & mp = (*mesh)[pi]; + surf_ost << mp(0) << " " << mp(1) << " " << mp(2) << "\n"; + } + + int cntverts = 0; + for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) + cntverts += 1 + (*mesh)[sei].GetNP(); + + surf_ost << "\nCELLS " << mesh->GetNSE() << " " << cntverts << "\n"; + for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) + { + const Element2d & el = (*mesh)[sei]; + surf_ost << el.GetNP(); + for (int j = 0; j < el.GetNP(); j++) + surf_ost << " " << el[j] - PointIndex::BASE; + surf_ost << "\n"; + } + surf_ost << "\nCELL_TYPES " << mesh->GetNSE() << "\n"; + for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++) + { + const Element2d & el = (*mesh)[sei]; + switch (el.GetType()) + { + case QUAD: surf_ost << 9; break; + case TRIG: surf_ost << 5; break; + default: + cerr << "not implemented 2378" << endl; + } + surf_ost << "\n"; + } + + + + ofstream ost(filename); + + ost << "# vtk DataFile Version 1.0\n" + << "NGSolve solution\n" + << "ASCII\n" + << "DATASET UNSTRUCTURED_GRID\n\n"; + + ost << "POINTS " << mesh->GetNP() << " float\n"; + for (PointIndex pi = PointIndex::BASE; pi < mesh->GetNP()+PointIndex::BASE; pi++) + { + const MeshPoint & mp = (*mesh)[pi]; + ost << mp(0) << " " << mp(1) << " " << mp(2) << "\n"; + } + + cntverts = 0; + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + cntverts += 1 + (*mesh)[ei].GetNP(); + + ost << "\nCELLS " << mesh->GetNE() << " " << cntverts << "\n"; + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + const Element & el = (*mesh)[ei]; + ost << el.GetNP(); + for (int j = 0; j < el.GetNP(); j++) + ost << " " << el[j] - PointIndex::BASE; + ost << "\n"; + } + ost << "\nCELL_TYPES " << mesh->GetNE() << "\n"; + for (ElementIndex ei = 0; ei < mesh->GetNE(); ei++) + { + const Element & el = (*mesh)[ei]; + switch (el.GetType()) + { + case TET: ost << 10; break; + default: + cerr << "not implemented 67324" << endl; + } + ost << "\n"; + } + + + ost << "CELL_DATA " << mesh->GetNE() << "\n"; + for (int i = 0; i < soldata.Size(); i++) + { + ost << "VECTORS bfield float\n"; + SolutionData & sol = *(soldata[i] -> solclass); + double values[3]; + + for (int elnr = 0; elnr < mesh->GetNE(); elnr++) + { + sol.GetValue (elnr, 0.25, 0.25, 0.25, values); + ost << values[0] << " " << values[1] << " " << values[2] << "\n"; + } + } + + /* + ost << "POINT_DATA " << mesh->GetNP() << "\n"; + for (int i = 0; i < soldata.Size(); i++) + { + ost << "VECTORS bfield float\n"; + SolutionData & sol = *(soldata[i] -> solclass); + + for (PointIndex pi = PointIndex::BASE; + pi < mesh->GetNP()+PointIndex::BASE; pi++) + { + double values[3], sumvalues[3] = { 0, 0, 0 }; + + FlatArray els = mesh->GetTopology().GetVertexElements(pi); + + for (int j = 0; j < els.Size(); j++) + { + sol.GetValue (els[j]-1, 0.25, 0.25, 0.25, values); + for (int k = 0; k < 3; k++) + sumvalues[k] += values[k]; + } + for (int k = 0; k < 3; k++) + sumvalues[k] /= els.Size(); + + ost << sumvalues[0] << " " << sumvalues[1] << " " << sumvalues[2] << "\n"; + } + } + */ + } + + } + + + + + void VisualSceneSolution :: DrawScene () + { + if (!mesh) + { + VisualScene::DrawScene(); + return; + } + + // static NgLock mem_lock(mem_mutex); + // mem_lock.Lock(); + + NgLock meshlock1 (mesh->MajorMutex(), true); + NgLock meshlock (mesh->Mutex(), true); + + BuildScene(); + + CreateTexture (numtexturecols, lineartexture, 0.5, GL_MODULATE); + + glClearColor(backcolor, backcolor, backcolor, 1); + // glClearColor(backcolor, backcolor, backcolor, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + SetLight(); + + glPushMatrix(); + glMultMatrixf (transformationmat); + + glMatrixMode (GL_MODELVIEW); + + glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + glPolygonOffset (1, 1); + + glEnable (GL_POLYGON_OFFSET_FILL); + + glEnable (GL_COLOR_MATERIAL); + + if (usetexture) + { + SetTextureMode (usetexture); + + glMatrixMode (GL_TEXTURE); + glLoadIdentity(); + + if (usetexture == 1) + { + double hmax = maxval; + double hmin = minval; + if (invcolor) Swap (hmax, hmin); + + if (fabs (hmax - hmin) > 1e-30) + glScaled (1.0 / (hmin - hmax), 0, 0); + else + glScaled (1e30, 0, 0); + + glTranslatef (-hmax, 0, 0); + } + else + { + glTranslatef (0.5, 0, 0); + glRotatef(360 * vssolution.time, 0, 0, -1); + if (fabs (maxval) > 1e-10) + glScalef(0.5/maxval, 0.5/maxval, 0.5/maxval); + else + glScalef (1e10, 1e10, 1e10); + } + glMatrixMode (GL_MODELVIEW); + } + + + + + if (vispar.drawfilledtrigs || vispar.drawtetsdomain > 0 || vispar.drawdomainsurf > 0) + { + // Change for Martin: + + // orig: + SetClippingPlane (); + + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + // glEnable(GL_BLEND); + glDisable(GL_BLEND); + glCallList (surfellist); + glDisable(GL_BLEND); + /* + // transparent test ... + glColor4f (1, 0, 0, 0.1); + glEnable (GL_COLOR_MATERIAL); + + glDepthFunc(GL_GREATER); + glDepthMask(GL_FALSE); + // glBlendFunc(GL_ONE_MINUS_DST_ALPHA,GL_DST_ALPHA); + glBlendFunc(GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA); + + glCallList (surfellist); + + glDisable(GL_BLEND); + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + + glCallList (surfellist); + // end test ... + */ + + + glCallList (surface_vector_list); + glDisable(GL_CLIP_PLANE0); + } + + + if (showclipsolution) + { + if (clipsolution == 1) + { + // Martin + // orig: + glCallList (clipplanelist_scal); + + // transparent experiments + // see http://wiki.delphigl.com/index.php/Blenden + + /* + glColor4f (1, 1, 1, 0.5); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_COLOR); + glDepthFunc(GL_GREATER); + glDepthMask(GL_FALSE); + + glCallList (clipplanelist_scal); + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + + glCallList (clipplanelist_scal); + glDisable(GL_BLEND); + */ + + + /* + // latest transparent version ... + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + + // CreateTexture (numtexturecols, lineartexture, 0.25, GL_MODULATE); + // glCallList (clipplanelist_scal); + + glEnable(GL_BLEND); + // glDisable(GL_DEPTH_TEST); + + // CreateTexture (numtexturecols, lineartexture, 0.25, GL_MODULATE); + glCallList (clipplanelist_scal); + + + // glDepthFunc(GL_LEQUAL); + // glDepthMask(GL_TRUE); + // glCallList (clipplanelist_scal); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + */ + // end test + } + if (clipsolution == 2) + { + // glDisable(GL_DEPTH_TEST); + glCallList (clipplanelist_vec); + // glEnable(GL_DEPTH_TEST); + } + } + + + + if (draw_fieldlines) + { + SetClippingPlane(); + if (num_fieldlineslists <= 1) + glCallList (fieldlineslist); + else + { // animated + int start = int (time / 10 * num_fieldlineslists); + for (int ln = 0; ln < 10; ln++) + { + int nr = fieldlineslist + (start + ln) % num_fieldlineslists; + glCallList (nr); + } + } + glDisable(GL_CLIP_PLANE0); + } + + if(drawpointcurves) + { + glCallList(pointcurvelist); + } + + + glMatrixMode (GL_TEXTURE); + glLoadIdentity(); + glMatrixMode (GL_MODELVIEW); + + glDisable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + + glDisable (GL_POLYGON_OFFSET_FILL); + glDisable (GL_COLOR_MATERIAL); + + if (draw_isosurface) + glCallList (isosurface_list); + + + GLfloat matcol0[] = { 0, 0, 0, 1 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol0); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, matcol0); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matcol0); + + glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); + glLineWidth (1.0f); + glColor3f (0.0f, 0.0f, 0.0f); + glDisable (GL_LINE_SMOOTH); + + if (vispar.drawedges) + { + glCallList (element1dlist); + } + + if (vispar.drawoutline && !numisolines) + { + SetClippingPlane (); + glDepthMask(GL_FALSE); + glCallList (linelist); + glDepthMask(GL_TRUE); + + glDisable(GL_CLIP_PLANE0); + } + + if (numisolines) + { + SetClippingPlane (); + glCallList (isolinelist); + + glDisable(GL_CLIP_PLANE0); + glCallList (clipplane_isolinelist); + } + + glPopMatrix(); + + glDisable(GL_CLIP_PLANE0); + DrawColorBar (minval, maxval, logscale, lineartexture); + + if (vispar.drawcoordinatecross) + DrawCoordinateCross (); + DrawNetgenLogo (); + + glFinish(); + + + // delete lock; + // mem_lock.UnLock(); + } + + + + /* + void VisualSceneSolution :: RealVec3d (const double * values, Vec3d & v, + bool iscomplex, bool imag) + { + if (!iscomplex) + { + v.X() = values[0]; + v.Y() = values[1]; + v.Z() = values[2]; + } + else + { + if (!imag) + { + v.X() = values[0]; + v.Y() = values[2]; + v.Z() = values[4]; + } + else + { + v.X() = values[1]; + v.Y() = values[3]; + v.Z() = values[5]; + } + } + } + */ + Vec<3> VisualSceneSolution :: RealVec3d (const double * values, + bool iscomplex, bool imag) + { + Vec<3> v; + if (!iscomplex) + { + for (int j = 0; j < 3; j++) + v(j) = values[j]; + } + else + { + if (!imag) + { + for (int j = 0; j < 3; j++) + v(j) = values[2*j]; + } + else + { + for (int j = 0; j < 3; j++) + v(j) = values[2*j+1]; + } + } + return v; + } + + + void VisualSceneSolution :: RealVec3d (const double * values, Vec3d & v, + bool iscomplex, double phaser, double phasei) + { + if (!iscomplex) + { + v.X() = values[0]; + v.Y() = values[1]; + v.Z() = values[2]; + } + else + { + for (int i = 0; i < 3; i++) + v.X(i+1) = phaser * values[2*i] + phasei * values[2*i+1]; + } + } + + + + + void VisualSceneSolution :: BuildScene (int zoomall) + { + if (!mesh) + { + VisualScene::BuildScene (zoomall); + return; + } + + /* + if (!cone_list) + { + cone_list = glGenLists (1); + glNewList (cone_list, GL_COMPILE); + DrawCone (Point<3> (0,0,0), Point<3> (0,0,1), 0.4); + glEndList(); + } + */ + + // vispar.colormeshsize = 1; + + // recalc clipping plane + SetClippingPlane (); + glDisable(GL_CLIP_PLANE0); + + + SolData * sol = NULL; + SolData * vsol = NULL; + + if (scalfunction != -1) + sol = soldata[scalfunction]; + if (vecfunction != -1) + vsol = soldata[vecfunction]; + + if (mesh->GetTimeStamp () > solutiontimestamp) + { + sol = NULL; + vsol = NULL; + } + + + if (sol && sol->solclass) sol->solclass->SetMultiDimComponent (multidimcomponent); + if (vsol && vsol->solclass) vsol->solclass->SetMultiDimComponent (multidimcomponent); + + if (!autoscale || (!sol && !vsol) ) + { + minval = mminval; + maxval = mmaxval; + } + else + { + if (mesh->GetTimeStamp () > surfeltimestamp || + vispar.clipping.timestamp > clipplanetimestamp || + solutiontimestamp > surfeltimestamp) + { + GetMinMax (scalfunction, scalcomp, minval, maxval); + } + } + + if (mesh->GetTimeStamp() > surfeltimestamp || + solutiontimestamp > surfeltimestamp || + zoomall) + { + if (mesh->GetTimeStamp() > surfeltimestamp || zoomall) + { + // mesh has changed + + Point3d pmin, pmax; + static double oldrad = 0; + + mesh->GetBox (pmin, pmax, -1); + center = Center (pmin, pmax); + rad = 0.5 * Dist (pmin, pmax); + + glEnable (GL_NORMALIZE); + + if (rad > 1.5 * oldrad || + mesh->GetMajorTimeStamp() > surfeltimestamp || + zoomall) + { + CalcTransformationMatrices(); + oldrad = rad; + } + } + + DrawSurfaceElements(); + + surfeltimestamp = max2 (solutiontimestamp, mesh->GetTimeStamp()); + } + + if (mesh->GetTimeStamp() > surfellinetimestamp || + subdivision_timestamp > surfellinetimestamp || + (deform && solutiontimestamp > surfellinetimestamp) || + zoomall) + { + DrawSurfaceElementLines(); + surfellinetimestamp = max2 (solutiontimestamp, mesh->GetTimeStamp()); + } + + + if (vispar.drawedges) + Draw1DElements(); + + + + if (mesh->GetTimeStamp() > surface_vector_timestamp || + solutiontimestamp > surface_vector_timestamp || + zoomall) + { + if (surface_vector_list) + glDeleteLists (surface_vector_list, 1); + + surface_vector_list = glGenLists (1); + glNewList (surface_vector_list, GL_COMPILE); + + glEnable (GL_NORMALIZE); + DrawSurfaceVectors(); + + glEndList (); + + surface_vector_timestamp = + max2 (mesh->GetTimeStamp(), solutiontimestamp); + } + + + if (clipplanetimestamp < vispar.clipping.timestamp || + clipplanetimestamp < solutiontimestamp) + { + + // cout << "clipsolution = " << clipsolution << endl; + if (vispar.clipping.enable && clipsolution == 2) + { + // lock->UnLock(); + NgLock mlock (mesh->Mutex(), 0); + mlock.UnLock(); + mesh->BuildElementSearchTree(); + mlock.Lock(); + + // lock->Lock(); + } + + + if (vispar.clipping.enable && clipsolution == 1 && sol) + DrawClipPlaneTrigs (); + + if (clipplanelist_vec) + glDeleteLists (clipplanelist_vec, 1); + + clipplanelist_vec = glGenLists (1); + glNewList (clipplanelist_vec, GL_COMPILE); + + if (vispar.clipping.enable && clipsolution == 2 && vsol) + { + SetTextureMode (usetexture); + + if (autoscale) + GetMinMax (vecfunction, 0, minval, maxval); + + Array cpp; + GetClippingPlaneGrid (cpp); + + for (int i = 0; i < cpp.Size(); i++) + { + const ClipPlanePoint & p = cpp[i]; + double values[6]; + Vec3d v; + + bool drawelem = + GetValues (vsol, p.elnr, p.lami(0), p.lami(1), p.lami(2), values); + // RealVec3d (values, v, vsol->iscomplex, imag_part); + v = RealVec3d (values, vsol->iscomplex, imag_part); + + double val = v.Length(); + + if (drawelem && val > 1e-10 * maxval) + { + v *= (rad / val / gridsize * 0.5); + + SetOpenGlColor (val); + DrawCone (p.p, p.p+v, rad / gridsize * 0.2); + } + } + } + + glEndList (); + } + + + if (mesh->GetTimeStamp() > isosurface_timestamp || + solutiontimestamp > isosurface_timestamp || + zoomall) + { + if (isosurface_list) + glDeleteLists (isosurface_list, 1); + + isosurface_list = glGenLists (1); + glNewList (isosurface_list, GL_COMPILE); + + glEnable (GL_NORMALIZE); + DrawIsoSurface(sol, vsol, scalcomp); + + glEndList (); + + isosurface_timestamp = + max2 (mesh->GetTimeStamp(), solutiontimestamp); + } + + if(mesh->GetTimeStamp() > pointcurve_timestamp || + solutiontimestamp > pointcurve_timestamp) + { + if(pointcurvelist) + glDeleteLists(pointcurvelist,1); + + + if(mesh->GetNumPointCurves() > 0) + { + pointcurvelist = glGenLists(1); + glNewList(pointcurvelist,GL_COMPILE); + //glColor3f (1.0f, 0.f, 0.f); + + for(int i=0; iGetNumPointCurves(); i++) + { + Box3d box; + box.SetPoint(mesh->GetPointCurvePoint(i,0)); + for(int j=1; jGetNumPointsOfPointCurve(i); j++) + box.AddPoint(mesh->GetPointCurvePoint(i,j)); + double diam = box.CalcDiam(); + + double thick = min2(0.1*diam, 0.001*rad); + + double red,green,blue; + mesh->GetPointCurveColor(i,red,green,blue); + glColor3f (red, green, blue); + for(int j=0; jGetNumPointsOfPointCurve(i)-1; j++) + { + DrawCylinder(mesh->GetPointCurvePoint(i,j), + mesh->GetPointCurvePoint(i,j+1), + thick); + } + } + glEndList(); + } + + } + + + if ( + numisolines && + (clipplanetimestamp < vispar.clipping.timestamp || + clipplanetimestamp < solutiontimestamp) + ) + { + if (isolinelist) glDeleteLists (isolinelist, 1); + + isolinelist = glGenLists (1); + glNewList (isolinelist, GL_COMPILE); + + Point<3> points[1100]; + double values[1100]; + + int nse = mesh->GetNSE(); + + CurvedElements & curv = mesh->GetCurvedElements(); + + if (sol) + { + glBegin (GL_LINES); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + + bool curved = curv.IsHighOrder(); // && curv.IsSurfaceElementCurved(sei); + + if (el.GetType() == TRIG || el.GetType() == TRIG6) + { + Point<3> lp1, lp2, lp3; + if (!curved) + { + GetPointDeformation (el[0]-1, lp1); + GetPointDeformation (el[1]-1, lp2); + GetPointDeformation (el[2]-1, lp3); + } + + int n = 1 << subdivisions; + int ii = 0; + int ix, iy; + for (iy = 0; iy <= n; iy++) + for (ix = 0; ix <= n-iy; ix++) + { + double x = double(ix) / n; + double y = double(iy) / n; + + // TODO: consider return value (bool: draw/don't draw element) + GetSurfValue (sol, sei, -1, x, y, scalcomp, values[ii]); + Point<2> xref(x,y); + + if (curved) + mesh->GetCurvedElements(). + CalcSurfaceTransformation (xref, sei, points[ii]); + else + points[ii] = lp3 + x * (lp1-lp3) + y * (lp2-lp3); + + if (deform) + { + points[ii] += GetSurfDeformation (sei, -1, x, y); + } + ii++; + } + + ii = 0; + for (iy = 0; iy < n; iy++, ii++) + for (ix = 0; ix < n-iy; ix++, ii++) + { + int index[] = { ii, ii+1, ii+n-iy+1, + ii+1, ii+n-iy+2, ii+n-iy+1 }; + + DrawIsoLines (points[index[0]], points[index[1]], points[index[2]], + values[index[0]], values[index[1]], values[index[2]]); + + if (ix < n-iy-1) + DrawIsoLines (points[index[3]], points[index[4]], points[index[5]], + values[index[3]], values[index[4]], values[index[5]]); + } + } + + + if (el.GetType() == QUAD || el.GetType() == QUAD6 || el.GetType() == QUAD8 ) + { + Point<3> lpi[4]; + Vec<3> vx = 0.0, vy = 0.0, vtwist = 0.0, def; + if (!curved) + { + for (int j = 0; j < 4; j++) + GetPointDeformation (el[j]-1, lpi[j]); + vx = lpi[1]-lpi[0]; + vy = lpi[3]-lpi[0]; + vtwist = (lpi[0]-lpi[1]) + (lpi[2]-lpi[3]); + } + + int n = 1 << subdivisions; + int ix, iy, ii = 0; + for (iy = 0; iy <= n; iy++) + for (ix = 0; ix <= n; ix++, ii++) + { + double x = double(ix) / n; + double y = double(iy) / n; + + // TODO: consider return value (bool: draw/don't draw element) + GetSurfValue (sol, sei, -1, x, y, scalcomp, values[ii]); + Point<2> xref(x,y); + + if (curved) + mesh->GetCurvedElements(). + CalcSurfaceTransformation (xref, sei, points[ii]); + else + points[ii] = lpi[0] + x * vx + y * vy + x*y * vtwist; + + if (deform) + points[ii] += GetSurfDeformation (sei, -1, x, y); + } + + ii = 0; + for (iy = 0; iy < n; iy++, ii++) + for (ix = 0; ix < n; ix++, ii++) + { + DrawIsoLines (points[ii], points[ii+1], points[ii+n+1], + values[ii], values[ii+1], values[ii+n+1]); + DrawIsoLines (points[ii+1], points[ii+n+2], points[ii+n+1], + values[ii+1], values[ii+n+2], values[ii+n+1]); + } + } + } + glEnd(); + } + glEndList (); + + if (clipplane_isolinelist) glDeleteLists (clipplane_isolinelist, 1); + + if (vispar.clipping.enable && clipsolution == 1 && sol) + { + clipplane_isolinelist = glGenLists (1); + glNewList (clipplane_isolinelist, GL_COMPILE); + + Array cpt; + Array pts; + GetClippingPlaneTrigs (cpt, pts); + bool drawelem; + + glNormal3d (-clipplane[0], -clipplane[1], -clipplane[2]); + + if (numisolines) + for (int i = 0; i < cpt.Size(); i++) + { + const ClipPlaneTrig & trig = cpt[i]; + double vali[3]; + for (int j = 0; j < 3; j++) + { + Point<3> lami = pts[trig.points[j].pnr].lami; + drawelem = GetValue (sol, trig.elnr, lami(0), lami(1), lami(2), + scalcomp, vali[j]); + } + if ( drawelem ) + DrawIsoLines (pts[trig.points[0].pnr].p, + pts[trig.points[1].pnr].p, + pts[trig.points[2].pnr].p, + // trig.points[1].p, + // trig.points[2].p, + vali[0], vali[1], vali[2]); + } + glEndList (); + } + glEnd(); + } + + clipplanetimestamp = max2 (vispar.clipping.timestamp, solutiontimestamp); + } + + void VisualSceneSolution :: Draw1DElements () + { + if (element1dlist) + glDeleteLists (element1dlist, 1); + + element1dlist = glGenLists (1); + glNewList (element1dlist, GL_COMPILE); + + int npt = (1 << subdivisions) + 1; + Array pref(npt), values(npt); + Array > points(npt); + + const SolData * sol = NULL; + if (scalfunction != -1) sol = soldata[scalfunction]; + + int ncomp = 0; + if (sol) ncomp = sol->components; + Array mvalues(ncomp); + + + for (int i = 0; i < npt; i++) + pref[i] = double(i) / (npt-1); + + for (SegmentIndex i = 0; i < mesh -> GetNSeg(); i++) + { + // mesh->GetCurvedElements(). + // CalcMultiPointSegmentTransformation (&pref, i, &points, NULL); + // const Segment & seg = mesh -> LineSegment(i); + for (int j = 0; j < npt; j++) + mesh->GetCurvedElements(). + CalcSegmentTransformation (pref[j], i, points[j]); + if (sol) + { + for (int j = 0; j < npt; j++) + { + sol->solclass->GetSegmentValue (i, pref[j], &mvalues[0]); + values[j] = ExtractValue (sol, scalcomp, &mvalues[0]); + points[j](1) += scaledeform * values[j]; + } + } + + glBegin (GL_LINE_STRIP); + for (int i = 0; i < npt; i++) + glVertex3dv (points[i]); + glEnd(); + } + + glEndList (); + } + + void VisualSceneSolution :: DrawSurfaceElements () + { + static int timer = NgProfiler::CreateTimer ("Solution::DrawSurfaceElements"); + NgProfiler::RegionTimer reg (timer); + + +#ifdef PARALLELGL + + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + + par_surfellists.SetSize (ntasks); + + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("solsurfellist"); + + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (par_surfellists[dest], dest, MPI_TAG_VIS); + + if (surfellist) + glDeleteLists (surfellist, 1); + + surfellist = glGenLists (1); + glNewList (surfellist, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (par_surfellists[dest]); + + glEndList(); + return; + } +#endif + + + + if (surfellist) + glDeleteLists (surfellist, 1); + + surfellist = glGenLists (1); + glNewList (surfellist, GL_COMPILE); + + + const SolData * sol = NULL; + + if (scalfunction != -1) + sol = soldata[scalfunction]; + + if (mesh->GetTimeStamp () > solutiontimestamp) + sol = NULL; + + if (sol && sol->solclass) sol->solclass->SetMultiDimComponent (multidimcomponent); + + + + glLineWidth (1.0f); + + GLfloat col_grey[] = { 0.6f, 0.6f, 0.6f, 1.0f }; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col_grey); + + + int nse = mesh->GetNSE(); + + SetTextureMode (usetexture); + + CurvedElements & curv = mesh->GetCurvedElements(); + + int n = 1 << subdivisions; + int npt = sqr(n+1); + + Array > pref (npt); + Array > points (npt); + Array > dxdxis (npt); + Array > nvs(npt); + Array values(npt); + + Array mvalues(npt); + if (sol && sol->draw_surface) mvalues.SetSize (npt * sol->components); + + Array > valuesc(npt); + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + + if (vispar.drawdomainsurf > 0) + { + if (mesh->GetDimension() == 3) + { + if (vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainIn() && + vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainOut()) + continue; + } + else + { + if (el.GetIndex() != vispar.drawdomainsurf) continue; + } + } + + + + if ( el.GetType() == QUAD || el.GetType() == QUAD6 ) + { + bool curved = curv.IsSurfaceElementCurved (sei); + + + for (int iy = 0, ii = 0; iy <= n; iy++) + for (int ix = 0; ix <= n; ix++, ii++) + pref[ii] = Point<2> (double(ix)/n, double(iy)/n); + + int npt = (n+1)*(n+1); + if (curved) + { + for (int ii = 0; ii < npt; ii++) + { + Point<2> xref = pref[ii]; + + mesh->GetCurvedElements(). + CalcSurfaceTransformation (xref, sei, points[ii], dxdxis[ii]); + nvs[ii] = Cross (dxdxis[ii].Col(0), dxdxis[ii].Col(1)); + nvs[ii].Normalize(); + } + } + else + { + Point<3> lpi[4]; + Vec<3> vx, vy, vtwist; + + for (int k = 0; k < 4; k++) + GetPointDeformation (el[k]-1, lpi[k]); + + vx = lpi[1]-lpi[0]; + vy = lpi[3]-lpi[0]; + vtwist = (lpi[0]-lpi[1]) + (lpi[2]-lpi[3]); + + for (int ii = 0; ii < npt; ii++) + { + double x = pref[ii](0); + double y = pref[ii](1); + points[ii] = lpi[0] + x * vx + y * vy + x*y * vtwist; + for (int j = 0; j < 3; j++) + { + dxdxis[ii](j,0) = vx(j) + y*vtwist(j); + dxdxis[ii](j,1) = vy(j) + x*vtwist(j); + } + } + + Vec<3> nv = Cross (vx, vy); + nv.Normalize(); + for (int ii = 0; ii < npt; ii++) + nvs[ii] = nv; + } + + + bool drawelem = false; + /* + if (sol && sol->draw_surface) + { + if (usetexture == 2) + for (int ii = 0; ii < npt; ii++) + drawelem = GetSurfValueComplex (sol, sei, -1, pref[ii](0), pref[ii](1), scalcomp, valuesc[ii]); + else + for (int ii = 0; ii < npt; ii++) + drawelem = GetSurfValue (sol, sei, -1, pref[ii](0), pref[ii](1), scalcomp, values[ii]); + } + */ + if (sol && sol->draw_surface) + { + drawelem = GetMultiSurfValues (sol, sei, -1, npt, + &pref[0](0), &pref[1](0)-&pref[0](0), + &points[0](0), &points[1](0)-&points[0](0), + &dxdxis[0](0), &dxdxis[1](0)-&dxdxis[0](0), + &mvalues[0], sol->components); + if (usetexture == 2) + for (int ii = 0; ii < npt; ii++) + valuesc[ii] = ExtractValueComplex(sol, scalcomp, &mvalues[ii*sol->components]); + else + for (int ii = 0; ii < npt; ii++) + values[ii] = ExtractValue(sol, scalcomp, &mvalues[ii*sol->components]); + } + + + if (deform) + for (int ii = 0; ii < npt; ii++) + points[ii] += GetSurfDeformation (sei, -1, pref[ii](0), pref[ii](1)); + + + int save_usetexture = usetexture; + if (!drawelem) + { + usetexture = 0; + SetTextureMode (0); + } + + int ii = 0; + + glBegin (GL_QUADS); + + for (int iy = 0; iy < n; iy++, ii++) + for (int ix = 0; ix < n; ix++, ii++) + { + int index[] = { ii, ii+1, ii+n+2, ii+n+1 }; + + for (int j = 0; j < 4; j++) + { + if (drawelem) + { + if (usetexture != 2) + SetOpenGlColor (values[index[j]]); + else + glTexCoord2f ( valuesc[index[j]].real(), + valuesc[index[j]].imag() ); + } + else + glColor4fv (col_grey); + + glNormal3dv (nvs[index[j]]); + glVertex3dv (points[index[j]]); + } + } + glEnd(); + + if (!drawelem && (usetexture != save_usetexture)) + { + usetexture = save_usetexture; + SetTextureMode (usetexture); + } + + } + } + + n = 1 << subdivisions; + double invn = 1.0 / n; + npt = (n+1)*(n+2)/2; + + for(SurfaceElementIndex sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + // if (el.GetIndex() <= 1) continue; + + if(vispar.drawdomainsurf > 0) + { + if (mesh->GetDimension() == 3) + { + if (vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainIn() && + vispar.drawdomainsurf != mesh->GetFaceDescriptor(el.GetIndex()).DomainOut()) + continue; + } + else + { + if (el.GetIndex() != vispar.drawdomainsurf) + continue; + } + } + + if ( el.GetType() == TRIG || el.GetType() == TRIG6 ) + { + bool curved = curv.IsSurfaceElementCurved(sei); + + for (int iy = 0, ii = 0; iy <= n; iy++) + for (int ix = 0; ix <= n-iy; ix++, ii++) + pref[ii] = Point<2> (ix*invn, iy*invn); + + if (curved) + { + mesh->GetCurvedElements(). + CalcMultiPointSurfaceTransformation (&pref, sei, &points, &dxdxis); + + for (int ii = 0; ii < npt; ii++) + nvs[ii] = Cross (dxdxis[ii].Col(0), dxdxis[ii].Col(1)).Normalize(); + } + else + { + Point<3> p1 = mesh->Point (el[0]); + Point<3> p2 = mesh->Point (el[1]); + Point<3> p3 = mesh->Point (el[2]); + + Vec<3> vx = p1-p3; + Vec<3> vy = p2-p3; + for (int ii = 0; ii < npt; ii++) + { + points[ii] = p3 + pref[ii](0) * vx + pref[ii](1) * vy; + for (int j = 0; j < 3; j++) + { + dxdxis[ii](j,0) = vx(j); + dxdxis[ii](j,1) = vy(j); + } + } + + Vec<3> nv = Cross (vx, vy).Normalize(); + for (int ii = 0; ii < npt; ii++) + nvs[ii] = nv; + } + + bool drawelem = false; + if (sol && sol->draw_surface) + { + drawelem = GetMultiSurfValues (sol, sei, -1, npt, + &pref[0](0), &pref[1](0)-&pref[0](0), + &points[0](0), &points[1](0)-&points[0](0), + &dxdxis[0](0), &dxdxis[1](0)-&dxdxis[0](0), + &mvalues[0], sol->components); + if (usetexture == 2) + for (int ii = 0; ii < npt; ii++) + valuesc[ii] = ExtractValueComplex(sol, scalcomp, &mvalues[ii*sol->components]); + else + for (int ii = 0; ii < npt; ii++) + values[ii] = ExtractValue(sol, scalcomp, &mvalues[ii*sol->components]); + } + + if (deform) + for (int ii = 0; ii < npt; ii++) + points[ii] += GetSurfDeformation (sei, -1, pref[ii](0), pref[ii](1)); + + int save_usetexture = usetexture; + if (!drawelem) + { + usetexture = 0; + SetTextureMode (usetexture); + } + + for (int iy = 0, ii = 0; iy < n; iy++) + { + glBegin (GL_TRIANGLE_STRIP); + for (int ix = 0; ix <= n-iy; ix++, ii++) + for (int k = 0; k < 2; k++) + { + if (ix+iy+k > n) continue; + int hi = (k == 0) ? ii : ii+n-iy+1; + + if (drawelem) + { + if (usetexture != 2) + SetOpenGlColor (values[hi]); + else + glTexCoord2f ( valuesc[hi].real(), valuesc[hi].imag() ); + } + else + glColor4fv (col_grey); + + glNormal3dv (nvs[hi]); + glVertex3dv (points[hi]); + } + glEnd(); + } + + + /* + + GLuint vboId[3]; + glGenBuffersARB (3, &vboId[0]); +// cout << "vboId = " << vboId << endl; + + glBindBufferARB (GL_ARRAY_BUFFER_ARB, vboId[0]); + glBufferDataARB (GL_ARRAY_BUFFER_ARB, points.Size()*sizeof(Point<3>), + &points[0][0], GL_STATIC_DRAW_ARB); + + + // not so fast as old-fashened style + glEnableClientState(GL_VERTEX_ARRAY); + // glVertexPointer(3, GL_DOUBLE, 0, &points[0][0]); + glVertexPointer(3, GL_DOUBLE, 0, 0); //ARB + + glBindBufferARB (GL_ARRAY_BUFFER_ARB, vboId[1]); + glBufferDataARB (GL_ARRAY_BUFFER_ARB, nvs.Size()*sizeof(Point<3>), + &nvs[0][0], GL_STATIC_DRAW_ARB); + + glEnableClientState(GL_NORMAL_ARRAY); + // glNormalPointer(GL_DOUBLE, 0, &nvs[0][0]); + glNormalPointer(GL_DOUBLE, 0, 0); // ARB + + // if (drawelem && usetexture == 1) + { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + // glTexCoordPointer(1, GL_DOUBLE, 0, &values[0]); + + glBindBufferARB (GL_ARRAY_BUFFER_ARB, vboId[2]); + glBufferDataARB (GL_ARRAY_BUFFER_ARB, values.Size()*sizeof(double), + &values[0], GL_STATIC_DRAW_ARB); + glTexCoordPointer(1, GL_DOUBLE, 0, 0); + } + + Array gind; + + for (int iy = 0, ii = 0; iy < n; iy++,ii++) + { + for (int ix = 0; ix < n-iy; ix++, ii++) + { + int nv = (ix+iy+1 < n) ? 6 : 3; + + int ind[] = { ii, ii+1, ii+n-iy+1, + ii+n-iy+1, ii+1, ii+n-iy+2 }; + +// if (ix == 0 && iy == 0) +// for (int l = 0; l < 3; l++) +// { +// if (drawelem) +// { +// if (usetexture != 2) +// // SetOpenGlColor (values[ind[l]]); +// glTexCoord1f ( values[ind[l]] ); +// else +// glTexCoord2f ( valuesc[ind[l]].real(), valuesc[ind[l]].imag() ); +// } +// else +// glColor3fv (col_grey); +// } + + for (int j = 0; j < nv; j++) + gind.Append(ind[j]); + // glDrawElements(GL_TRIANGLES, nv, GL_UNSIGNED_INT, &ind[0]); + } + } + glDrawElements(GL_TRIANGLES, gind.Size(), GL_UNSIGNED_INT, &gind[0]); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glDeleteBuffersARB (3, &vboId[0]); + */ + + + if (!drawelem && (usetexture != save_usetexture)) + { + usetexture = save_usetexture; + SetTextureMode (usetexture); + } + } + } + glEndList (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (surfellist, 0, MPI_TAG_VIS); +#endif + } + + + void VisualSceneSolution :: DrawSurfaceElementLines () + { +#ifdef PARALLELGL + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + + par_surfellists.SetSize (ntasks); + + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("solsurfellinelist"); + + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (par_surfellists[dest], dest, MPI_TAG_VIS); + + if (linelist) + glDeleteLists (linelist, 1); + + linelist = glGenLists (1); + glNewList (linelist, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (par_surfellists[dest]); + + glEndList(); + return; + } +#endif + + if (linelist) + glDeleteLists (linelist, 1); + + linelist = glGenLists (1); + glNewList (linelist, GL_COMPILE); + + glLineWidth (1.0f); + + int nse = mesh->GetNSE(); + CurvedElements & curv = mesh->GetCurvedElements(); + + int n = 1 << subdivisions; + ArrayMem, 65> ptsloc(n+1); + ArrayMem, 65> ptsglob(n+1); + + double trigpts[3][2] = { { 0, 0 }, { 0, 1 }, { 1, 0} }; + double trigvecs[3][2] = { { 1, 0 }, { 0, -1 }, { -1, 1} }; + + double quadpts[4][2] = { { 0, 0 }, { 1, 1 }, { 0, 1}, { 1, 0 } }; + double quadvecs[4][2] = { { 1, 0 }, { -1, 0}, { 0, -1}, { 0, 1 } }; + + for (SurfaceElementIndex sei = 0; sei < nse; sei++) + { + Element2d & el = (*mesh)[sei]; + + int nv = (el.GetType() == TRIG || el.GetType() == TRIG6) ? 3 : 4; + for (int k = 0; k < nv; k++) + { + Point<2> p0; + Vec<2> vtau; + if (nv == 3) + { + p0 = Point<2>(trigpts[k][0], trigpts[k][1]); + vtau = Vec<2>(trigvecs[k][0], trigvecs[k][1]); + } + else + { + p0 = Point<2>(quadpts[k][0], quadpts[k][1]); + vtau = Vec<2>(quadvecs[k][0], quadvecs[k][1]); + } + + glBegin (GL_LINE_STRIP); + + for (int ix = 0; ix <= n; ix++) + ptsloc[ix] = p0 + (double(ix) / n) * vtau; + + curv.CalcMultiPointSurfaceTransformation (&ptsloc, sei, &ptsglob, 0); + + for (int ix = 0; ix <= n; ix++) + { + if (deform) + ptsglob[ix] += GetSurfDeformation (sei, k, ptsloc[ix](0), ptsloc[ix](1)); + glVertex3dv (ptsglob[ix]); + } + + glEnd (); + } + } + glEndList (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (linelist, 0, MPI_TAG_VIS); +#endif + } + + + + + + + + + + void VisualSceneSolution :: DrawIsoSurface(const SolData * sol, + const SolData * vsol, + int comp) + { + if (!draw_isosurface) return; + if (!sol) return; + + + SetTextureMode (0); + glColor3d (1.0, 0, 0); + glEnable (GL_COLOR_MATERIAL); + + + glBegin (GL_TRIANGLES); + + int ne = mesh->GetNE(); + + const int edgei[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + double edgelam[6]; + Point<3> edgep[6]; + Vec<3> normp[6]; + double nodevali[4]; + + int cntce; + int cpe1 = 0, cpe2 = 0, cpe3 = 0; + + int n = 1 << subdivisions; + int n3 = (n+1)*(n+1)*(n+1); + + Array > grid(n3); + Array > locgrid(n3); + Array > trans(n3); + Array val(n3); + Array > grads(n3); + Array compress(n3); + + MatrixFixWidth<3> pointmat(8); + grads = Vec<3> (0.0); + + for (ElementIndex ei = 0; ei < ne; ei++) + { + // if(vispar.clipdomain > 0 && vispar.clipdomain != (*mesh)[ei].GetIndex()) continue; + // if(vispar.donotclipdomain > 0 && vispar.donotclipdomain == (*mesh)[ei].GetIndex()) continue; + + ELEMENT_TYPE type = (*mesh)[ei].GetType(); + if (type == HEX || type == PRISM || type == TET || type == PYRAMID) + { + const Element & el = (*mesh)[ei]; + + int ii = 0; + int cnt_valid = 0; + + for (int ix = 0; ix <= n; ix++) + for (int iy = 0; iy <= n; iy++) + for (int iz = 0; iz <= n; iz++, ii++) + { + Point<3> ploc; + compress[ii] = ii; + + switch (type) + { + case PRISM: + if (ix+iy <= n) + { + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + compress[ii] = cnt_valid; + cnt_valid++; + } + else + compress[ii] = -1; + break; + case TET: + if (ix+iy+iz <= n) + { + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + compress[ii] = cnt_valid; + cnt_valid++; + } + else + compress[ii] = -1; + break; + case HEX: + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + break; + case PYRAMID: + ploc = Point<3> (double(ix) / n * (1-double(iz)/n), + double(iy) / n * (1-double(iz)/n), + double(iz)/n); + break; + default: + cerr << "case not implementd 878234" << endl; + ploc = 0.0; + } + if (compress[ii] != -1) + locgrid[compress[ii]] = ploc; + } + + if (type != TET && type != PRISM) cnt_valid = n3; + + + if (mesh->GetCurvedElements().IsHighOrder() || 1) + { + mesh->GetCurvedElements(). + CalcMultiPointElementTransformation (&locgrid, ei, &grid, &trans); + } + else + { + Vector shape(el.GetNP()); + for (int k = 0; k < el.GetNP(); k++) + for (int j = 0; j < 3; j++) + pointmat(k,j) = (*mesh)[el[k]](j); + + for (int i = 0; i < cnt_valid; i++) + { + el.GetShapeNew (locgrid[i], shape); + Point<3> pglob; + for (int j = 0; j < 3; j++) + { + pglob(j) = 0; + for (int k = 0; k < el.GetNP(); k++) + pglob(j) += shape(k) * pointmat(k,j); + } + grid[i] = pglob; + } + } + + bool has_pos = 0, has_neg = 0; + + for (int i = 0; i < cnt_valid; i++) + { + GetValue (sol, ei, &locgrid[i](0), &grid[i](0), &trans[i](0), comp, val[i]); + + val[i] -= minval; + + if (vsol) + GetValues (vsol, ei, &locgrid[i](0), &grid[i](0), &trans[i](0), &grads[i](0)); + grads[i] *= -1; + + + if (val[i] > 0) + has_pos = 1; + else + has_neg = 1; + } + + if (!has_pos || !has_neg) continue; + + for (int ix = 0; ix < n; ix++) + for (int iy = 0; iy < n; iy++) + for (int iz = 0; iz < n; iz++) + { + int base = iz + (n+1)*iy + (n+1)*(n+1)*ix; + int pi[8] = + { base, base+(n+1)*(n+1), base+(n+1)*(n+1)+(n+1), base+(n+1), + base+1, base+(n+1)*(n+1)+1, base+(n+1)*(n+1)+(n+1)+1, base+(n+1)+1 }; + + for (int j = 0; j < 8; j++) + pi[j] = compress[pi[j]]; + + int tets[6][4] = + { { 1, 2, 4, 5 }, + { 4, 5, 2, 8 }, + { 2, 8, 5, 6 }, + { 2, 3, 4, 8 }, + { 2, 3, 8, 6 }, + { 3, 8, 6, 7 } }; + + for (int ii = 0; ii < 6; ii++) + { + int teti[4]; + for (int k = 0; k < 4; k++) + teti[k] = pi[tets[ii][k]-1]; + + bool is_valid = 1; + for (int j = 0; j < 4; j++) + if (teti[j] == -1) is_valid = 0; + + if (!is_valid) continue; + + for (int j = 0; j < 4; j++) + nodevali[j] = val[teti[j]]; + + cntce = 0; + for (int j = 0; j < 6; j++) + { + int lpi1 = edgei[j][0]; + int lpi2 = edgei[j][1]; + if ( (nodevali[lpi1] > 0) != + (nodevali[lpi2] > 0) ) + { + Point<3> p1 = grid[teti[lpi1]]; + Point<3> p2 = grid[teti[lpi2]]; + + edgelam[j] = nodevali[lpi2] / (nodevali[lpi2] - nodevali[lpi1]); + edgep[j] = grid[teti[lpi1]] + (1-edgelam[j]) * (grid[teti[lpi2]]-grid[teti[lpi1]]); + normp[j] = grads[teti[lpi1]] + (1-edgelam[j]) * (grads[teti[lpi2]]-grads[teti[lpi1]]); + + cntce++; + cpe3 = cpe2; + cpe2 = cpe1; + cpe1 = j; + if (cntce >= 3) + { + if (!vsol) + { + Point<3> points[3]; + + points[0] = edgep[cpe1]; + points[1] = edgep[cpe2]; + points[2] = edgep[cpe3]; + + Vec<3> normal = Cross (points[2]-points[0], points[1]-points[0]); + if ( ( (normal * (p2-p1)) > 0 ) == ( nodevali[lpi1] < 0) ) + normal *= -1; + glNormal3dv (normal); + + glVertex3dv (points[0]); + glVertex3dv (points[1]); + glVertex3dv (points[2]); + } + else + { + glNormal3dv (normp[cpe1]); + glVertex3dv (edgep[cpe1]); + glNormal3dv (normp[cpe2]); + glVertex3dv (edgep[cpe2]); + glNormal3dv (normp[cpe3]); + glVertex3dv (edgep[cpe3]); + } + } + } + } + } + } + } + } + glEnd(); + } + + + + + + + + + void VisualSceneSolution :: DrawTrigSurfaceVectors(const Array< Point<3> > & lp, + const Point<3> & pmin, const Point<3> & pmax, + const int sei, const SolData * vsol) + { + int dir,dir1,dir2; + double s,t; + + Vec<3> n = Cross (lp[1]-lp[0], lp[2]-lp[0]); + Vec<3> na (fabs (n(0)), fabs(n(1)), fabs(n(2))); + if (na(0) > na(1) && na(0) > na(2)) + dir = 1; + else if (na(1) > na(2)) + dir = 2; + else + dir = 3; + + dir1 = (dir % 3) + 1; + dir2 = (dir1 % 3) + 1; + + Point<2> p2d[3]; + + int k; + + for (k = 0; k < 3; k++) + { + p2d[k] = Point<2> ((lp[k](dir1-1) - pmin(dir1-1)) / (2*rad), + (lp[k](dir2-1) - pmin(dir2-1)) / (2*rad)); + } + + + double minx2d, maxx2d, miny2d, maxy2d; + minx2d = maxx2d = p2d[0](0); + miny2d = maxy2d = p2d[0](1); + for (k = 1; k < 3; k++) + { + minx2d = min2 (minx2d, p2d[k](0)); + maxx2d = max2 (maxx2d, p2d[k](0)); + miny2d = min2 (miny2d, p2d[k](1)); + maxy2d = max2 (maxy2d, p2d[k](1)); + } + + double mat11 = p2d[1](0) - p2d[0](0); + double mat21 = p2d[1](1) - p2d[0](1); + double mat12 = p2d[2](0) - p2d[0](0); + double mat22 = p2d[2](1) - p2d[0](1); + + double det = mat11*mat22-mat21*mat12; + double inv11 = mat22/det; + double inv21 = -mat21/det; + double inv12 = -mat12/det; + double inv22 = mat11/det; + + // cout << "drawsurfacevectors. xoffset = " << xoffset << ", yoffset = "; + // cout << yoffset << endl; + + for (s = xoffset/gridsize; s <= 1+xoffset/gridsize; s += 1.0 / gridsize) + if (s >= minx2d && s <= maxx2d) + for (t = yoffset/gridsize; t <= 1+yoffset/gridsize; t += 1.0 / gridsize) + if (t >= miny2d && t <= maxy2d) + { + double lam1 = inv11 * (s - p2d[0](0)) + inv12 * (t-p2d[0](1)); + double lam2 = inv21 * (s - p2d[0](0)) + inv22 * (t-p2d[0](1)); + + if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1) + { + Point<3> cp; + for (k = 0; k < 3; k++) + cp(k) = lp[0](k) + + lam1 * (lp[1](k)-lp[0](k)) + + lam2 * (lp[2](k)-lp[0](k)); + + Vec<3> v; + double values[6]; + bool drawelem = + GetSurfValues (vsol, sei, -1, lam1, lam2, values); + + if (!vsol->iscomplex) + for (k = 0; k < 3; k++) + v(k) = values[k]; + else + { + if (!imag_part) + for (k = 0; k < 3; k++) + v(k) = values[2*k]; + else + for (k = 0; k < 3; k++) + v(k) = values[2*k+1]; + } + + if (mesh->GetDimension() == 2) + if ( (!vsol->iscomplex && vsol->components != 3) || + (vsol->iscomplex && vsol->components != 6) ) + v(2) = 0; + + double val = v.Length(); + + SetOpenGlColor (val); // (val, minval, maxval, logscale); // change JS + + if (val > 1e-10 * maxval) + v *= (rad / val / gridsize * 0.5); + else + drawelem = 0; + + if ( drawelem ) + DrawCone (cp, cp+4*v, 0.8*rad / gridsize); + } + } + + } + + + + void VisualSceneSolution :: DrawSurfaceVectors () + { + SurfaceElementIndex sei; + + const SolData * vsol = NULL; + // bool drawelem; + + if (vecfunction != -1) + vsol = soldata[vecfunction]; + + if (mesh->GetTimeStamp () > solutiontimestamp) + vsol = NULL; + + if (!vsol) return; + + + Point<3> pmin = center - Vec3d (rad, rad, rad); + Point<3> pmax = center - Vec3d (rad, rad, rad); + + + // glColor3d (1.0, 1.0, 1.0); + // glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + + if (vsol->draw_surface && showsurfacesolution) + { + int nse = mesh->GetNSE(); + for (sei = 0; sei < nse; sei++) + { + const Element2d & el = (*mesh)[sei]; + + if (el.GetType() == TRIG || el.GetType() == TRIG6) + { + + Array< Point<3> > lp(3); + + lp[0] = mesh->Point(el[2]); + lp[1] = mesh->Point(el[0]); + lp[2] = mesh->Point(el[1]); + + DrawTrigSurfaceVectors(lp,pmin,pmax,sei,vsol); + + /* + Vec<3> n = Cross (lp[1]-lp[0], lp[2]-lp[0]); + Vec<3> na (fabs (n(0)), fabs(n(1)), fabs(n(2))); + if (na(0) > na(1) && na(0) > na(2)) + dir = 1; + else if (na(1) > na(2)) + dir = 2; + else + dir = 3; + + dir1 = (dir % 3) + 1; + dir2 = (dir1 % 3) + 1; + + for (k = 0; k < 3; k++) + { + p2d[k] = Point<2> ((lp[k](dir1-1) - pmin(dir1-1)) / (2*rad), + (lp[k](dir2-1) - pmin(dir2-1)) / (2*rad)); + } + + double minx2d, maxx2d, miny2d, maxy2d; + minx2d = maxx2d = p2d[0](0); + miny2d = maxy2d = p2d[0](1); + for (k = 1; k < 3; k++) + { + minx2d = min2 (minx2d, p2d[k](0)); + maxx2d = max2 (maxx2d, p2d[k](0)); + miny2d = min2 (miny2d, p2d[k](1)); + maxy2d = max2 (maxy2d, p2d[k](1)); + } + + double mat11 = p2d[1](0) - p2d[0](0); + double mat21 = p2d[1](1) - p2d[0](1); + double mat12 = p2d[2](0) - p2d[0](0); + double mat22 = p2d[2](1) - p2d[0](1); + + double det = mat11*mat22-mat21*mat12; + double inv11 = mat22/det; + double inv21 = -mat21/det; + double inv12 = -mat12/det; + double inv22 = mat11/det; + + // cout << "drawsurfacevectors. xoffset = " << xoffset << ", yoffset = "; + // cout << yoffset << endl; + + for (s = xoffset/gridsize; s <= 1+xoffset/gridsize; s += 1.0 / gridsize) + if (s >= minx2d && s <= maxx2d) + for (t = yoffset/gridsize; t <= 1+yoffset/gridsize; t += 1.0 / gridsize) + if (t >= miny2d && t <= maxy2d) + { + double lam1 = inv11 * (s - p2d[0](0)) + inv12 * (t-p2d[0](1)); + double lam2 = inv21 * (s - p2d[0](0)) + inv22 * (t-p2d[0](1)); + + if (lam1 >= 0 && lam2 >= 0 && lam1+lam2 <= 1) + { + Point<3> cp; + for (k = 0; k < 3; k++) + cp(k) = lp[0](k) + + lam1 * (lp[1](k)-lp[0](k)) + + lam2 * (lp[2](k)-lp[0](k)); + + Vec<3> v; + double values[6]; + drawelem = GetSurfValues (vsol, sei, lam1, lam2, values); + + if (!vsol->iscomplex) + for (k = 0; k < 3; k++) + v(k) = values[k]; + else + { + if (!imag_part) + for (k = 0; k < 3; k++) + v(k) = values[2*k]; + else + for (k = 0; k < 3; k++) + v(k) = values[2*k+1]; + } + + if (mesh->GetDimension() == 2) + if ( (!vsol->iscomplex && vsol->components != 3) || + (vsol->iscomplex && vsol->components != 6) ) + v(2) = 0; + + double val = v.Length(); + SetOpenGlColor (val, minval, maxval, logscale); + + if (val > 1e-10 * maxval) + v *= (rad / val / gridsize * 0.5); + else drawelem = 0; + // "drawelem": added 07.04.2004 (FB) + if ( drawelem ) DrawCone (cp, cp+4*v, 0.8*rad / gridsize); + + + } + } + */ + } + else if (el.GetType() == QUAD) + { + /* + Array < Point<3> > lp(3); + + lp[0] = mesh->Point(el[0]); + lp[1] = mesh->Point(el[1]); + lp[2] = mesh->Point(el[2]); + + DrawTrigSurfaceVectors(lp,pmin,pmax,sei,vsol); + + lp[0] = mesh->Point(el[0]); + lp[1] = mesh->Point(el[2]); + lp[2] = mesh->Point(el[3]); + + DrawTrigSurfaceVectors(lp,pmin,pmax,sei,vsol); + */ + + Point<3> lp[4]; + Point<2> p2d[4]; + + for (int k = 0; k < 4; k++) + lp[k] = mesh->Point (el[k]); + + + Vec<3> n = Cross (lp[1]-lp[0], lp[2]-lp[0]); + Vec<3> na (fabs (n(0)), fabs(n(1)), fabs(n(2))); + int dir, dir1, dir2; + if (na(0) > na(1) && na(0) > na(2)) + dir = 1; + else if (na(1) > na(2)) + dir = 2; + else + dir = 3; + + dir1 = (dir % 3) + 1; + dir2 = (dir1 % 3) + 1; + + for (int k = 0; k < 4; k++) + { + p2d[k] = Point<2> ((lp[k](dir1-1) - pmin(dir1-1)) / (2*rad), + (lp[k](dir2-1) - pmin(dir2-1)) / (2*rad)); + } + + double minx2d, maxx2d, miny2d, maxy2d; + minx2d = maxx2d = p2d[0](0); + miny2d = maxy2d = p2d[0](1); + for (int k = 1; k < 4; k++) + { + minx2d = min2 (minx2d, p2d[k](0)); + maxx2d = max2 (maxx2d, p2d[k](0)); + miny2d = min2 (miny2d, p2d[k](1)); + maxy2d = max2 (maxy2d, p2d[k](1)); + } + + for (double s = xoffset/gridsize; s <= 1+xoffset/gridsize; s += 1.0 / gridsize) + if (s >= minx2d && s <= maxx2d) + for (double t = yoffset/gridsize; t <= 1+yoffset/gridsize; t += 1.0 / gridsize) + if (t >= miny2d && t <= maxy2d) + { + double lami[3]; + Point3d p3d(2*rad*s+pmin(0), 2*rad*t+pmin(1),0); + + if (mesh->PointContainedIn2DElement (p3d, lami, sei+1)) + { + Point<3> cp = p3d; + double lam1 = lami[0]; + double lam2 = lami[1]; + + //for (k = 0; k < 3; k++) + //cp(k) = lp[0](k) + + //lam1 * (lp[1](k)-lp[0](k)) + + //lam2 * (lp[2](k)-lp[0](k)); + + + Vec<3> v; + double values[6]; + bool drawelem = GetSurfValues (vsol, sei, -1, lam1, lam2, values); + (*testout) << "sei " << sei << " lam1 " << lam1 << " lam2 " << lam2 << " drawelem " << drawelem << endl; + + if (!vsol->iscomplex) + for (int k = 0; k < 3; k++) + v(k) = values[k]; + else + { + if (!imag_part) + for (int k = 0; k < 3; k++) + v(k) = values[2*k]; + else + for (int k = 0; k < 3; k++) + v(k) = values[2*k+1]; + } + + if (mesh->GetDimension() == 2) + if ( (!vsol->iscomplex && vsol->components != 3) || + (vsol->iscomplex && vsol->components != 6) ) + v(2) = 0; + + double val = v.Length(); + SetOpenGlColor (val); // , minval, maxval, logscale); july 09 + + (*testout) << "v " << v << endl; + + if (val > 1e-10 * maxval) + v *= (rad / val / gridsize * 0.5); + + (*testout) << "v " << v << endl; + + if ( drawelem ) + { + DrawCone (cp, cp+4*v, 0.8*rad / gridsize); + (*testout) << "cp " << cp << " rad " << rad << " gridsize " << gridsize << endl; + } + + } + } + } + } + } + } + + + + + void VisualSceneSolution :: + DrawIsoLines (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + double val1, double val2, double val3) + { + DrawIsoLines2 (p1, p2, p1, p3, val1, val2, val1, val3); // , minval, maxval, n); + DrawIsoLines2 (p2, p1, p2, p3, val2, val1, val2, val3); // , minval, maxval, n); + DrawIsoLines2 (p3, p1, p3, p2, val3, val1, val3, val2); // , minval, maxval, n); + } + + + void VisualSceneSolution :: + DrawIsoLines2 (const Point<3> & hp1, + const Point<3> & hp2, + const Point<3> & hp3, + const Point<3> & hp4, + double val1, double val2, double val3, double val4) + { + int n = numisolines; + Point<3> p1, p2, p3, p4; + if (val1 < val2) + { + p1 = hp1; p2 = hp2; + } + else + { + p1 = hp2; p2 = hp1; + swap (val1, val2); + } + + if (val3 < val4) + { + p3 = hp3; p4 = hp4; + } + else + { + p3 = hp4; p4 = hp3; + swap (val3, val4); + } + + val2 += 1e-10; + val4 += 1e-10; + + double fac = (maxval-minval) / n; + double idelta1 = 1.0 / (val2 - val1); + double idelta2 = 1.0 / (val4 - val3); + + int mini = int ((max2 (val1, val3) - minval) / fac); + int maxi = int ((min2 (val2, val4) - minval) / fac); + if (mini < 0) mini = 0; + if (maxi > n-1) maxi = n-1; + + for (int i = mini; i <= maxi; i++) + { + double val = minval + i * fac; + double lam1 = (val - val1) * idelta1; + double lam2 = (val - val3) * idelta2; + if (lam1 >= 0 && lam1 <= 1 && lam2 >= 0 && lam2 <= 1) + { + Point<3> lp1 = p1 + lam1 * (p2-p1); + Point<3> lp2 = p3 + lam2 * (p4-p3); + glVertex3dv (lp1 ); + glVertex3dv (lp2 ); + // glVertex3dv (lp2 ); // better ? + // glVertex3dv (lp1 ); + } + } + } + + + + void VisualSceneSolution :: + GetMinMax (int funcnr, int comp, double & minv, double & maxv) const + { + static int timer1 = NgProfiler::CreateTimer ("getminmax, vol"); + static int timer2 = NgProfiler::CreateTimer ("getminmax, surf"); + +#ifdef PARALLEL + if (id == 0) + { + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("getminmax"); + } + MyMPI_Bcast (funcnr); + MyMPI_Bcast (comp); +#endif + + // double val; + // bool considerElem; + + bool hasit = false; +#ifdef max; + #undef max; +#endif + minv = numeric_limits::max(); + maxv = -numeric_limits::max(); + + if ((ntasks == 1) || (id > 0)) + if (funcnr != -1) + { + const SolData * sol = soldata[funcnr]; + + if (sol->draw_volume) + { + NgProfiler::RegionTimer reg1 (timer1); + + int ne = mesh->GetNE(); + + double hminv = numeric_limits::max(); + double hmaxv = -numeric_limits::max(); + bool hhasit = false; +#pragma omp parallel for reduction (max : hmaxv) reduction (min : hminv) reduction (|| : hhasit) + for (int i = 0; i < ne; i++) + { + double val; + bool considerElem = GetValue (sol, i, 0.333, 0.333, 0.333, comp, val); + if (considerElem) + { + if (val > hmaxv) hmaxv = val; + if (val < hminv) hminv = val; + hhasit = true; + } + } + + minv = min(minv, hminv); + maxv = max(maxv, hmaxv); + hasit |= hhasit; + } + + if (sol->draw_surface) + { + NgProfiler::RegionTimer reg2 (timer2); + + int nse = mesh->GetNSE(); + for (int i = 0; i < nse; i++) + { + ELEMENT_TYPE type = mesh->SurfaceElement(i+1).GetType(); + double val; + bool considerElem = (type == QUAD) + ? GetSurfValue (sol, i, -1, 0.5, 0.5, comp, val) + : GetSurfValue (sol, i, -1, 0.3333333, 0.3333333, comp, val); + + if (considerElem) + { + if (val > maxv) maxv = val; + if (val < minv) minv = val; + hasit = true; + } + } + } + } + if (minv == maxv) maxv = minv+1e-6; + if (!hasit) { minv = 0; maxv = 1; } + +#ifdef PARALLEL + if ((ntasks > 1) && (id == 0)) + { + minv = 1e99; + maxv = -1e99; + } + double hmin, hmax; + MPI_Reduce (&minv, &hmin, 1, MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD); + MPI_Reduce (&maxv, &hmax, 1, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD); + minv = hmin; + maxv = hmax; +#endif + } + + + + + + bool VisualSceneSolution :: + GetValues (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + double * values) const + { + bool ok = false; + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ok = data->solclass->GetValue (elnr, lam1, lam2, lam3, values); + break; + } + default: + { + for (int i = 0; i < data->components; i++) + ok = GetValue (data, elnr, lam1, lam2, lam3, i+1, values[i]); + } + } + return ok; + } + + bool VisualSceneSolution :: + GetValues (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const + { + bool ok = false; + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ok = data->solclass->GetValue (elnr, xref, x, dxdxref, values); + break; + } + default: + { + for (int i = 0; i < data->components; i++) + ok = GetValue (data, elnr, xref[0], xref[1], xref[2], i+1, values[i]); + } + } + return ok; + } + + + bool VisualSceneSolution :: + GetValue (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const + { + + double lam1 = xref[0]; + double lam2 = xref[1]; + double lam3 = xref[2]; + + val = 0; + bool ok = 0; + + + if (comp == 0) + { + ArrayMem values(data->components); + ok = GetValues (data, elnr, xref, x, dxdxref, &values[0]); + + val = ExtractValue (data, 0, &values[0]); + return ok; + } + + + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + double values[20]; + ok = data->solclass->GetValue (elnr, xref, x, dxdxref, values); + + val = values[comp-1]; + return ok; + } + case SOL_NODAL: + { + const Element & el = (*mesh)[elnr]; + + double lami[8] = { 0.0 }; + int np = 0; + + switch (el.GetType()) + { + case TET: + case TET10: + { + lami[1] = lam1; + lami[2] = lam2; + lami[3] = lam3; + lami[0] = 1-lam1-lam2-lam3; + np = 4; + break; + } + case PRISM: + case PRISM12: + { + lami[0] = (1-lam3) * (1-lam1-lam2); + lami[1] = (1-lam3) * lam1; + lami[2] = (1-lam3) * lam2; + lami[3] = (lam3) * (1-lam1-lam2); + lami[4] = (lam3) * lam1; + lami[5] = (lam3) * lam2; + np = 6; + break; + } + default: + cerr << "case not implementd 23523" << endl; + } + + for (int i = 0; i < np; i++) + val += lami[i] * data->data[(el[i]-1) * data->dist + comp-1]; + + return 1; + } + + case SOL_ELEMENT: + { + val = data->data[elnr * data->dist + comp-1]; + return 1; + } + + case SOL_SURFACE_ELEMENT: + return 0; + + case SOL_NONCONTINUOUS: + { + const Element & el = (*mesh)[elnr]; + + double lami[8] = { 0.0 }; + int np = 0; + + switch (el.GetType()) + { + case TET: + case TET10: + { + lami[1] = lam1; + lami[2] = lam2; + lami[3] = lam3; + lami[0] = 1-lam1-lam2-lam3; + np = 4; + break; + } + case PRISM: + case PRISM12: + { + lami[0] = (1-lam3) * (1-lam1-lam2); + lami[1] = (1-lam3) * lam1; + lami[2] = (1-lam3) * lam2; + lami[3] = (lam3) * (1-lam1-lam2); + lami[4] = (lam3) * lam1; + lami[5] = (lam3) * lam2; + np = 6; + break; + } + case PYRAMID: + { + if (lam3 > 1-1e-5) + { + lami[0] = lami[1] = lami[2] = lami[3] = 0; + lami[4] = 1; + } + else + { + double x0 = lam1 / (1-lam3); + double y0 = lam2 / (1-lam3); + lami[0] = (1-x0) * (1-y0) * (1-lam3); + lami[1] = ( x0) * (1-y0) * (1-lam3); + lami[2] = ( x0) * ( y0) * (1-lam3); + lami[3] = (1-x0) * ( y0) * (1-lam3); + lami[4] = lam3; + np = 5; + } + break; + } + default: + np = 0; + } + + int base; + if (data->order == 1) + base = 6 * elnr; + else + base = 10 * elnr; + + + for (int i = 0; i < np; i++) + val += lami[i] * data->data[(base+i) * data->dist + comp-1]; + + return 1; + } + + case SOL_MARKED_ELEMENTS: + { + val = (*mesh)[elnr].TestRefinementFlag(); + return 1; + } + + case SOL_ELEMENT_ORDER: + { + val = (*mesh)[elnr].GetOrder(); + return 1; + } + + default: + cerr << "case not handled 7234" << endl; + } + return 0; + } + + + + bool VisualSceneSolution :: + GetValue (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + int comp, double & val) const + { + + val = 0; + bool ok = 0; + + if (comp == 0) + { + ArrayMem values(data->components); + ok = GetValues (data, elnr, lam1, lam2, lam3, &values[0]); + val = ExtractValue (data, 0, &values[0]); + return ok; + } + + + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + double values[20]; + ok = data->solclass->GetValue (elnr, lam1, lam2, lam3, values); + + val = values[comp-1]; + return ok; + } + case SOL_NODAL: + { + const Element & el = (*mesh)[elnr]; + + double lami[8] = { 0.0 }; + int np = 0; + + switch (el.GetType()) + { + case TET: + case TET10: + { + lami[1] = lam1; + lami[2] = lam2; + lami[3] = lam3; + lami[0] = 1-lam1-lam2-lam3; + np = 4; + break; + } + case PRISM: + case PRISM12: + { + lami[0] = (1-lam3) * (1-lam1-lam2); + lami[1] = (1-lam3) * lam1; + lami[2] = (1-lam3) * lam2; + lami[3] = (lam3) * (1-lam1-lam2); + lami[4] = (lam3) * lam1; + lami[5] = (lam3) * lam2; + np = 6; + break; + } + default: + cerr << "case not implemented 234324" << endl; + } + + for (int i = 0; i < np; i++) + val += lami[i] * data->data[(el[i]-1) * data->dist + comp-1]; + + return 1; + } + + case SOL_ELEMENT: + { + val = data->data[elnr * data->dist + comp-1]; + return 1; + } + + case SOL_SURFACE_ELEMENT: + return 0; + + case SOL_NONCONTINUOUS: + { + const Element & el = (*mesh)[elnr]; + + double lami[8] = { 0.0 }; + int np = 0; + + switch (el.GetType()) + { + case TET: + case TET10: + { + lami[1] = lam1; + lami[2] = lam2; + lami[3] = lam3; + lami[0] = 1-lam1-lam2-lam3; + np = 4; + break; + } + case PRISM: + case PRISM12: + { + lami[0] = (1-lam3) * (1-lam1-lam2); + lami[1] = (1-lam3) * lam1; + lami[2] = (1-lam3) * lam2; + lami[3] = (lam3) * (1-lam1-lam2); + lami[4] = (lam3) * lam1; + lami[5] = (lam3) * lam2; + np = 6; + break; + } + case PYRAMID: + { + if (lam3 > 1-1e-5) + { + lami[0] = lami[1] = lami[2] = lami[3] = 0; + lami[4] = 1; + } + else + { + double x0 = lam1 / (1-lam3); + double y0 = lam2 / (1-lam3); + lami[0] = (1-x0) * (1-y0) * (1-lam3); + lami[1] = ( x0) * (1-y0) * (1-lam3); + lami[2] = ( x0) * ( y0) * (1-lam3); + lami[3] = (1-x0) * ( y0) * (1-lam3); + lami[4] = lam3; + np = 5; + } + break; + } + default: + np = 0; + } + + int base; + if (data->order == 1) + base = 6 * elnr; + else + base = 10 * elnr; + + + for (int i = 0; i < np; i++) + val += lami[i] * data->data[(base+i) * data->dist + comp-1]; + + return 1; + } + + case SOL_MARKED_ELEMENTS: + { + val = (*mesh)[elnr].TestRefinementFlag(); + return 1; + } + + case SOL_ELEMENT_ORDER: + { + val = (*mesh)[elnr].GetOrder(); + return 1; + } + default: + cerr << "case not implemented 234234" << endl; + } + return 0; + } + + + + + + + + bool VisualSceneSolution :: + GetValueComplex (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + int comp, complex & val) const + { + val = 0.0; + bool ok = 0; + + + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + double values[20]; + ok = data->solclass->GetValue (elnr, lam1, lam2, lam3, values); + val = complex (values[comp-1], values[comp]); + return ok; + } + default: + cerr << "case not handled 234234" << endl; + } + return 0; + } + + + bool VisualSceneSolution :: + GetMultiValues (const SolData * data, ElementIndex elnr, int facetnr, int npt, + const double * xref, int sxref, + const double * x, int sx, + const double * dxdxref, int sdxdxref, + double * val, int sval) const + { + bool drawelem = false; + if (data->soltype == SOL_VIRTUALFUNCTION) + drawelem = data->solclass->GetMultiValue(elnr, facetnr, npt, xref, sxref, x, sx, dxdxref, sdxdxref, val, sval); + else + for (int i = 0; i < npt; i++) + drawelem = GetValues (data, elnr, xref+i*sxref, x+i*sx, dxdxref+i*sdxdxref, val+i*sval); + return drawelem; + } + + + + + + + bool VisualSceneSolution :: + GetSurfValues (const SolData * data, SurfaceElementIndex selnr, int facetnr, + double lam1, double lam2, + double * values) const + { + bool ok = false; + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ok = data->solclass->GetSurfValue (selnr, facetnr, lam1, lam2, values); + // ok = 1; + // values[0] = 1.0; + break; + } + default: + { + for (int i = 0; i < data->components; i++) + ok = GetSurfValue (data, selnr, facetnr, lam1, lam2, i+1, values[i]); + } + } + return ok; + } + + + bool VisualSceneSolution :: + GetSurfValues (const SolData * data, SurfaceElementIndex selnr, int facetnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const + { + bool ok = false; + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ok = data->solclass->GetSurfValue (selnr, facetnr, xref, x, dxdxref, values); + break; + } + default: + { + for (int i = 0; i < data->components; i++) + ok = GetSurfValue (data, selnr, facetnr, xref[0], xref[1], i+1, values[i]); + } + } + return ok; + } + + bool VisualSceneSolution :: + GetMultiSurfValues (const SolData * data, SurfaceElementIndex elnr, int facetnr, int npt, + const double * xref, int sxref, + const double * x, int sx, + const double * dxdxref, int sdxdxref, + double * val, int sval) const + { + bool drawelem = false; + if (data->soltype == SOL_VIRTUALFUNCTION) + drawelem = data->solclass->GetMultiSurfValue(elnr, facetnr, npt, xref, sxref, x, sx, dxdxref, sdxdxref, val, sval); + else + for (int i = 0; i < npt; i++) + drawelem = GetSurfValues (data, elnr, facetnr, xref+i*sxref, x+i*sx, dxdxref+i*sdxdxref, val+i*sval); + return drawelem; + } + + double VisualSceneSolution :: ExtractValue (const SolData * data, int comp, double * values) const + { + double val = 0; + if (comp == 0) + { + switch (evalfunc) + { + case FUNC_ABS: + { + for (int ci = 0; ci < data->components; ci++) + val += sqr (values[ci]); + val = sqrt (val); + break; + } + case FUNC_ABS_TENSOR: + { + int d = 0; + switch (data->components) + { + case 1: d = 1; break; + case 3: d = 2; break; + case 6: d = 3; break; + } + for (int ci = 0; ci < d; ci++) + val += sqr (values[ci]); + for (int ci = d; ci < data->components; ci++) + val += 2*sqr (values[ci]); + val = sqrt (val); + break; + } + + case FUNC_MISES: + { + int d = 0; + switch(data->components) + { + case 1: d = 1; break; + case 3: d = 2; break; + case 6: d = 3; break; + } + int ci; + double trace = 0.; + for (ci = 0; ci < d; ci++) + trace += 1./3.*(values[ci]); + for (ci = 0; ci < d; ci++) + val += sqr (values[ci]-trace); + for (ci = d; ci < data->components; ci++) + val += 2.*sqr (values[ci]); + val = sqrt (val); + break; + } + case FUNC_MAIN: + { + int d = 0; + switch(data->components) + { + case 1: d = 1; break; + case 3: d = 2; break; + case 6: d = 3; break; + } + Mat<3,3> m ; + Vec<3> ev; + int ci; + for (ci = 0; ci < d; ci++) + m(ci,ci) = (values[ci]); + m(0,1) = m(1,0) = values[3]; + m(0,2) = m(2,0) = values[4]; + m(1,2) = m(2,1) = values[5]; + + EigenValues (m, ev); + double help; + for (int i=0; i abs(ev(j-1)) ) + { + help = ev(j); + ev(j) = ev(j-1); + ev(j-1) = help; + } + } + } + val = (ev(0)); + break; + } + } + return val; + } + + return values[comp-1]; + } + + complex VisualSceneSolution :: ExtractValueComplex (const SolData * data, int comp, double * values) const + { + if (!data->iscomplex) + return values[comp-1]; + else + return complex (values[comp-1], values[comp]); + } + + + + + bool VisualSceneSolution :: + GetSurfValueComplex (const SolData * data, SurfaceElementIndex selnr, int facetnr, + double lam1, double lam2, + int comp, complex & val) const + { + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ArrayMem values(data->components); + bool ok; + + ok = data->solclass->GetSurfValue (selnr, facetnr, lam1, lam2, &values[0]); + + if (ok) + { + if (!data->iscomplex) + val = values[comp-1]; + else + val = complex (values[comp-1], values[comp]); + } + + return ok; + } + default: + cerr << "case not implementd 6565" << endl; + } + return 0; + } + + bool VisualSceneSolution :: + GetSurfValue (const SolData * data, SurfaceElementIndex selnr, int facetnr, + double lam1, double lam2, + int comp, double & val) const + { + bool ok; + if (comp == 0) + { + val = 0; + ArrayMem values(data->components); + ok = GetSurfValues (data, selnr, facetnr, lam1, lam2, &values[0]); + val = ExtractValue (data, 0, &values[0]); + return ok; + } + + + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + + ArrayMem values(data->components); + bool ok; + + ok = data->solclass->GetSurfValue (selnr, facetnr, lam1, lam2, &values[0]); + + if (ok) + { + if (!data->iscomplex) + val = values[comp-1]; + else + { + // cout << "time = " << time << ", cos = " << cos(time) << endl; + + // old version: val = values[comp-1]*cos(3*time) + values[comp]*sin(3*time); + // SZ: Sept 06 + if(comp%2==0) + val = values[comp-1]*cos(3*time) - values[comp-2]*sin(3*time); + else + val = values[comp-1]*cos(3*time) + values[comp]*sin(3*time); + + + + } + } + + return ok; + } + + + case SOL_NODAL: + { + const Element2d & el = (*mesh)[selnr]; + + double lami[8]; + int np, i; + val = 0; + double lam3 = 1-lam1-lam2; + + switch (el.GetType()) + { + case TRIG: + /* + lami[0] = lam3; + lami[1] = lam1; + lami[2] = lam2; + */ + lami[0] = lam1; + lami[1] = lam2; + lami[2] = lam3; + np = 3; + break; + + case TRIG6: + /* + lami[0] = lam3*(2*lam3-1); + lami[1] = lam1*(2*lam1-1); + lami[2] = lam2*(2*lam2-1); + */ + // hierarchical basis: + lami[0] = lam3; + lami[1] = lam1; + lami[2] = lam2; + lami[3] = 4*lam1*lam2; + lami[4] = 4*lam2*lam3; + lami[5] = 4*lam1*lam3; + np = 6; + break; + + case QUAD: + case QUAD6: + lami[0] = (1-lam1)*(1-lam2); + lami[1] = lam1 * (1-lam2); + lami[2] = lam1 * lam2; + lami[3] = (1-lam1) * lam2; + np = 4; + break; + + default: + np = 0; + } + + for (i = 0; i < np; i++) + val += lami[i] * data->data[(el[i]-1) * data->dist + comp-1]; + + return 1; + } + + case SOL_ELEMENT: + { + int el1, el2; + mesh->GetTopology().GetSurface2VolumeElement (selnr+1, el1, el2); + el1--; + + val = data->data[el1 * data->dist+comp-1]; + return 1; + } + + case SOL_NONCONTINUOUS: + { + val = 0; + // ????? + return 0; + } + + case SOL_SURFACE_ELEMENT: + { + val = data->data[selnr * data->dist + comp-1]; + return 1; + } + + case SOL_SURFACE_NONCONTINUOUS: + { + const Element2d & el = (*mesh)[selnr]; + + double lami[8]; + int np = 0; + val = 0; + int order = data->order; + + switch (order) + { + case 0: + return data->data[selnr * data->dist + comp-1]; + case 1: + { + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + lami[1] = lam1; + lami[2] = lam2; + lami[0] = 1-lam1-lam2; + np = 3; + break; + } + default: + cerr << "case not implementd 2342" << endl; + } + break; + } + case 2: + { + switch (el.GetType()) + { + case TRIG: + { + lami[1] = lam1; + lami[2] = lam2; + lami[0] = 1-lam1-lam2; + np = 3; + break; + } + case TRIG6: + { + double lam3 = 1-lam1-lam2; + lami[1] = 2*lam1 * (lam1-0.5); + lami[2] = 2*lam2 * (lam2-0.5); + lami[0] = 2*lam3 * (lam3-0.5); + lami[3] = 4*lam1*lam2; + lami[4] = 4*lam2*lam3; + lami[5] = 4*lam1*lam3; + np = 6; + break; + } + default: + cerr << "case not implemented 8712" << endl; + } + break; + } + } + + int base; + if (order == 1) + base = 4 * selnr; + else + base = 9 * selnr; + + for (int i = 0; i < np; i++) + val += lami[i] * data->data[(base+i) * data->dist + comp-1]; + + return 1; + } + + case SOL_MARKED_ELEMENTS: + { + val = (*mesh)[selnr].TestRefinementFlag(); + return 1; + } + + case SOL_ELEMENT_ORDER: + { + val = (*mesh)[selnr].GetOrder(); + return 1; + } + + } + return 0; + } + + + + + + + + + + + + + bool VisualSceneSolution :: + GetSurfValue (const SolData * data, SurfaceElementIndex selnr, int facetnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const + { + double lam1 = xref[0], lam2 = xref[1]; + + bool ok; + if (comp == 0) + { + val = 0; + ArrayMem values(data->components); + ok = GetSurfValues (data, selnr, facetnr, xref, x, dxdxref, &values[0]); + val = ExtractValue (data, 0, &values[0]); + return ok; + } + + + switch (data->soltype) + { + case SOL_VIRTUALFUNCTION: + { + ArrayMem values(data->components); + bool ok; + + // ok = data->solclass->GetSurfValue (selnr, lam1, lam2, &values[0]); + // cout << "data->solclass = " << flush << data->solclass << endl; + ok = data->solclass->GetSurfValue (selnr, facetnr, xref, x, dxdxref, &values[0]); + // ok = 1; + // values[0] = 1.0; + + if (ok) + { + if (!data->iscomplex) + val = values[comp-1]; + else + { + // cout << "time = " << time << ", cos = " << cos(time) << endl; + + // old version: val = values[comp-1]*cos(3*time) + values[comp]*sin(3*time); + // SZ: Sept 06 + if(comp%2==0) + val = values[comp-1]*cos(3*time) - values[comp-2]*sin(3*time); + else + val = values[comp-1]*cos(3*time) + values[comp]*sin(3*time); + + } + } + + return ok; + } + + + case SOL_NODAL: + { + const Element2d & el = (*mesh)[selnr]; + + double lami[8]; + int np, i; + val = 0; + double lam3 = 1-lam1-lam2; + + switch (el.GetType()) + { + case TRIG: + /* + lami[0] = lam3; + lami[1] = lam1; + lami[2] = lam2; + */ + lami[0] = lam1; + lami[1] = lam2; + lami[2] = lam3; + np = 3; + break; + + case TRIG6: + /* + lami[0] = lam3*(2*lam3-1); + lami[1] = lam1*(2*lam1-1); + lami[2] = lam2*(2*lam2-1); + */ + // hierarchical basis: + lami[0] = lam3; + lami[1] = lam1; + lami[2] = lam2; + lami[3] = 4*lam1*lam2; + lami[4] = 4*lam2*lam3; + lami[5] = 4*lam1*lam3; + np = 6; + break; + + case QUAD: + case QUAD6: + lami[0] = (1-lam1)*(1-lam2); + lami[1] = lam1 * (1-lam2); + lami[2] = lam1 * lam2; + lami[3] = (1-lam1) * lam2; + np = 4; + break; + + default: + np = 0; + } + + for (i = 0; i < np; i++) + val += lami[i] * data->data[(el[i]-1) * data->dist + comp-1]; + + return 1; + } + + case SOL_ELEMENT: + { + int el1, el2; + mesh->GetTopology().GetSurface2VolumeElement (selnr+1, el1, el2); + el1--; + + val = data->data[el1 * data->dist+comp-1]; + return 1; + } + + case SOL_NONCONTINUOUS: + { + val = 0; + // ????? + return 0; + } + + case SOL_SURFACE_ELEMENT: + { + val = data->data[selnr * data->dist + comp-1]; + return 1; + } + + case SOL_SURFACE_NONCONTINUOUS: + { + const Element2d & el = (*mesh)[selnr]; + + double lami[8] = { 0.0 }; + int np = 0; + val = 0; + int order = data->order; + + switch (order) + { + case 0: + return data->data[selnr * data->dist + comp-1]; + case 1: + { + switch (el.GetType()) + { + case TRIG: + case TRIG6: + { + lami[1] = lam1; + lami[2] = lam2; + lami[0] = 1-lam1-lam2; + np = 3; + break; + } + default: + cerr << "case not impl 234234" << endl; + } + break; + } + case 2: + { + switch (el.GetType()) + { + case TRIG: + { + lami[1] = lam1; + lami[2] = lam2; + lami[0] = 1-lam1-lam2; + np = 3; + break; + } + case TRIG6: + { + double lam3 = 1-lam1-lam2; + lami[1] = 2*lam1 * (lam1-0.5); + lami[2] = 2*lam2 * (lam2-0.5); + lami[0] = 2*lam3 * (lam3-0.5); + lami[3] = 4*lam1*lam2; + lami[4] = 4*lam2*lam3; + lami[5] = 4*lam1*lam3; + np = 6; + break; + } + default: + cerr << "case not implented 3234" << endl; + } + break; + } + } + + int base; + if (order == 1) + base = 4 * selnr; + else + base = 9 * selnr; + + for (int i = 0; i < np; i++) + val += lami[i] * data->data[(base+i) * data->dist + comp-1]; + + return 1; + } + + case SOL_MARKED_ELEMENTS: + { + val = (*mesh)[selnr].TestRefinementFlag(); + return 1; + } + + case SOL_ELEMENT_ORDER: + { + val = (*mesh)[selnr].GetOrder(); + return 1; + } + + } + return 0; + } + + + + + + + + + + Vec<3> VisualSceneSolution :: + GetDeformation (ElementIndex elnr, const Point<3> & p) const + { + Vec<3> def; + if (deform && vecfunction != -1) + { + GetValues (soldata[vecfunction], elnr, p(0), p(1), p(2), &def(0)); + def *= scaledeform; + + if (soldata[vecfunction]->components == 2) def(2) = 0; + } + else + def = 0; + return def; + } + + + Vec<3> VisualSceneSolution :: + GetSurfDeformation (SurfaceElementIndex elnr, int facetnr, double lam1, double lam2) const + { + Vec<3> def; + if (deform && vecfunction != -1) + { + // GetSurfValues (soldata[vecfunction], elnr, facetnr, lam1, lam2, &def(0)); + double values[6]; + GetSurfValues (soldata[vecfunction], elnr, facetnr, lam1, lam2, values); + def = RealVec3d (values, soldata[vecfunction]->iscomplex, imag_part); + def *= scaledeform; + + if (soldata[vecfunction]->components == 2) def(2) = 0; + } + else if (deform && scalfunction != -1 && mesh->GetDimension()==2) + { // he: allow for 3d plots of 2d surfaces: usage: turn deformation on + def = 0; + GetSurfValue (soldata[scalfunction], elnr, facetnr, lam1, lam2, scalcomp, def(2)); + def *= scaledeform; + } + else + def = 0; + return def; + } + + void VisualSceneSolution :: GetPointDeformation (int pnum, Point<3> & p, + SurfaceElementIndex elnr) const + { + p = mesh->Point (pnum+1); + if (deform && vecfunction != -1) + { + const SolData * vsol = soldata[vecfunction]; + + Vec<3> v(0,0,0); + if (vsol->soltype == SOL_NODAL) + { + v = Vec3d(vsol->data[pnum * vsol->dist], + vsol->data[pnum * vsol->dist+1], + vsol->data[pnum * vsol->dist+2]); + } + else if (vsol->soltype == SOL_SURFACE_NONCONTINUOUS) + { + const Element2d & el = (*mesh)[elnr]; + for (int j = 0; j < el.GetNP(); j++) + if (el[j] == pnum+1) + { + int base = (4*elnr+j-1) * vsol->dist; + v = Vec3d(vsol->data[base], + vsol->data[base+1], + vsol->data[base+2]); + } + } + + if (vsol->dist == 2) v(2) = 0; + + v *= scaledeform; + p += v; + } + } + + + + + void VisualSceneSolution :: GetClippingPlaneTrigs (Array & trigs, + Array & pts) + { + static int timer_vals = NgProfiler::CreateTimer ("ClipPlaneTrigs - vertex values"); + static int timer1 = NgProfiler::CreateTimer ("ClipPlaneTrigs1"); + static int timer1a = NgProfiler::CreateTimer ("ClipPlaneTrigs1a"); + // static int timer2 = NgProfiler::CreateTimer ("ClipPlaneTrigs2"); + static int timer3 = NgProfiler::CreateTimer ("ClipPlaneTrigs3"); + static int timer4 = NgProfiler::CreateTimer ("ClipPlaneTrigs4"); + static int timer4b = NgProfiler::CreateTimer ("ClipPlaneTrigs4b"); + + + NgProfiler::RegionTimer reg1 (timer1); + + + int ne = mesh->GetNE(); + + const int edgei[6][2] = + { { 0, 1 }, { 0, 2 }, { 0, 3 }, + { 1, 2 }, { 1, 3 }, { 2, 3 } }; + + double edgelam[6]; + Point<3> edgep[6]; + double nodevali[4]; + + int cntce; + int cpe1 = 0, cpe2 = 0, cpe3 = 0; + + // Array loctets; + // Array loctetsloc; + // Array > pointsloc; + + int n = 1 << subdivisions; + int n3 = (n+1)*(n+1)*(n+1); + + Array > grid(n3); + Array > locgrid(n3); + Array > trans(n3); + Array val(n3); + Array locposval(n3); + Array compress(n3); + + NgProfiler::StartTimer (timer_vals); + Array vertval(mesh->GetNV()); + Array posval(mesh->GetNV()); + for (PointIndex pi = vertval.Begin(); pi < vertval.End(); pi++) + { + Point<3> vert = (*mesh)[pi]; + vertval[pi] = + vert(0) * clipplane[0] + + vert(1) * clipplane[1] + + vert(2) * clipplane[2] + + clipplane[3]; + posval[pi] = vertval[pi] > 0; + } + NgProfiler::StopTimer (timer_vals); + + INDEX_2_CLOSED_HASHTABLE edges(8*n3); // point nr of edge + + + for (ElementIndex ei = 0; ei < ne; ei++) + { + // NgProfiler::RegionTimer reg1a (timer1a); + int first_point_of_element = pts.Size(); + + locgrid.SetSize(n3); + if(vispar.clipdomain > 0 && vispar.clipdomain != (*mesh)[ei].GetIndex()) continue; + if(vispar.donotclipdomain > 0 && vispar.donotclipdomain == (*mesh)[ei].GetIndex()) continue; + + ELEMENT_TYPE type = (*mesh)[ei].GetType(); + if (type == HEX || type == PRISM || type == TET || type == TET10 || type == PYRAMID) + { + const Element & el = (*mesh)[ei]; + + int ii = 0; + int cnt_valid = 0; + + // NgProfiler::StartTimer (timer2); + + + if (!mesh->GetCurvedElements().IsElementHighOrder(ei)) + { + bool has_pos = 0, has_neg = 0; + + for (int i = 0; i < el.GetNP(); i++) + if (posval[el[i]] > 0) + has_pos = 1; + else + has_neg = 1; + + if (!has_pos || !has_neg) + { + // NgProfiler::StopTimer (timer2); + continue; + } + } + + + + if (type == TET || type == TET10) + { + for (int ix = 0; ix <= n; ix++) + for (int iy = 0; iy <= n; iy++) + for (int iz = 0; iz <= n; iz++, ii++) + { + if (ix+iy+iz <= n) + { + compress[ii] = cnt_valid; + locgrid[cnt_valid] = + Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + cnt_valid++; + } + else + compress[ii] = -1; + } + } + + else + + for (int ix = 0; ix <= n; ix++) + for (int iy = 0; iy <= n; iy++) + for (int iz = 0; iz <= n; iz++, ii++) + { + Point<3> ploc; + compress[ii] = ii; + + switch (type) + { + case PRISM: + if (ix+iy <= n) + { + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + compress[ii] = cnt_valid; + cnt_valid++; + } + else + compress[ii] = -1; + break; + case HEX: + ploc = Point<3> (double(ix) / n, double(iy) / n, double(iz) / n); + break; + case PYRAMID: + ploc = Point<3> (double(ix) / n * (1-double(iz)/n), + double(iy) / n * (1-double(iz)/n), + double(iz)/n); + if (iz == n) ploc = Point<3> (0,0,1-1e-8); + break; + default: + cerr << "clip plane trigs not implemented" << endl; + ploc = Point<3> (0,0,0); + } + if (compress[ii] != -1) + locgrid[compress[ii]] = ploc; + } + + if (type != TET && type != TET10 && type != PRISM) cnt_valid = n3; + + locgrid.SetSize(cnt_valid); + + // NgProfiler::StopTimer (timer2); + // NgProfiler::RegionTimer reg4(timer4); + + if (mesh->GetCurvedElements().IsHighOrder()) + { + NgProfiler::RegionTimer reg4(timer4); + mesh->GetCurvedElements(). + CalcMultiPointElementTransformation (&locgrid, ei, &grid, 0); + } + else + { + NgProfiler::RegionTimer reg4(timer4b); + Vector shape(el.GetNP()); + MatrixFixWidth<3> pointmat(el.GetNP()); + + for (int k = 0; k < el.GetNP(); k++) + for (int j = 0; j < 3; j++) + pointmat(k,j) = (*mesh)[el[k]](j); + + for (int i = 0; i < cnt_valid; i++) + { + el.GetShapeNew (locgrid[i], shape); + Point<3> pglob; + for (int j = 0; j < 3; j++) + { + pglob(j) = 0; + for (int k = 0; k < el.GetNP(); k++) + pglob(j) += shape(k) * pointmat(k,j); + } + grid[i] = pglob; + } + } + + NgProfiler::RegionTimer reg3(timer3); + + bool has_pos = false, all_pos = true; + + for (int i = 0; i < cnt_valid; i++) + { + val[i] = + grid[i](0) * clipplane[0] + + grid[i](1) * clipplane[1] + + grid[i](2) * clipplane[2] + + clipplane[3]; + + locposval[i] = val[i] > 0; + has_pos |= locposval[i]; + all_pos &= locposval[i]; + + // if (val[i] > 0) has_pos = 1; else has_neg = 1; + } + + // if (!has_pos || !has_neg) continue; + if (!has_pos || all_pos) continue; + + edges.DeleteData(); + + for (int ix = 0; ix < n; ix++) + for (int iy = 0; iy < n; iy++) + for (int iz = 0; iz < n; iz++) + { + int base = iz + (n+1)*iy + (n+1)*(n+1)*ix; + int pi[8] = + { base, base+(n+1)*(n+1), base+(n+1)*(n+1)+(n+1), base+(n+1), + base+1, base+(n+1)*(n+1)+1, base+(n+1)*(n+1)+(n+1)+1, base+(n+1)+1 }; + + for (int j = 0; j < 8; j++) + pi[j] = compress[pi[j]]; + + bool has_pos = false, all_pos = true; + for (int j = 0; j < 8; j++) + if (pi[j] != -1) + { + has_pos |= locposval[pi[j]]; + all_pos &= locposval[pi[j]]; + } + if (!has_pos || all_pos) continue; + + + const int tets[6][4] = + { { 1, 2, 4, 5 }, + { 4, 5, 2, 8 }, + { 2, 8, 5, 6 }, + { 2, 3, 4, 8 }, + { 2, 3, 8, 6 }, + { 3, 8, 6, 7 } }; + + for (int ii = 0; ii < 6; ii++) + { + int teti[4]; + for (int k = 0; k < 4; k++) + teti[k] = pi[tets[ii][k]-1]; + + bool is_valid = true; + for (int j = 0; j < 4; j++) + is_valid &= (teti[j] != -1); + if (!is_valid) continue; + + bool has_pos = false, all_pos = true; + for (int j = 0; j < 4; j++) + { + has_pos |= locposval[teti[j]]; + all_pos &= locposval[teti[j]]; + } + if (!has_pos || all_pos) continue; + + for (int j = 0; j < 4; j++) + nodevali[j] = val[teti[j]]; + + cntce = 0; + for (int j = 0; j < 6; j++) + { + int lpi1 = edgei[j][0]; + int lpi2 = edgei[j][1]; + if ( (nodevali[lpi1] > 0) != (nodevali[lpi2] > 0) ) + { + cntce++; + cpe3 = cpe2; + cpe2 = cpe1; + cpe1 = j; + if (cntce >= 3) + { + ClipPlaneTrig cpt; + cpt.elnr = ei; + + for (int k = 0; k < 3; k++) + { + int ednr; + switch (k) + { + case 0: ednr = cpe1; break; + case 1: ednr = cpe2; break; + case 2: ednr = cpe3; break; + } + + int pi1 = edgei[ednr][0]; + int pi2 = edgei[ednr][1]; + int pnr = -1; + + INDEX_2 pair (teti[pi1], teti[pi2]); + pair.Sort(); + if (edges.Used(pair)) + pnr = edges.Get(pair); + else + { + ClipPlanePoint cppt; + cppt.elnr = ei; + + edgelam[ednr] = nodevali[pi2] / (nodevali[pi2] - nodevali[pi1]); + + Point<3> gp1 = grid[teti[pi1]]; + Point<3> gp2 = grid[teti[pi2]]; + cppt.p = gp2 + edgelam[ednr] * (gp1-gp2); + + Point<3> p1 = locgrid[teti[pi1]]; + Point<3> p2 = locgrid[teti[pi2]]; + cppt.lami = p2 + edgelam[ednr] * (p1-p2); + + + pnr = pts.Append (cppt)-1; + edges.Set (pair, pnr); + } + + cpt.points[k].pnr = pnr; + cpt.points[k].locpnr = pnr-first_point_of_element; + } + + trigs.Append (cpt); + } + } + } + } + } + } + + else + { // other elements not supported (JS, June 2007) + continue; // return; + } + + } + } + + void VisualSceneSolution :: GetClippingPlaneGrid (Array & pts) + { + Vec3d n(clipplane[0], clipplane[1], clipplane[2]); + + double mu = -clipplane[3] / n.Length2(); + Point3d p(mu*n.X(), mu * n.Y(), mu * n.Z()); + + // n /= n.Length(); + n.Normalize(); + Vec3d t1, t2; + n.GetNormal (t1); + t2 = Cross (n, t1); + + double xi1, xi2; + + double xi1mid = (center - p) * t1; + double xi2mid = (center - p) * t2; + + pts.SetSize(0); + + for (xi1 = xi1mid-rad+xoffset/gridsize; xi1 <= xi1mid+rad+xoffset/gridsize; xi1 += rad / gridsize) + for (xi2 = xi2mid-rad+yoffset/gridsize; xi2 <= xi2mid+rad+yoffset/gridsize; xi2 += rad / gridsize) + { + Point3d hp = p + xi1 * t1 + xi2 * t2; + + int cindex(-1); + bool allowindex(true); + if(vispar.clipdomain > 0) + { + cindex = vispar.clipdomain; + } + else if(vispar.donotclipdomain > 0) + { + allowindex = false; + cindex = vispar.donotclipdomain; + } + + double lami[3]; + int elnr = mesh->GetElementOfPoint (hp, lami,0,cindex,allowindex)-1; + + if (elnr != -1) + { + ClipPlanePoint cpp; + cpp.p = hp; + cpp.elnr = elnr; + cpp.lami(0) = lami[0]; + cpp.lami(1) = lami[1]; + cpp.lami(2) = lami[2]; + pts.Append (cpp); + } + } + }; + + + + + void VisualSceneSolution :: DrawClipPlaneTrigs () + { +#ifdef PARALLELGL + + if (id == 0 && ntasks > 1) + { + InitParallelGL(); + + Array parlists (ntasks); + + MyMPI_SendCmd ("redraw"); + MyMPI_SendCmd ("clipplanetrigs"); + + for ( int dest = 1; dest < ntasks; dest++ ) + MyMPI_Recv (parlists[dest], dest, MPI_TAG_VIS); + + if (clipplanelist_scal) + glDeleteLists (clipplanelist_scal, 1); + + clipplanelist_scal = glGenLists (1); + glNewList (clipplanelist_scal, GL_COMPILE); + + for ( int dest = 1; dest < ntasks; dest++ ) + glCallList (parlists[dest]); + + glEndList(); + return; + } +#endif + + + + + + if (clipplanelist_scal) + glDeleteLists (clipplanelist_scal, 1); + + clipplanelist_scal = glGenLists (1); + glNewList (clipplanelist_scal, GL_COMPILE); + + + Array trigs; + Array points; + GetClippingPlaneTrigs (trigs, points); + + glNormal3d (-clipplane[0], -clipplane[1], -clipplane[2]); + glColor3d (1.0, 1.0, 1.0); + + SetTextureMode (usetexture); + + SolData * sol = NULL; + + if (scalfunction != -1) + sol = soldata[scalfunction]; + + if (sol -> draw_volume) + { + glBegin (GL_TRIANGLES); + + int maxlpnr = 0; + for (int i = 0; i < trigs.Size(); i++) + for (int j = 0; j < 3; j++) + maxlpnr = max2 (maxlpnr, trigs[i].points[j].locpnr); + + Array vals(maxlpnr+1); + Array > valsc(maxlpnr+1); + Array elnrs(maxlpnr+1); + Array trigok(maxlpnr+1); + Array > locpoints(maxlpnr+1); + Array > globpoints(maxlpnr+1); + Array > jacobi(maxlpnr+1); + Array mvalues( (maxlpnr+1) * sol->components); + trigok = false; + elnrs = -1; + + Point<3> p[3]; + // double val[3]; + // complex valc[3]; + int lastelnr = -1; + int nlp = -1; + bool ok = false; + + for (int i = 0; i < trigs.Size(); i++) + { + const ClipPlaneTrig & trig = trigs[i]; + if (trig.elnr != lastelnr) + { + lastelnr = trig.elnr; + nlp = -1; + + for (int ii = i; ii < trigs.Size(); ii++) + { + if (trigs[ii].elnr != trig.elnr) break; + for (int j = 0; j < 3; j++) + nlp = max (nlp, trigs[ii].points[j].locpnr); + } + nlp++; + locpoints.SetSize (nlp); + + for (int ii = i; ii < trigs.Size(); ii++) + { + if (trigs[ii].elnr != trig.elnr) break; + for (int j = 0; j < 3; j++) + locpoints[trigs[ii].points[j].locpnr] = points[trigs[ii].points[j].pnr].lami; + } + + mesh->GetCurvedElements(). + CalcMultiPointElementTransformation (&locpoints, trig.elnr, + &globpoints, &jacobi); + + bool + drawelem = GetMultiValues (sol, trig.elnr, -1, nlp, + &locpoints[0](0), &locpoints[1](0)-&locpoints[0](0), + &globpoints[0](0), &globpoints[1](0)-&globpoints[0](0), + &jacobi[0](0), &jacobi[1](0)-&jacobi[0](0), + &mvalues[0], sol->components); + + // cout << "have multivalues, comps = " << sol->components << endl; + + // if (!drawelem) ok = false; + ok = drawelem; + if (usetexture != 2 || !sol->iscomplex) + for (int ii = 0; ii < nlp; ii++) + vals[ii] = ExtractValue(sol, scalcomp, &mvalues[ii*sol->components]); + else + for (int ii = 0; ii < nlp; ii++) + valsc[ii] = complex (mvalues[ii*sol->components], + mvalues[ii*sol->components+1]); + } + + if(ok) + for(int j=0; j<3; j++) + { + if (usetexture != 2 || !sol->iscomplex) + SetOpenGlColor (vals[trig.points[j].locpnr]); + else + glTexCoord2f ( valsc[trig.points[j].locpnr].real(), + valsc[trig.points[j].locpnr].imag() ); + + p[j] = points[trig.points[j].pnr].p; + + if (deform) + { + Point<3> ploc = points[trig.points[j].pnr].lami; + p[j] += GetDeformation (trig.elnr, ploc); + } + + glVertex3dv (p[j]); + } + + } + glEnd(); + } + glEndList (); + + +#ifdef PARALLELGL + glFinish(); + if (id > 0) + MyMPI_Send (clipplanelist_scal, 0, MPI_TAG_VIS); +#endif + } + + + + + + + + + + + void VisualSceneSolution :: + SetOpenGlColor(double val) + { + if (usetexture == 1 && !logscale) + { + glTexCoord1f ( val ); + return; + } + + double valmin = minval; + double valmax = maxval; + + double value; + + if (!logscale) + value = (val - valmin) / (valmax - valmin); + else + { + if (valmax <= 0) valmax = 1; + if (valmin <= 0) valmin = 1e-4 * valmax; + value = (log(fabs(val)) - log(valmin)) / (log(valmax) - log(valmin)); + } + + if (!invcolor) + value = 1 - value; + + + if (value > 1) value = 1; + if (value < 0) value = 0; + + value *= 4; + + static const double colp[][3] = + { + { 1, 0, 0 }, + { 1, 1, 0 }, + { 0, 1, 0 }, + { 0, 1, 1 }, + { 0, 0, 1 }, + { 1, 0, 1 }, + { 1, 0, 0 }, + }; + + int i = int(value); + double r = value - i; + + GLdouble col[3]; + for (int j = 0; j < 3; j++) + col[j] = (1-r) * colp[i][j] + r * colp[i+1][j]; + + glColor3dv (col); + } + + + + void VisualSceneSolution :: + SetTextureMode (int texturemode) const + { + switch (texturemode) + { + case 0: + glDisable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + break; + case 1: + glEnable (GL_TEXTURE_1D); + glDisable (GL_TEXTURE_2D); + glColor3d (1.0, 1.0, 1.0); + break; + case 2: + glDisable (GL_TEXTURE_1D); + glEnable (GL_TEXTURE_2D); + glColor3d (1.0, 1.0, 1.0); + break; + } + } + + + + + void VisualSceneSolution :: + DrawCone (const Point<3> & p1, const Point<3> & p2, double r) + { + int n = 10, i; + Vec<3> p1p2 = p2 - p1; + + p1p2.Normalize(); + Vec<3> p2p1 = -p1p2; + + Vec<3> t1 = p1p2.GetNormal(); + Vec<3> t2 = Cross (p1p2, t1); + + Point<3> oldp = p1 + r * t1; + Vec<3> oldn = t1; + + Point<3> p; + Vec<3> normal; + + Mat<2> rotmat; + Vec<2> cs, newcs; + cs(0) = 1; + cs(1) = 0; + rotmat(0,0) = rotmat(1,1) = cos(2*M_PI/n); + rotmat(1,0) = sin(2*M_PI/n); + rotmat(0,1) = -rotmat(1,0); + + glBegin (GL_TRIANGLES); + for (i = 1; i <= n; i++) + { + /* + phi = 2 * M_PI * i / n; + normal = cos(phi) * t1 + sin(phi) * t2; + */ + newcs = rotmat * cs; + cs = newcs; + normal = cs(0) * t1 + cs(1) * t2; + + p = p1 + r * normal; + + // cone + glNormal3dv (normal); + glVertex3dv (p); + glVertex3dv (p2); + glNormal3dv (oldn); + glVertex3dv (oldp); + + // base-circle + glNormal3dv (p2p1); + glVertex3dv (p); + glVertex3dv (p1); + glVertex3dv (oldp); + + oldp = p; + oldn = normal; + } + glEnd (); + } + + + + void VisualSceneSolution :: + DrawCylinder (const Point<3> & p1, const Point<3> & p2, double r) + { + int n = 10, i; + Vec<3> p1p2 = p2 - p1; + + p1p2.Normalize(); + // Vec<3> p2p1 = -p1p2; + + Vec<3> t1 = p1p2.GetNormal(); + Vec<3> t2 = Cross (p1p2, t1); + + Point<3> oldhp1 = p1 + r * t1; + Point<3> oldhp2 = p2 + r * t1; + Vec<3> oldn = t1; + + Point<3> hp1, hp2; + Vec<3> normal; + + Mat<2> rotmat; + Vec<2> cs, newcs; + cs(0) = 1; + cs(1) = 0; + rotmat(0,0) = rotmat(1,1) = cos(2*M_PI/n); + rotmat(1,0) = sin(2*M_PI/n); + rotmat(0,1) = -rotmat(1,0); + + glBegin (GL_QUADS); + for (i = 1; i <= n; i++) + { + newcs = rotmat * cs; + cs = newcs; + normal = cs(0) * t1 + cs(1) * t2; + + hp1 = p1 + r * normal; + hp2 = p2 + r * normal; + + // cylinder + glNormal3dv (normal); + + glVertex3dv (hp1); + glVertex3dv (hp2); + glVertex3dv (oldhp2); + glVertex3dv (oldhp1); + + oldhp1 = hp1; + oldhp2 = hp2; + oldn = normal; + } + glEnd (); + } + + + + + + + + + + + + + + void VisualSceneSolution :: MouseDblClick (int px, int py) + { + vsmesh.SetClippingPlane(); + // vsmesh.BuildFilledList(); + vsmesh.MouseDblClick(px,py); + } + + + +#ifdef PARALLELGL + + void VisualSceneSolution :: Broadcast () + { + MPI_Datatype type; + int blocklen[] = + { + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 4, 1, 1, + 1 + }; + MPI_Aint displ[] = { (char*)&usetexture - (char*)this, + (char*)&clipsolution - (char*)this, + (char*)&scalfunction - (char*)this, + (char*)&scalcomp - (char*)this, + + (char*)&vecfunction - (char*)this, + (char*)&gridsize - (char*)this, + (char*)&autoscale - (char*)this, + (char*)&logscale - (char*)this, + + (char*)&minval - (char*)this, + (char*)&maxval - (char*)this, + (char*)&numisolines - (char*)this, + (char*)&subdivisions - (char*)this, + + (char*)&evalfunc - (char*)this, + (char*)&clipplane[0] - (char*)this, + (char*)&multidimcomponent - (char*)this, + (char*)&deform - (char*)this, + + (char*)&scaledeform - (char*)this + }; + + + MPI_Datatype types[] = { + MPI_INT, MPI_INT, MPI_INT, MPI_INT, + MPI_INT, MPI_INT, MPI_INT, MPI_INT, + MPI_DOUBLE, MPI_DOUBLE, MPI_INT, MPI_INT, + MPI_INT, MPI_DOUBLE, MPI_INT, MPI_INT, + MPI_DOUBLE + }; + + MPI_Type_create_struct (17, blocklen, displ, types, &type); + MPI_Type_commit ( &type ); + + MPI_Bcast (this, 1, type, 0, MPI_COMM_WORLD); + MPI_Type_free (&type); + } + +#endif + + + int Ng_Vis_Set (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + + { + if (argc >= 2) + { + if (strcmp (argv[1], "parameters") == 0) + { + vssolution.imag_part = + atoi (Tcl_GetVar (interp, "::visoptions.imaginary", TCL_GLOBAL_ONLY)); + vssolution.usetexture = + atoi (Tcl_GetVar (interp, "::visoptions.usetexture", TCL_GLOBAL_ONLY)); + if (atoi (Tcl_GetVar (interp, "::visoptions.redrawperiodic", TCL_GLOBAL_ONLY))) + vssolution.usetexture = 2; + + vssolution.invcolor = + atoi (Tcl_GetVar (interp, "::visoptions.invcolor", TCL_GLOBAL_ONLY)); + + vssolution.clipsolution = 0; + + if (strcmp (Tcl_GetVar (interp, "::visoptions.clipsolution", TCL_GLOBAL_ONLY), + "scal") == 0) + vssolution.clipsolution = 1; + if (strcmp (Tcl_GetVar (interp, "::visoptions.clipsolution", TCL_GLOBAL_ONLY), + "vec") == 0) + vssolution.clipsolution = 2; + + tcl_const char * scalname = + Tcl_GetVar (interp, "::visoptions.scalfunction", TCL_GLOBAL_ONLY); + tcl_const char * vecname = + Tcl_GetVar (interp, "::visoptions.vecfunction", TCL_GLOBAL_ONLY); + tcl_const char * fieldlines_vecname = + Tcl_GetVar (interp, "::visoptions.fieldlinesvecfunction", TCL_GLOBAL_ONLY); + + + vssolution.scalfunction = -1; + vssolution.vecfunction = -1; + vssolution.fieldlines_vecfunction = -1; + + int pointpos; // SZ + const char * pch = strchr(scalname,':'); + pointpos = int(pch-scalname+1); + + for (int i = 0; i < vssolution.soldata.Size(); i++) + { + if ( (strlen (vssolution.soldata[i]->name) == pointpos-1) && + (strncmp (vssolution.soldata[i]->name, scalname, pointpos-1) == 0) ) + { + vssolution.scalfunction = i; + vssolution.scalcomp = atoi (scalname + pointpos); + if ( vssolution.scalcomp > vssolution.soldata[i]->components ) + vssolution.scalcomp = 1; + char newscalname[100]; + for ( int ii = 0; ii < pointpos; ii++ ) + newscalname[ii] = scalname[ii]; + newscalname[pointpos] = ':'; + sprintf (newscalname+pointpos, "%i", vssolution.scalcomp); + + if (strcmp (scalname, newscalname) != 0) + Tcl_SetVar ( interp, "::visoptions.scalfunction", newscalname, TCL_GLOBAL_ONLY ); + scalname = Tcl_GetVar (interp, "::visoptions.scalfunction", TCL_GLOBAL_ONLY); + } + if (strcmp (vssolution.soldata[i]->name, vecname) == 0) + vssolution.vecfunction = i; + + if (strcmp (vssolution.soldata[i]->name, fieldlines_vecname) == 0) + vssolution.fieldlines_vecfunction = i; + } + + if(vssolution.fieldlines_vecfunction != -1 && + vssolution.vecfunction == -1) + { + //cout << "WARNING: Setting vector function in Visualization toolbox to value from Fieldlines toolbox!" << endl; + vssolution.vecfunction = vssolution.fieldlines_vecfunction; + } + + // reset visoptions.scalfunction and visoptions.vecfunction if not avialable + if ( vssolution.scalfunction == -1 && strcmp (scalname, "none") != 0) + Tcl_SetVar ( interp, "::visoptions.scalfunction", "none", TCL_GLOBAL_ONLY ); + if ( vssolution.vecfunction == -1 && strcmp (vecname, "none") != 0) + Tcl_SetVar ( interp, "::visoptions.vecfunction", "none", TCL_GLOBAL_ONLY ); + + tcl_const char * evalname = + Tcl_GetVar (interp, "::visoptions.evaluate", TCL_GLOBAL_ONLY); + + if (strcmp(evalname, "abs") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_ABS; + if (strcmp(evalname, "abstens") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_ABS_TENSOR; + if (strcmp(evalname, "mises") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_MISES; + if (strcmp(evalname, "main") == 0) vssolution.evalfunc = VisualSceneSolution::FUNC_MAIN; + + vssolution.gridsize = + atoi (Tcl_GetVar (interp, "::visoptions.gridsize", TCL_GLOBAL_ONLY)); + + vssolution.xoffset = + atof (Tcl_GetVar (interp, "::visoptions.xoffset", TCL_GLOBAL_ONLY)); + + // cout << "x-offset:" << vssolution.xoffset << endl; + + vssolution.yoffset = + atof (Tcl_GetVar (interp, "::visoptions.yoffset", TCL_GLOBAL_ONLY)); + + vssolution.autoscale = + atoi (Tcl_GetVar (interp, "::visoptions.autoscale", TCL_GLOBAL_ONLY)); + + + /* + vssolution.linear_colors = + atoi (Tcl_GetVar (interp, "::visoptions.lineartexture", TCL_GLOBAL_ONLY)); + */ + vssolution.logscale = + atoi (Tcl_GetVar (interp, "::visoptions.logscale", TCL_GLOBAL_ONLY)); + + vssolution.mminval = + atof (Tcl_GetVar (interp, "::visoptions.mminval", TCL_GLOBAL_ONLY)); + vssolution.mmaxval = + atof (Tcl_GetVar (interp, "::visoptions.mmaxval", TCL_GLOBAL_ONLY)); + + vssolution.showclipsolution = + atoi (Tcl_GetVar (interp, "::visoptions.showclipsolution", TCL_GLOBAL_ONLY)); + vssolution.showsurfacesolution = + atoi (Tcl_GetVar (interp, "::visoptions.showsurfacesolution", TCL_GLOBAL_ONLY)); + vssolution.lineartexture = + atoi (Tcl_GetVar (interp, "::visoptions.lineartexture", TCL_GLOBAL_ONLY)); + vssolution.numtexturecols = + atoi (Tcl_GetVar (interp, "::visoptions.numtexturecols", TCL_GLOBAL_ONLY)); + + vssolution.multidimcomponent = + atoi (Tcl_GetVar (interp, "::visoptions.multidimcomponent", TCL_GLOBAL_ONLY)); + + vssolution.drawpointcurves = + atoi (Tcl_GetVar (interp, "::visoptions.drawpointcurves", TCL_GLOBAL_ONLY)); + + vssolution.draw_fieldlines = + atoi (Tcl_GetVar (interp, "::visoptions.drawfieldlines", TCL_GLOBAL_ONLY)); + vssolution.num_fieldlines = + atoi (Tcl_GetVar (interp, "::visoptions.numfieldlines", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_randomstart = + atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesrandomstart", TCL_GLOBAL_ONLY)); + + vssolution.fieldlines_reltolerance = + atof (Tcl_GetVar (interp, "::visoptions.fieldlinestolerance", TCL_GLOBAL_ONLY)); + + if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "euler") == 0) + vssolution.fieldlines_rktype = 0; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "eulercauchy") == 0) + vssolution.fieldlines_rktype = 1; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "simpson") == 0) + vssolution.fieldlines_rktype = 2; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesrktype", TCL_GLOBAL_ONLY), + "crungekutta") == 0) + vssolution.fieldlines_rktype = 3; + + + vssolution.fieldlines_rellength = + atof (Tcl_GetVar (interp, "::visoptions.fieldlineslength", TCL_GLOBAL_ONLY)); + + vssolution.fieldlines_maxpoints = + atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesmaxpoints", TCL_GLOBAL_ONLY)); + + vssolution.fieldlines_relthickness = + atof (Tcl_GetVar (interp, "::visoptions.fieldlinesthickness", TCL_GLOBAL_ONLY)); + + + vssolution.fieldlines_fixedphase = + (atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesonlyonephase", TCL_GLOBAL_ONLY)) != 0); + + if(vssolution.fieldlines_fixedphase) + vssolution.fieldlines_phase = + atof (Tcl_GetVar (interp, "::visoptions.fieldlinesphase", TCL_GLOBAL_ONLY)); + + + if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesstartarea", TCL_GLOBAL_ONLY), + "box") == 0) + vssolution.fieldlines_startarea = 0; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesstartarea", TCL_GLOBAL_ONLY), + "file") == 0) + vssolution.fieldlines_startarea = 1; + else if (strcmp (Tcl_GetVar (interp, "::visoptions.fieldlinesstartarea", TCL_GLOBAL_ONLY), + "face") == 0) + vssolution.fieldlines_startarea = 2; + + + if (vssolution.fieldlines_startarea == 0) + { + vssolution.fieldlines_startarea_parameter.SetSize(6); + vssolution.fieldlines_startarea_parameter[0] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap1x", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[1] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap1y", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[2] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap1z", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[3] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap2x", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[4] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap2y", TCL_GLOBAL_ONLY)); + vssolution.fieldlines_startarea_parameter[5] = atof (Tcl_GetVar (interp, "::visoptions.fieldlinesstartareap2z", TCL_GLOBAL_ONLY)); + } + else if (vssolution.fieldlines_startarea == 1) + { + vssolution.fieldlines_filename = Tcl_GetVar (interp, "::visoptions.fieldlinesfilename", TCL_GLOBAL_ONLY); + } + else if (vssolution.fieldlines_startarea == 2) + { + vssolution.fieldlines_startface = atoi (Tcl_GetVar (interp, "::visoptions.fieldlinesstartface", TCL_GLOBAL_ONLY)); + } + + + vssolution.deform = + atoi (Tcl_GetVar (interp, "::visoptions.deformation", TCL_GLOBAL_ONLY)); + vssolution.scaledeform = + atof (Tcl_GetVar (interp, "::visoptions.scaledeform1", TCL_GLOBAL_ONLY)) * + atof (Tcl_GetVar (interp, "::visoptions.scaledeform2", TCL_GLOBAL_ONLY)); + + + if (atoi (Tcl_GetVar (interp, "::visoptions.isolines", TCL_GLOBAL_ONLY))) + vssolution.numisolines = atoi (Tcl_GetVar (interp, "::visoptions.numiso", TCL_GLOBAL_ONLY)); + else + vssolution.numisolines = 0; + vssolution.draw_isosurface = + atoi (Tcl_GetVar (interp, "::visoptions.isosurf", TCL_GLOBAL_ONLY)); + + vssolution.SetSubdivision(atoi (Tcl_GetVar (interp, "::visoptions.subdivisions", TCL_GLOBAL_ONLY))); + + vssolution.UpdateSolutionTimeStamp(); + } + + if (strcmp (argv[1], "parametersrange") == 0) + { + vssolution.invcolor = + atoi (Tcl_GetVar (interp, "::visoptions.invcolor", TCL_GLOBAL_ONLY)); + vssolution.mminval = + atof (Tcl_GetVar (interp, "::visoptions.mminval", TCL_GLOBAL_ONLY)); + vssolution.mmaxval = + atof (Tcl_GetVar (interp, "::visoptions.mmaxval", TCL_GLOBAL_ONLY)); + vssolution.lineartexture = + atoi (Tcl_GetVar (interp, "::visoptions.lineartexture", TCL_GLOBAL_ONLY)); + vssolution.numtexturecols = + atoi (Tcl_GetVar (interp, "::visoptions.numtexturecols", TCL_GLOBAL_ONLY)); + + if (vssolution.usetexture == 0 || vssolution.logscale) + vssolution.UpdateSolutionTimeStamp(); + } + + + if (argc >= 3 && strcmp (argv[1], "time") == 0) + { + vssolution.time = double (atoi (argv[2])) / 1000; + + vssolution.timetimestamp = NextTimeStamp(); + cout << "\rtime = " << vssolution.time << " " << flush; + } + + } + + + vsmesh.SetClippingPlane (); // for computing parameters + vssolution.SetClippingPlane (); // for computing parameters + glDisable(GL_CLIP_PLANE0); + +#ifdef PARALLELGL + vsmesh.Broadcast (); +#endif + + + return TCL_OK; + } + + int Ng_Vis_Field (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int i; + char buf[1000]; + buf[0] = 0; + + if (argc >= 2) + { + if (strcmp (argv[1], "setfield") == 0) + { + if (argc < 3) + return TCL_ERROR; + + for (i = 0; i < vssolution.GetNSolData(); i++) + if (strcmp (vssolution.GetSolData(i)->name, argv[2]) == 0) + { + cout << "found soldata " << i << endl; + } + } + + if (strcmp (argv[1], "getnfieldnames") == 0) + { + sprintf (buf, "%d", vssolution.GetNSolData()); + } + + if (strcmp (argv[1], "getfieldname") == 0) + { + sprintf (buf, "%s", vssolution.GetSolData(atoi(argv[2])-1)->name); + } + + if (strcmp (argv[1], "iscomplex") == 0) + { + sprintf (buf, "%d", vssolution.GetSolData(atoi(argv[2])-1)->iscomplex); + } + + if (strcmp (argv[1], "getfieldcomponents") == 0) + { + sprintf (buf, "%d", vssolution.GetSolData(atoi(argv[2])-1)->components); + } + + + if (strcmp (argv[1], "getfieldnames") == 0) + { + for (i = 0; i < vssolution.GetNSolData(); i++) + { + strcat (buf, vssolution.GetSolData(i)->name); + strcat (buf, " "); + } + strcat (buf, "var1 var2 var3"); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + if (strcmp (argv[1], "setcomponent") == 0) + { + cout << "set component " << argv[2] << endl; + } + + if (strcmp (argv[1], "getactivefield") == 0) + { + sprintf (buf, "1"); + } + + if (strcmp (argv[1], "getdimension") == 0) + { + sprintf (buf, "%d", mesh->GetDimension()); + } + } + + Tcl_SetResult (interp, buf, TCL_STATIC); + return TCL_OK; + } + + + extern "C" int Ng_Vis_Init (Tcl_Interp * interp); + + int Ng_Vis_Init (Tcl_Interp * interp) + { + Tcl_CreateCommand (interp, "Ng_Vis_Set", Ng_Vis_Set, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Vis_Field", Ng_Vis_Field, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + return TCL_OK; + } +} + +#endif // NOTCL diff --git a/libsrc/visualization/vssolution.hpp b/libsrc/visualization/vssolution.hpp new file mode 100644 index 00000000..067446ae --- /dev/null +++ b/libsrc/visualization/vssolution.hpp @@ -0,0 +1,436 @@ +#ifndef FILE_VSSOLUTION +#define FILE_VSSOLUTION + + + +#ifndef SMALLLIB +#ifndef NOTCL + +extern +void ImportSolution (const char * filename); + +extern int Ng_Vis_Set (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); +#endif +#endif + +class FieldLineCalc; + +class VisualSceneSolution : public VisualScene +{ + friend class FieldLineCalc; + + class ClipPlaneTrig + { + public: + struct ps + { + int pnr, locpnr; + }; + ps points[3]; + ElementIndex elnr; + }; + + class ClipPlanePoint + { + public: + ElementIndex elnr; + Point<3> lami; + Point<3> p; + }; + + + int surfellist; + int linelist; + int element1dlist; + int clipplanelist_scal; + int clipplanelist_vec; + int isolinelist; + int clipplane_isolinelist; + int surface_vector_list; + // int cone_list; + int isosurface_list; + + int pointcurvelist; + + bool draw_fieldlines; + bool drawpointcurves; + bool draw_isosurface; + int num_fieldlines; + bool fieldlines_randomstart; + int fieldlineslist; + int num_fieldlineslists; + int fieldlines_startarea; + Array fieldlines_startarea_parameter; + int fieldlines_startface; + string fieldlines_filename; + double fieldlines_reltolerance; + int fieldlines_rktype; + double fieldlines_rellength; + double fieldlines_relthickness; + int fieldlines_vecfunction; + bool fieldlines_fixedphase; + float fieldlines_phase; + int fieldlines_maxpoints; + + + int surfeltimestamp, clipplanetimestamp, solutiontimestamp; + int surfellinetimestamp; + int fieldlinestimestamp, surface_vector_timestamp; + int pointcurve_timestamp; + int isosurface_timestamp; + int subdivision_timestamp; + int timetimestamp; + double minval, maxval; + + NgLock *lock; + + +#ifdef PARALLELGL + Array par_linelists; + Array par_surfellists; +#endif + + +public: + + enum EvalFunc { + FUNC_ABS = 1, + FUNC_ABS_TENSOR = 2, + FUNC_MISES = 3, + FUNC_MAIN = 4 + }; + int evalfunc; + + enum SolType + { + SOL_NODAL = 1, + SOL_ELEMENT = 2, + SOL_SURFACE_ELEMENT = 3, + SOL_NONCONTINUOUS = 4, + SOL_SURFACE_NONCONTINUOUS = 5, + SOL_VIRTUALFUNCTION = 6, + SOL_MARKED_ELEMENTS = 10, + SOL_ELEMENT_ORDER = 11, + }; + + class SolData + { + public: + SolData (); + ~SolData (); + + char * name; + double * data; + int components; + int dist; + int order; + bool iscomplex; + bool draw_volume; + bool draw_surface; + SolType soltype; + SolutionData * solclass; + + // internal variables: + int size; + }; + + + + + Array soldata; + + + int usetexture; // 0..no, 1..1D texture (standard), 2..2D-texture (complex) + int clipsolution; // 0..no, 1..scal, 2..vec + int scalfunction, scalcomp, vecfunction; + int gridsize; + double xoffset, yoffset; + + int autoscale, logscale; + double mminval, mmaxval; + int numisolines; + int subdivisions; + + bool showclipsolution; + bool showsurfacesolution; + bool lineartexture; + int numtexturecols; + + int multidimcomponent; + + // bool fieldlineplot; + double time; + + int deform; + double scaledeform; + bool imag_part; + +private: + void BuildFieldLinesFromFile(Array & startpoints); + void BuildFieldLinesFromFace(Array & startpoints); + void BuildFieldLinesFromBox(Array & startpoints); + void BuildFieldLinesFromLine(Array & startpoints); + +public: + VisualSceneSolution (); + virtual ~VisualSceneSolution (); + + virtual void BuildScene (int zoomall = 0); + virtual void DrawScene (); + virtual void MouseDblClick (int px, int py); + + void BuildFieldLinesPlot (); + + void AddSolutionData (SolData * soldata); + void ClearSolutionData (); + void UpdateSolutionTimeStamp (); + SolData * GetSolData (int i); + int GetNSolData () { return soldata.Size(); } + + void SaveSolutionData (const char * filename); + + /* + static void RealVec3d (const double * values, Vec3d & v, + bool iscomplex, bool imag); + */ + static Vec<3> RealVec3d (const double * values, + bool iscomplex, bool imag); + + static void RealVec3d (const double * values, Vec3d & v, + bool iscomplex, double phaser, double phasei); + + + void SetSubdivision (int sd) + { + subdivisions = sd; + subdivision_timestamp = solutiontimestamp = NextTimeStamp(); + } + + void GetMinMax (int funcnr, int comp, double & minv, double & maxv) const; + +private: + void GetClippingPlaneTrigs (Array & trigs, Array & pts); + void GetClippingPlaneGrid (Array & pts); + void DrawCone (const Point<3> & p1, const Point<3> & p2, double r); + void DrawCylinder (const Point<3> & p1, const Point<3> & p2, double r); + + + // Get Function Value, local coordinates lam1, lam2, lam3, + bool GetValue (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + int comp, double & val) const; + + bool GetValue (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const; + + bool GetValueComplex (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + int comp, complex & val) const; + + bool GetValues (const SolData * data, ElementIndex elnr, + double lam1, double lam2, double lam3, + double * values) const; + + bool GetValues (const SolData * data, ElementIndex elnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const; + + bool GetMultiValues (const SolData * data, ElementIndex elnr, int facetnr, int npt, + const double * xref, int sxref, + const double * x, int sx, + const double * dxdxref, int sdxdxref, + double * val, int sval) const; + + + bool GetSurfValue (const SolData * data, SurfaceElementIndex elnr, int facetnr, + double lam1, double lam2, + int comp, double & val) const; + + bool GetSurfValue (const SolData * data, SurfaceElementIndex elnr, int facetnr, + const double xref[], const double x[], const double dxdxref[], + int comp, double & val) const; + + + bool GetSurfValueComplex (const SolData * data, SurfaceElementIndex elnr, int facetnr, + double lam1, double lam2, + int comp, complex & val) const; + + bool GetSurfValues (const SolData * data, SurfaceElementIndex elnr, int facetnr, + double lam1, double lam2, + double * values) const; + + bool GetSurfValues (const SolData * data, SurfaceElementIndex elnr, int facetnr, + const double xref[], const double x[], const double dxdxref[], + double * values) const; + + bool GetMultiSurfValues (const SolData * data, SurfaceElementIndex elnr, int facetnr, + int npt, + const double * xref, int sxref, + const double * x, int sx, + const double * dxdxref, int sdxdxref, + double * val, int sval) const; + + double ExtractValue (const SolData * data, int comp, double * values) const; + complex ExtractValueComplex (const SolData * data, int comp, double * values) const; + + + Vec<3> GetDeformation (ElementIndex elnr, const Point<3> & p) const; + Vec<3> GetSurfDeformation (SurfaceElementIndex selnr, int facetnr, double lam1, double lam2) const; + + void GetPointDeformation (int pnum, Point<3> & p, SurfaceElementIndex elnr = -1) const; + +public: + /// draw elements (build lists) + void DrawSurfaceElements (); + void DrawSurfaceElementLines (); + void Draw1DElements(); + + void DrawSurfaceVectors (); + void DrawTrigSurfaceVectors(const Array< Point<3> > & lp, const Point<3> & pmin, const Point<3> & pmax, + const int sei, const SolData * vsol); + void DrawIsoSurface(const SolData * sol, const SolData * grad, int comp); + + void DrawIsoLines (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + double val1, double val2, double val3); + + // draw isolines between lines (p1,p2) and (p3,p4) + void DrawIsoLines2 (const Point<3> & p1, + const Point<3> & p2, + const Point<3> & p3, + const Point<3> & p4, + double val1, double val2, double val3, double val4); + + + void DrawClipPlaneTrigs (); // const SolData * sol, int comp); + + void SetOpenGlColor(double val); + + // 0 .. non, 1 .. scalar, 2 .. complex + void SetTextureMode (int texturemode) const; + +#ifndef SMALLLIB +#ifndef NOTCL + + friend int Ng_Vis_Set (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); + +#endif +#endif + + +#ifdef PARALLELGL + void Broadcast (); +#endif + + +}; + + + + +class RKStepper +{ +private: + Array c,b; + TABLE *a; + int steps; + int order; + + double tolerance; + + Array K; + + int stepcount; + + double h; + double startt; + double startt_bak; + Point3d startval; + Point3d startval_bak; + + bool adaptive; + int adrun; + Point3d valh; + + int notrestarted; + +public: + + ~RKStepper(); + + RKStepper(int type = 0); + + void SetTolerance(const double tol){tolerance = tol;} + + void StartNextValCalc(const Point3d & astartval, const double astartt, const double ah, const bool aadaptive = false); + + bool GetNextData(Point3d & val, double & t, double & ah); + + bool FeedNextF(const Vec3d & f); +}; + + + + + +class FieldLineCalc +{ +private: + const Mesh & mesh; + + VisualSceneSolution & vss; + + const VisualSceneSolution::SolData * vsol; + + RKStepper stepper; + + double maxlength; + + int maxpoints; + + int direction; + + Point3d pmin, pmax; + double rad; + double phaser, phasei; + + double critical_value; + + bool randomized; + + double thickness; + +public: + FieldLineCalc(const Mesh & amesh, VisualSceneSolution & avss, const VisualSceneSolution::SolData * solution, + const double rel_length, const int amaxpoints = -1, + const double rel_thickness = -1, const double rel_tolerance = -1, const int rk_type = 0, const int adirection = 0); + + void SetPhase(const double real, const double imag) { phaser = real; phasei = imag; } + + void SetCriticalValue(const double val) { critical_value = val; } + + void Randomized(void) { randomized = true; } + void NotRandomized(void) { randomized = false; } + + void Calc(const Point3d & startpoint, Array & points, Array & vals, Array & drawelems, Array & dirstart); + + void GenerateFieldLines(Array & potential_startpoints, const int numlines, const int gllist, + const double minval, const double maxval, const int logscale, double phaser, double phasei); +}; + + + + +extern VisualSceneSolution vssolution; + + + + +#endif + diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 00000000..c2852d85 --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,9661 @@ + +# libtool (GNU libtool) 2.4.2 +# Written by Gordon Matzigkeit , 1996 + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, +# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Usage: $progname [OPTION]... [MODE-ARG]... +# +# Provide generalized library-building support services. +# +# --config show all configuration variables +# --debug enable verbose shell tracing +# -n, --dry-run display commands without modifying any files +# --features display basic configuration information and exit +# --mode=MODE use operation mode MODE +# --preserve-dup-deps don't remove duplicate dependency libraries +# --quiet, --silent don't print informational messages +# --no-quiet, --no-silent +# print informational messages (default) +# --no-warn don't display warning messages +# --tag=TAG use configuration variables from tag TAG +# -v, --verbose print more informational messages than default +# --no-verbose don't print the extra informational messages +# --version print version information +# -h, --help, --help-all print short, long, or detailed help message +# +# MODE must be one of the following: +# +# clean remove files from the build directory +# compile compile a source file into a libtool object +# execute automatically set library path, then run a program +# finish complete the installation of libtool libraries +# install install libraries or executables +# link create a library or an executable +# uninstall remove libraries from an installed directory +# +# MODE-ARGS vary depending on the MODE. When passed as first option, +# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. +# Try `$progname --help --mode=MODE' for a more detailed description of MODE. +# +# When reporting a bug, please describe a test case to reproduce it and +# include the following information: +# +# host-triplet: $host +# shell: $SHELL +# compiler: $LTCC +# compiler flags: $LTCFLAGS +# linker: $LD (gnu? $with_gnu_ld) +# $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 +# automake: $automake_version +# autoconf: $autoconf_version +# +# Report bugs to . +# GNU libtool home page: . +# General help using GNU software: . + +PROGRAM=libtool +PACKAGE=libtool +VERSION="2.4.2 Debian-2.4.2-1ubuntu1" +TIMESTAMP="" +package_revision=1.3337 + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# NLS nuisances: We save the old values to restore during execute mode. +lt_user_locale= +lt_safe_locale= +for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test \"\${$lt_var+set}\" = set; then + save_$lt_var=\$$lt_var + $lt_var=C + export $lt_var + lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" + lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + fi" +done +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL + +$lt_unset CDPATH + + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath="$0" + + + +: ${CP="cp -f"} +test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} +: ${Xsed="$SED -e 1s/^X//"} + +# Global variables: +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +exit_status=$EXIT_SUCCESS + +# Make sure IFS has a sensible default +lt_nl=' +' +IFS=" $lt_nl" + +dirname="s,/[^/]*$,," +basename="s,^.*/,," + +# func_dirname file append nondir_replacement +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +func_dirname () +{ + func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi +} # func_dirname may be replaced by extended shell implementation + + +# func_basename file +func_basename () +{ + func_basename_result=`$ECHO "${1}" | $SED "$basename"` +} # func_basename may be replaced by extended shell implementation + + +# func_dirname_and_basename file append nondir_replacement +# perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# Implementation must be kept synchronized with func_dirname +# and func_basename. For efficiency, we do not delegate to +# those functions but instead duplicate the functionality here. +func_dirname_and_basename () +{ + # Extract subdirectory from the argument. + func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` + if test "X$func_dirname_result" = "X${1}"; then + func_dirname_result="${3}" + else + func_dirname_result="$func_dirname_result${2}" + fi + func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` +} # func_dirname_and_basename may be replaced by extended shell implementation + + +# func_stripname prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# func_strip_suffix prefix name +func_stripname () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname may be replaced by extended shell implementation + + +# These SED scripts presuppose an absolute path with a trailing slash. +pathcar='s,^/\([^/]*\).*$,\1,' +pathcdr='s,^/[^/]*,,' +removedotparts=':dotsl + s@/\./@/@g + t dotsl + s,/\.$,/,' +collapseslashes='s@/\{1,\}@/@g' +finalslash='s,/*$,/,' + +# func_normal_abspath PATH +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +# value returned in "$func_normal_abspath_result" +func_normal_abspath () +{ + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` + while :; do + # Processed it all yet? + if test "$func_normal_abspath_tpath" = / ; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result" ; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + +# func_relative_path SRCDIR DSTDIR +# generates a relative path from SRCDIR to DSTDIR, with a trailing +# slash if non-empty, suitable for immediately appending a filename +# without needing to append a separator. +# value returned in "$func_relative_path_result" +func_relative_path () +{ + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=${func_dirname_result} + if test "x$func_relative_path_tlibdir" = x ; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test "x$func_stripname_result" != x ; then + func_relative_path_result=${func_relative_path_result}/${func_stripname_result} + fi + + # Normalisation. If bindir is libdir, return empty string, + # else relative path ending with a slash; either way, target + # file name can be directly appended. + if test ! -z "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result/" + func_relative_path_result=$func_stripname_result + fi +} + +# The name of this program: +func_dirname_and_basename "$progpath" +progname=$func_basename_result + +# Make sure we have an absolute path for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=$func_dirname_result + progdir=`cd "$progdir" && pwd` + progpath="$progdir/$progname" + ;; + *) + save_IFS="$IFS" + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS="$save_IFS" + test -x "$progdir/$progname" && break + done + IFS="$save_IFS" + test -n "$progdir" || progdir=`pwd` + progpath="$progdir/$progname" + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed="${SED}"' -e 1s/^X//' +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' + +# Sed substitution that converts a w32 file name or path +# which contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-`\' parameter expansions in output of double_quote_subst that were +# `\'-ed in input to the same. If an odd number of `\' preceded a '$' +# in input to double_quote_subst, that '$' was protected from expansion. +# Since each input `\' is now two `\'s, look for any number of runs of +# four `\'s followed by two `\'s and then a '$'. `\' that '$'. +bs='\\' +bs2='\\\\' +bs4='\\\\\\\\' +dollar='\$' +sed_double_backslash="\ + s/$bs4/&\\ +/g + s/^$bs2$dollar/$bs&/ + s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g + s/\n//g" + +# Standard options: +opt_dry_run=false +opt_help=false +opt_quiet=false +opt_verbose=false +opt_warning=: + +# func_echo arg... +# Echo program name prefixed message, along with the current mode +# name if it has been set yet. +func_echo () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }$*" +} + +# func_verbose arg... +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $opt_verbose && func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +# func_error arg... +# Echo program name prefixed message to standard error. +func_error () +{ + $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 +} + +# func_warning arg... +# Echo program name prefixed warning message to standard error. +func_warning () +{ + $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + + # bash bug again: + : +} + +# func_fatal_error arg... +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + +# func_fatal_help arg... +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + func_error ${1+"$@"} + func_fatal_error "$help" +} +help="Try \`$progname --help' for more information." ## default + + +# func_grep expression filename +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_mkdir_p directory-path +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + my_directory_path="$1" + my_dir_list= + + if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then + + # Protect directory names starting with `-' + case $my_directory_path in + -*) my_directory_path="./$my_directory_path" ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$my_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + my_dir_list="$my_directory_path:$my_dir_list" + + # If the last portion added has no slash in it, the list is done + case $my_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` + done + my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` + + save_mkdir_p_IFS="$IFS"; IFS=':' + for my_dir in $my_dir_list; do + IFS="$save_mkdir_p_IFS" + # mkdir can fail with a `File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$my_dir" 2>/dev/null || : + done + IFS="$save_mkdir_p_IFS" + + # Bail out if we (or some other process) failed to create a directory. + test -d "$my_directory_path" || \ + func_fatal_error "Failed to create \`$1'" + fi +} + + +# func_mktempdir [string] +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, STRING is the basename for that directory. +func_mktempdir () +{ + my_template="${TMPDIR-/tmp}/${1-$progname}" + + if test "$opt_dry_run" = ":"; then + # Return a directory name, but don't create it in dry-run mode + my_tmpdir="${my_template}-$$" + else + + # If mktemp works, use that first and foremost + my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` + + if test ! -d "$my_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + my_tmpdir="${my_template}-${RANDOM-0}$$" + + save_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$my_tmpdir" + umask $save_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$my_tmpdir" || \ + func_fatal_error "cannot create temporary directory \`$my_tmpdir'" + fi + + $ECHO "$my_tmpdir" +} + + +# func_quote_for_eval arg +# Aesthetically quote ARG to be evaled later. +# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT +# is double-quoted, suitable for a subsequent eval, whereas +# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters +# which are still active within double quotes backslashified. +func_quote_for_eval () +{ + case $1 in + *[\\\`\"\$]*) + func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; + *) + func_quote_for_eval_unquoted_result="$1" ;; + esac + + case $func_quote_for_eval_unquoted_result in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and and variable + # expansion for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" + ;; + *) + func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" + esac +} + + +# func_quote_for_expand arg +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + case $1 in + *[\\\`\"]*) + my_arg=`$ECHO "$1" | $SED \ + -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + *) + my_arg="$1" ;; + esac + + case $my_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + my_arg="\"$my_arg\"" + ;; + esac + + func_quote_for_expand_result="$my_arg" +} + + +# func_show_eval cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$my_cmd" + my_status=$? + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + + +# func_show_eval_locale cmd [fail_exp] +# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + my_cmd="$1" + my_fail_exp="${2-:}" + + ${opt_silent-false} || { + func_quote_for_expand "$my_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + if ${opt_dry_run-false}; then :; else + eval "$lt_user_locale + $my_cmd" + my_status=$? + eval "$lt_safe_locale" + if test "$my_status" -eq 0; then :; else + eval "(exit $my_status); $my_fail_exp" + fi + fi +} + +# func_tr_sh +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_version +# Echo version message to standard output and exit. +func_version () +{ + $opt_debug + + $SED -n '/(C)/!b go + :more + /\./!{ + N + s/\n# / / + b more + } + :go + /^# '$PROGRAM' (GNU /,/# warranty; / { + s/^# // + s/^# *$// + s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ + p + }' < "$progpath" + exit $? +} + +# func_usage +# Echo short help message to standard output and exit. +func_usage () +{ + $opt_debug + + $SED -n '/^# Usage:/,/^# *.*--help/ { + s/^# // + s/^# *$// + s/\$progname/'$progname'/ + p + }' < "$progpath" + echo + $ECHO "run \`$progname --help | more' for full usage" + exit $? +} + +# func_help [NOEXIT] +# Echo long help message to standard output and exit, +# unless 'noexit' is passed as argument. +func_help () +{ + $opt_debug + + $SED -n '/^# Usage:/,/# Report bugs to/ { + :print + s/^# // + s/^# *$// + s*\$progname*'$progname'* + s*\$host*'"$host"'* + s*\$SHELL*'"$SHELL"'* + s*\$LTCC*'"$LTCC"'* + s*\$LTCFLAGS*'"$LTCFLAGS"'* + s*\$LD*'"$LD"'* + s/\$with_gnu_ld/'"$with_gnu_ld"'/ + s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ + s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ + p + d + } + /^# .* home page:/b print + /^# General help using/b print + ' < "$progpath" + ret=$? + if test -z "$1"; then + exit $ret + fi +} + +# func_missing_arg argname +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $opt_debug + + func_error "missing argument for $1." + exit_cmd=exit +} + + +# func_split_short_opt shortopt +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +func_split_short_opt () +{ + my_sed_short_opt='1s/^\(..\).*$/\1/;q' + my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + + func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` + func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` +} # func_split_short_opt may be replaced by extended shell implementation + + +# func_split_long_opt longopt +# Set func_split_long_opt_name and func_split_long_opt_arg shell +# variables after splitting LONGOPT at the `=' sign. +func_split_long_opt () +{ + my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' + my_sed_long_arg='1s/^--[^=]*=//' + + func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` + func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` +} # func_split_long_opt may be replaced by extended shell implementation + +exit_cmd=: + + + + + +magic="%%%MAGIC variable%%%" +magic_exe="%%%MAGIC EXE variable%%%" + +# Global variables. +nonopt= +preserve_args= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + +# func_append var value +# Append VALUE to the end of shell variable VAR. +func_append () +{ + eval "${1}=\$${1}\${2}" +} # func_append may be replaced by extended shell implementation + +# func_append_quoted var value +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +func_append_quoted () +{ + func_quote_for_eval "${2}" + eval "${1}=\$${1}\\ \$func_quote_for_eval_result" +} # func_append_quoted may be replaced by extended shell implementation + + +# func_arith arithmetic-term... +func_arith () +{ + func_arith_result=`expr "${@}"` +} # func_arith may be replaced by extended shell implementation + + +# func_len string +# STRING may not start with a hyphen. +func_len () +{ + func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` +} # func_len may be replaced by extended shell implementation + + +# func_lo2o object +func_lo2o () +{ + func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` +} # func_lo2o may be replaced by extended shell implementation + + +# func_xform libobj-or-source +func_xform () +{ + func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` +} # func_xform may be replaced by extended shell implementation + + +# func_fatal_configuration arg... +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func_error ${1+"$@"} + func_error "See the $PACKAGE documentation for more information." + func_fatal_error "Fatal configuration error." +} + + +# func_config +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + +# func_features +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + +# func_enable_tag tagname +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname="$1" + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf="/$re_begincf/,/$re_endcf/p" + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + +# func_check_version_match +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# Shorthand for --mode=foo, only valid as the first argument +case $1 in +clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; +compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; +execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; +finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; +install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; +link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; +uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; +esac + + + +# Option defaults: +opt_debug=: +opt_dry_run=false +opt_config=false +opt_preserve_dup_deps=false +opt_features=false +opt_finish=false +opt_help=false +opt_help_all=false +opt_silent=: +opt_warning=: +opt_verbose=: +opt_silent=false +opt_verbose=false + + +# Parse options once, thoroughly. This comes as soon as possible in the +# script to make things like `--version' happen as quickly as we can. +{ + # this just eases exit handling + while test $# -gt 0; do + opt="$1" + shift + case $opt in + --debug|-x) opt_debug='set -x' + func_echo "enabling shell trace mode" + $opt_debug + ;; + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + --config) + opt_config=: +func_config + ;; + --dlopen|-dlopen) + optarg="$1" + opt_dlopen="${opt_dlopen+$opt_dlopen +}$optarg" + shift + ;; + --preserve-dup-deps) + opt_preserve_dup_deps=: + ;; + --features) + opt_features=: +func_features + ;; + --finish) + opt_finish=: +set dummy --mode finish ${1+"$@"}; shift + ;; + --help) + opt_help=: + ;; + --help-all) + opt_help_all=: +opt_help=': help-all' + ;; + --mode) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_mode="$optarg" +case $optarg in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $opt" + exit_cmd=exit + break + ;; +esac + shift + ;; + --no-silent|--no-quiet) + opt_silent=false +func_append preserve_args " $opt" + ;; + --no-warning|--no-warn) + opt_warning=false +func_append preserve_args " $opt" + ;; + --no-verbose) + opt_verbose=false +func_append preserve_args " $opt" + ;; + --silent|--quiet) + opt_silent=: +func_append preserve_args " $opt" + opt_verbose=false + ;; + --verbose|-v) + opt_verbose=: +func_append preserve_args " $opt" +opt_silent=false + ;; + --tag) + test $# = 0 && func_missing_arg $opt && break + optarg="$1" + opt_tag="$optarg" +func_append preserve_args " $opt $optarg" +func_enable_tag "$optarg" + shift + ;; + + -\?|-h) func_usage ;; + --help) func_help ;; + --version) func_version ;; + + # Separate optargs to long options: + --*=*) + func_split_long_opt "$opt" + set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-n*|-v*) + func_split_short_opt "$opt" + set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognized option \`$opt'" ;; + *) set dummy "$opt" ${1+"$@"}; shift; break ;; + esac + done + + # Validate options: + + # save first non-option argument + if test "$#" -gt 0; then + nonopt="$opt" + shift + fi + + # preserve --debug + test "$opt_debug" = : || func_append preserve_args " --debug" + + case $host in + *cygwin* | *mingw* | *pw32* | *cegcc*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + func_fatal_configuration "not configured to build any kind of library" + fi + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test "$opt_mode" != execute; then + func_error "unrecognized option \`-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$progname --help --mode=$opt_mode' for more information." + } + + + # Bail if the options were screwed + $exit_cmd $EXIT_FAILURE +} + + + + +## ----------- ## +## Main. ## +## ----------- ## + +# func_lalib_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null \ + | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool `.la' library or `.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if `file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case "$lalib_p_line" in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test "$lalib_p" = yes +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + func_lalib_p "$1" +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $opt_debug + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$save_ifs + eval cmd=\"$cmd\" + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# `FILE.' does not work on cygwin managed mounts. +func_source () +{ + $opt_debug + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case "$lt_sysroot:$1" in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result="=$func_stripname_result" + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $opt_debug + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with \`--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=${1} + if test "$build_libtool_libs" = yes; then + write_lobj=\'${2}\' + else + write_lobj=none + fi + + if test "$build_old_libs" = yes; then + write_oldobj=\'${3}\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T </dev/null` + if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$lt_sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $opt_debug + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result="" + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $opt_debug + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $opt_debug + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $opt_debug + if test -z "$2" && test -n "$1" ; then + func_error "Could not determine host file name corresponding to" + func_error " \`$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result="$1" + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $opt_debug + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " \`$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result="$3" + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $opt_debug + case $4 in + $1 ) func_to_host_path_result="$3$func_to_host_path_result" + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via `$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $opt_debug + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $opt_debug + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result="$1" +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result="$func_convert_core_msys_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $opt_debug + func_to_host_file_result="$1" + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result="$func_cygpath_result" + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via `$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $opt_debug + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd="func_convert_path_${func_stripname_result}" + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $opt_debug + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result="$1" +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $opt_debug + func_to_host_path_result="$1" + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result="$func_cygpath_result" + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_mode_compile arg... +func_mode_compile () +{ + $opt_debug + # Get the compilation command and the source file. + base_compile= + srcfile="$nonopt" # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg="$arg" + arg_mode=normal + ;; + + target ) + libobj="$arg" + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify \`-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs="$IFS"; IFS=',' + for arg in $args; do + IFS="$save_ifs" + func_append_quoted lastarg "$arg" + done + IFS="$save_ifs" + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg="$srcfile" + srcfile="$arg" + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with \`-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj="$func_basename_result" + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from \`$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name \`$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname="$func_basename_result" + xdir="$func_dirname_result" + lobj=${xdir}$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} + lockfile="$output_obj.lock" + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test "$pic_mode" != no; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test "$suppress_opt" = yes; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + if test "$pic_mode" != yes; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test "$compiler_c_o" = yes; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test "$need_locks" = warn && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test "$opt_mode" = compile && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a \`.o' file suitable for static linking + -static only build a \`.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + + execute) + $ECHO \ +"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + + finish) + $ECHO \ +"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + + install) + $ECHO \ +"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE Use a list of object files found in FILE to specify objects + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + + *) + func_fatal_help "invalid operation mode \`$opt_mode'" + ;; + esac + + echo + $ECHO "Try \`$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test "$opt_help" = :; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | sed -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + sed '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $opt_debug + # The first argument is the command name. + cmd="$nonopt" + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "\`$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "\`$file' was not linked with \`-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir="$func_dirname_result" + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir="$func_dirname_result" + ;; + + *) + func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case $file in + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file="$progdir/$program" + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if test "X$opt_dry_run" = Xfalse; then + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd="\$cmd$args" + else + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = execute && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $opt_debug + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "\`$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument \`$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_silent && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + $ECHO " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + + echo "See any operating system documentation about shared libraries for" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test "$opt_mode" = finish && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $opt_debug + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac; then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=yes ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test "x$prev" = x-m && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the \`$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir="$func_dirname_result" + destname="$func_basename_result" + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "\`$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "\`$destdir' must be an absolute directory name" + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case $file in + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "\`$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir="$func_dirname_result" + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking \`$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname="$1" + shift + + srcname="$realname" + test -n "$relink_command" && srcname="$realname"T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme="$stripme" + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme="" + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try `ln -sf' first, because the `ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name="$func_basename_result" + instname="$dir/$name"i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append staticlibs " $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest="$destfile" + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to \`$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + func_basename "$file" + destfile="$func_basename_result" + destfile="$destdir/$destfile" + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext="" + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=".exe" + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script \`$wrapper'" + + finalize=yes + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "\`$lib' has not been installed in \`$libdir'" + finalize=no + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + $opt_dry_run || { + if test "$finalize" = yes; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file="$func_basename_result" + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_silent || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink \`$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file="$outputname" + else + func_warning "cannot relink \`$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name="$func_basename_result" + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run \`$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test "$opt_mode" = install && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $opt_debug + my_outputname="$1" + my_originator="$2" + my_pic_p="${3-no}" + my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms="${my_outputname}S.c" + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${my_outputname}.nm" + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + func_verbose "generating symbol list for \`$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$outputname.exp" + $opt_dry_run || { + $RM $export_symbols + eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from \`$dlprefile'" + func_basename "$dlprefile" + name="$func_basename_result" + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename="" + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname" ; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename="$func_basename_result" + else + # no lafile. user explicitly requested -dlpreopen . + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename" ; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 /dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[]; +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{\ + { \"$my_originator\", (void *) 0 }," + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + if test "X$my_pic_p" != Xno; then + pic_flag_for_symtable=" $pic_flag" + fi + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + + # Transform the symbol file into the correct name. + symfileobj="$output_objdir/${my_outputname}S.$objext" + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for \`$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $opt_debug + win32_libid_type="unknown" + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s,.*,import, + p + q + } + }'` + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $opt_debug + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $opt_debug + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive which possess that section. Heuristic: eliminate + # all those which have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $opt_debug + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $opt_debug + if func_cygming_gnu_implib_p "$1" ; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1" ; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result="" + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $opt_debug + f_ex_an_ar_dir="$1"; shift + f_ex_an_ar_oldlib="$1" + if test "$lock_old_archive_extraction" = yes; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test "$lock_old_archive_extraction" = yes; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $opt_debug + my_gentop="$1"; shift + my_oldlibs=${1+"$@"} + my_oldobjs="" + my_xlib="" + my_xabs="" + my_xdir="" + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib="$func_basename_result" + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir="$my_gentop/$my_xlib_u" + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + darwin_base_archive=`basename "$darwin_archive"` + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches ; do + func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" + $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" + cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" + func_extract_an_archive "`pwd`" "${darwin_base_archive}" + cd "$darwin_curdir" + $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result="$my_oldobjs" +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory in which it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + $ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${1+\"\$@\"} + fi + else + # The program doesn't exist. + \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 + \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat < +#include +#ifdef _MSC_VER +# include +# include +# include +#else +# include +# include +# ifdef __CYGWIN__ +# include +# endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +/* declarations of non-ANSI functions */ +#if defined(__MINGW32__) +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined(__CYGWIN__) +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined (other platforms) ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined(_MSC_VER) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +# ifndef _INTPTR_T_DEFINED +# define _INTPTR_T_DEFINED +# define intptr_t int +# endif +#elif defined(__MINGW32__) +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined(__CYGWIN__) +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined (other platforms) ... */ +#endif + +#if defined(PATH_MAX) +# define LT_PATHMAX PATH_MAX +#elif defined(MAXPATHLEN) +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ + defined (__OS2__) +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free ((void *) stale); stale = 0; } \ +} while (0) + +#if defined(LT_DEBUGWRAPPER) +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + int tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined (HAVE_DOS_BASED_FILE_SYSTEM) + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (strcmp (str, pat) == 0) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + int len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + int orig_value_len = strlen (orig_value); + int add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + int len = strlen (new_value); + while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[len-1] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $opt_debug + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $opt_debug + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=no + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module="${wl}-single_module" + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test "$build_libtool_libs" != yes && \ + func_fatal_configuration "can not build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + build_libtool_libs=no + build_old_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test "$#" -gt 0; do + arg="$1" + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir="$arg" + prev= + continue + ;; + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=yes + fi + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols="$arg" + test -f "$arg" \ + || func_fatal_error "symbol file \`$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir="$arg" + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file \`$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + precious_regex) + precious_files_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds="$arg" + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg="$arg" + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "\`-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between \`-L' and \`$1'" + else + func_fatal_error "need path for \`-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of \`$dir'" + dir="$absdir" + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test "X$arg" = "X-lc" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + test "X$arg" = "X-lc" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test "X$arg" = "X-lc" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test "X$arg" = "X-lc" && continue + ;; + esac + elif test "X$arg" = "X-lc_r"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module="${wl}-multi_module" + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "\`-no-install' is ignored for $host" + func_warning "assuming \`-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs="$IFS"; IFS=',' + for flag in $args; do + IFS="$save_ifs" + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS="$save_ifs" + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test "$pic_object" = none && + test "$non_pic_object" = none; then + func_fatal_error "cannot find name of object for \`$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + if test "$pic_object" != none; then + # Prepend the subdirectory the object is found in. + pic_object="$xdir$pic_object" + + if test "$prev" = dlfiles; then + if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test "$prev" = dlprefiles; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg="$pic_object" + fi + + # Non-PIC object. + if test "$non_pic_object" != none; then + # Prepend the subdirectory the object is found in. + non_pic_object="$xdir$non_pic_object" + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test "$pic_object" = none ; then + arg="$non_pic_object" + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object="$pic_object" + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir="$func_dirname_result" + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "\`$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test "$prev" = dlfiles; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test "$prev" = dlprefiles; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg="$func_quote_for_eval_result" + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the \`$prevarg' option requires an argument" + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname="$func_basename_result" + libobjs_save="$libobjs" + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + func_dirname "$output" "/" "" + output_objdir="$func_dirname_result$objdir" + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps ; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test "$linkmode" = lib; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=no + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test "$linkmode,$pass" = "lib,link"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs="$tmp_deplibs" + fi + + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan"; then + libs="$deplibs" + deplibs= + fi + if test "$linkmode" = prog; then + case $pass in + dlopen) libs="$dlfiles" ;; + dlpreopen) libs="$dlprefiles" ;; + link) + libs="$deplibs %DEPLIBS%" + test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" + ;; + esac + fi + if test "$linkmode,$pass" = "lib,dlpreopen"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs="$dlprefiles" + fi + if test "$pass" = dlopen; then + # Collect dlpreopened libraries + save_deplibs="$deplibs" + deplibs= + fi + + for deplib in $libs; do + lib= + found=no + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test "$linkmode" != lib && test "$linkmode" != prog; then + func_warning "\`-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test "$linkmode" = lib; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib="$searchdir/lib${name}${search_ext}" + if test -f "$lib"; then + if test "$search_ext" = ".la"; then + found=yes + else + found=no + fi + break 2 + fi + done + done + if test "$found" != yes; then + # deplib doesn't seem to be a libtool library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + else # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll="$l" + done + if test "X$ll" = "X$old_library" ; then # only static version available + found=no + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + lib=$ladir/$old_library + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + fi + ;; # -l + *.ltframework) + if test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test "$linkmode" = lib ; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test "$pass" = conv && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + if test "$pass" = scan; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "\`-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test "$pass" = link; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=no + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=yes + fi + ;; + pass_all) + valid_a_lib=yes + ;; + esac + if test "$valid_a_lib" != yes; then + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + else + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + fi + ;; + esac + continue + ;; + prog) + if test "$pass" != link; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test "$pass" = conv; then + deplibs="$deplib $deplibs" + elif test "$linkmode" = prog; then + if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=yes + continue + ;; + esac # case $deplib + + if test "$found" = yes || test -f "$lib"; then : + else + func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" + fi + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "\`$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir="$func_dirname_result" + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test "$linkmode,$pass" = "lib,link" || + test "$linkmode,$pass" = "prog,scan" || + { test "$linkmode" != prog && test "$linkmode" != lib; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test "$pass" = conv; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + elif test "$linkmode" != prog && test "$linkmode" != lib; then + func_fatal_error "\`$lib' is not a convenience library" + fi + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test "$prefer_static_libs" = yes || + test "$prefer_static_libs,$installed" = "built,no"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib="$l" + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for \`$lib'" + fi + + # This library was specified with -dlopen. + if test "$pass" = dlopen; then + if test -z "$libdir"; then + func_fatal_error "cannot -dlopen a convenience library: \`$lib'" + fi + if test -z "$dlname" || + test "$dlopen_support" != yes || + test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir="$ladir" + fi + ;; + esac + func_basename "$lib" + laname="$func_basename_result" + + # Find the relevant object directory and library name. + if test "X$installed" = Xyes; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library \`$lib' was moved." + dir="$ladir" + absdir="$abs_ladir" + libdir="$abs_ladir" + else + dir="$lt_sysroot$libdir" + absdir="$lt_sysroot$libdir" + fi + test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir="$ladir" + absdir="$abs_ladir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir="$ladir/$objdir" + absdir="$abs_ladir/$objdir" + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test "$pass" = dlpreopen; then + if test -z "$libdir" && test "$linkmode" = prog; then + func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + fi + case "$host" in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test "$linkmode" = lib; then + deplibs="$dir/$old_library $deplibs" + elif test "$linkmode,$pass" = "prog,link"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test "$linkmode" = prog && test "$pass" != link; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=no + if test "$link_all_deplibs" != no || test -z "$library_names" || + test "$build_libtool_libs" = no; then + linkalldeplibs=yes + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if test "$linkalldeplibs" = yes; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test "$linkmode,$pass" = "prog,link"; then + if test -n "$library_names" && + { { test "$prefer_static_libs" = no || + test "$prefer_static_libs,$installed" = "built,yes"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath:" in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if test "$alldeplibs" = yes && + { test "$deplibs_check_method" = pass_all || + { test "$build_libtool_libs" = yes && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test "$use_static_libs" = built && test "$installed" = yes; then + use_static_libs=no + fi + if test -n "$library_names" && + { test "$use_static_libs" = no || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test "$installed" = no; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule="" + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule="$dlpremoduletest" + break + fi + done + if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + echo + if test "$linkmode" = prog; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test "$linkmode" = lib && + test "$hardcode_into_libs" = yes; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname="$1" + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname="$dlname" + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc*) + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + esac + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot="$soname" + func_basename "$soroot" + soname="$func_basename_result" + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from \`$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for \`$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test "$linkmode" = prog || test "$opt_mode" != relink; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test "$hardcode_direct" = no; then + add="$dir/$linklib" + case $host in + *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; + *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir="-L$dir" ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we can not + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null ; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library" ; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add="$dir/$old_library" + fi + elif test -n "$old_library"; then + add="$dir/$old_library" + fi + fi + esac + elif test "$hardcode_minus_L" = no; then + case $host in + *-*-sunos*) add_shlibpath="$dir" ;; + esac + add_dir="-L$dir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = no; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + relink) + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$dir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$absdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + add_shlibpath="$dir" + add="-l$name" + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test "$lib_linked" != yes; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test "$linkmode" = prog; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test "$hardcode_direct" != yes && + test "$hardcode_minus_L" != yes && + test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test "$linkmode" = prog || test "$opt_mode" = relink; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes && + test "$hardcode_direct_absolute" = no; then + add="$libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + add_dir="-L$libdir" + add="-l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add="-l$name" + elif test "$hardcode_automatic" = yes; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib" ; then + add="$inst_prefix_dir$libdir/$linklib" + else + add="$libdir/$linklib" + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir="-L$libdir" + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add="-l$name" + fi + + if test "$linkmode" = prog; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test "$linkmode" = prog; then + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test "$build_libtool_libs" = yes; then + # Not a shared library + if test "$deplibs_check_method" != pass_all; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system can not link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test "$module" = yes; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test "$linkmode" = lib; then + if test -n "$dependency_libs" && + { test "$hardcode_into_libs" != yes || + test "$build_old_libs" = yes || + test "$link_static" = yes; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs="$temp_deplibs" + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps ; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test "$link_all_deplibs" != no; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path="$deplib" ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of \`$dir'" + absdir="$dir" + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names" ; then + for tmp in $deplibrary_names ; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl" ; then + depdepl="$absdir/$objdir/$depdepl" + darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" + func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + path= + fi + fi + ;; + *) + path="-L$absdir/$objdir" + ;; + esac + else + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "\`$deplib' seems to be moved" + + path="-L$absdir" + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test "$pass" = link; then + if test "$linkmode" = "prog"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs="$newdependency_libs" + if test "$pass" = dlpreopen; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test "$pass" != dlopen; then + if test "$pass" != conv; then + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + fi + + if test "$linkmode,$pass" != "prog,link"; then + vars="deplibs" + else + vars="compile_deplibs finalize_deplibs" + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs ; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i="" + ;; + esac + if test -n "$i" ; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test "$linkmode" = prog; then + dlfiles="$newdlfiles" + fi + if test "$linkmode" = prog || test "$linkmode" = lib; then + dlprefiles="$newdlprefiles" + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "\`-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "\`-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form `libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test "$module" = no && \ + func_fatal_help "libtool library \`$output' must begin with \`lib'" + + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test "$deplibs_check_method" != pass_all; then + func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test "$dlself" != no && \ + func_warning "\`-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test "$#" -gt 1 && \ + func_warning "ignoring multiple \`-rpath's for a libtool library" + + install_libdir="$1" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + # Some compilers have problems with a `.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "\`-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + shift + IFS="$save_ifs" + + test -n "$7" && \ + func_fatal_help "too many parameters to \`-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major="$1" + number_minor="$2" + number_revision="$3" + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # which has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_revision" + ;; + freebsd-aout|freebsd-elf|qnx|sunos) + current="$number_major" + revision="$number_minor" + age="0" + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age="$number_minor" + revision="$number_minor" + lt_irix_increment=no + ;; + *) + func_fatal_configuration "$modename: unknown library version type \`$version_type'" + ;; + esac + ;; + no) + current="$1" + revision="$2" + age="$3" + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT \`$current' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION \`$revision' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE \`$age' must be a nonnegative integer" + func_fatal_error "\`$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE \`$age' is greater than the current interface number \`$current'" + func_fatal_error "\`$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current" + ;; + + irix | nonstopux) + if test "X$lt_irix_increment" = "Xno"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring="$verstring_prefix$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test "$loop" -ne 0; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring_prefix$major.$iface:$verstring" + done + + # Before this point, $major must not contain `.'. + major=.$major + versuffix="$major.$revision" + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix="$major.$age.$revision" + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test "$loop" -ne 0; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + func_append verstring ":${current}.0" + ;; + + qnx) + major=".$current" + versuffix=".$current" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 filesystems. + func_arith $current - $age + major=$func_arith_result + versuffix="-$major" + ;; + + *) + func_fatal_configuration "unknown library version type \`$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring="0.0" + ;; + esac + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + func_warning "undefined symbols not allowed in $host shared libraries" + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + fi + + func_generate_dlsyms "$libname" "$libname" "yes" + func_append libobjs " $symfileobj" + test "X$libobjs" = "X " && libobjs= + + if test "$opt_mode" != relink; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) + if test "X$precious_files_regex" != "X"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles="$dlfiles" + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles="$dlprefiles" + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test "$build_libtool_libs" = yes; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test "$build_libtool_need_lc" = "yes"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c </dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib="" + ;; + esac + fi + if test -n "$a_deplib" ; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib="$potent_lib" # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib="" + break 2 + fi + done + done + fi + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib" ; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + for i in $predeps $postdeps ; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test "$allow_undefined" = no; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs="$new_libs" + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Remove ${wl} instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test "$hardcode_into_libs" = yes; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath="$finalize_rpath" + test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath="$finalize_shlibpath" + test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname="$1" + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib="$output_objdir/$realname" + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols="$output_objdir/$libname.uexp" + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols="$export_symbols" + export_symbols= + always_export_symbols=yes + fi + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs="$IFS"; IFS='~' + for cmd1 in $cmds; do + IFS="$save_ifs" + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test "$try_normal_branch" = yes \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=${output_objdir}/${output_la}.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS="$save_ifs" + if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs="$tmp_deplibs" + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test "$compiler_needs_object" = yes && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test "X$skipped_export" != "X:" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then + output=${output_objdir}/${output_la}.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then + output=${output_objdir}/${output_la}.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test "$compiler_needs_object" = yes; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-${k}.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test "X$objlist" = X || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-${k}.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-${k}.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + if ${skipped_export-false}; then + func_verbose "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + fi + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs="$IFS"; IFS='~' + for cmd in $concat_cmds; do + IFS="$save_ifs" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + if ${skipped_export-false}; then + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols="$export_symbols" + test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + fi + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test "$module" = yes && test -n "$module_cmds" ; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + eval cmd=\"$cmd\" + $opt_silent || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS="$save_ifs" + + # Restore the uninstalled library and exit + if test "$opt_mode" = relink; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + func_warning "\`-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "\`-l' and \`-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "\`-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "\`-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "\`-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object \`$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec and hope we can get by with + # turning comma into space.. + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + else + gentop="$output_objdir/${obj}x" + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + + # Create the old-style object. + reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + + output="$obj" + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + fi + + if test -n "$pic_flag" || test "$pic_mode" != default; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "\`-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "\`-release' is ignored for programs" + + test "$preload" = yes \ + && test "$dlopen_support" = unknown \ + && test "$dlopen_self" = unknown \ + && test "$dlopen_self_static" = unknown && \ + func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test "$tagname" = CXX ; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " ${wl}-bind_at_load" + func_append finalize_command " ${wl}-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs="$new_libs" + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=yes + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=no + ;; + *cygwin* | *mingw* ) + if test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + *) + if test "$need_relink" = no || test "$build_libtool_libs" != yes; then + wrappers_required=no + fi + ;; + esac + if test "$wrappers_required" = no; then + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.${objext}"; then + func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + fi + + exit $exit_status + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$no_install" = yes; then + # We don't need to create a wrapper script. + link_command="$compile_var$compile_command$compile_rpath" + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "\`$output' will be relinked during installation" + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource="$output_path/$objdir/lt-$output_name.c" + cwrapper="$output_path/$output_name.exe" + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host" ; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save $symfileobj" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$old_deplibs $non_pic_objects" + if test "$preload" = yes && test -f "$symfileobj"; then + func_append oldobjs " $symfileobj" + fi + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop="$output_objdir/${outputname}x" + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase="$func_basename_result" + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj" ; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test "X$oldobjs" = "X" ; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test "$hardcode_automatic" = yes ; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name="$func_basename_result" + func_resolve_sysroot "$deplib" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "\`$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs="$newdependency_libs" + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name="$func_basename_result" + eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "\`$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles="$newdlprefiles" + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles="$newdlfiles" + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles="$newdlprefiles" + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test "x$bindir" != x ; + then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that can not go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test "$installed" = no && test "$need_relink" = yes; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +{ test "$opt_mode" = link || test "$opt_mode" = relink; } && + func_mode_link ${1+"$@"} + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $opt_debug + RM="$nonopt" + files= + rmforce= + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=yes ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir="$func_dirname_result" + if test "X$dir" = X.; then + odir="$objdir" + else + odir="$dir/$objdir" + fi + func_basename "$file" + name="$func_basename_result" + test "$opt_mode" = uninstall && odir="$dir" + + # Remember odir for removal later, being careful to avoid duplicates + if test "$opt_mode" = clean; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif test "$rmforce" = yes; then + continue + fi + + rmfiles="$file" + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case "$opt_mode" in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && + test "$pic_object" != none; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && + test "$non_pic_object" != none; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test "$opt_mode" = clean ; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.${objext}" + if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name" ; then + func_append rmfiles " $odir/lt-${noexename}.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the ${objdir}s in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && + func_mode_uninstall ${1+"$@"} + +test -z "$opt_mode" && { + help="$generic_help" + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode \`$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# in which we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: +# vi:sw=2 + diff --git a/m4/libtool.m4 b/m4/libtool.m4 new file mode 100644 index 00000000..828104cf --- /dev/null +++ b/m4/libtool.m4 @@ -0,0 +1,8001 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file 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. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, +# 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, or +# obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +]) + +# serial 57 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ltmain" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +m4_defun([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options which allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld="$lt_cv_prog_gnu_ld" + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from `configure', and `config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# `config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain="$ac_aux_dir/ltmain.sh" +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the `libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to `config.status' so that its +# declaration there will have the same value as in `configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags="_LT_TAGS"dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into `config.status', and then the shell code to quote escape them in +# for loops in `config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# `#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test $lt_write_fail = 0 && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +\`$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to ." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test $[#] != 0 +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try \`$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try \`$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test "$silent" = yes && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options which allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + + cfgfile="${ofile}T" + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL + +# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +_LT_COPYING +_LT_LIBTOOL_TAGS + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + _LT_PROG_REPLACE_SHELLFNS + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + TIMESTAMP='$TIMESTAMP' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test $_lt_result -eq 0; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test "$lt_cv_ld_force_load" = "yes"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + case $cc_basename in + ifort*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test "$_lt_dar_can_shared" = "yes"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + m4_if([$1], [CXX], +[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test "${lt_cv_aix_libpath+set}" = set; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script which will find a shell with a builtin +# printf (which we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case "$ECHO" in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[ --with-sysroot[=DIR] Search for dependent libraries within DIR + (or the compiler's sysroot if not specified).], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case ${with_sysroot} in #( + yes) + if test "$GCC" = yes; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and in which our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD="${LD-ld}_sol2" + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks="$enable_libtool_lock" +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -eq 0; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test "$ac_status" -ne 0; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test "x$lt_cv_ar_at_file" = xno; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test x"[$]$2" = xyes; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8 ; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisbility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links="nottested" +if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", + [Define to the sub-directory in which libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existent directories. + if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || + test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test "$GCC" = yes; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; + *) lt_sed_strip_eq="s,=/,/,g" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + ;; + m68k) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + esac + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='${libname}.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec="$LIB" + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=yes + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +fi +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +fi + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[List of archive names. First name is the real one, the rest are links. + The last name is the one that the linker finds with -lNAME]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], + [Run-time system search path for libraries]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program which can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program which can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` + while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do + ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + : ${lt_cv_path_NM=no} +fi]) +if test "$lt_cv_path_NM" != "no"; then + NM="$lt_cv_path_NM" +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test "$DUMPBIN" != ":"; then + NM="$DUMPBIN" + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh + # decide which to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd="$ECHO" + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test "x$lt_cv_path_mainfest_tool" != xyes; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function + # and D for any global variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ +" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ +" s[1]~/^[@?]/{print s[1], s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +/* DATA imports from DLLs on WIN32 con't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined(__osf__) +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64 which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + # old Intel for x86_64 which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global defined + # symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + linux* | k*bsd*-gnu | gnu*) + _LT_TAGVAR(link_all_deplibs, $1)=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test "$with_gnu_ld" = yes; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test "$lt_use_gnu_ld_interface" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test "$host_os" = linux-dietlibc; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test "$tmp_diet" = no + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + # Also, AIX nm treats weak defined symbols like other global + # defined symbols, whereas GNU nm marks them as "W". + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + _LT_TAGVAR(link_all_deplibs, $1)=no + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes && test "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS="$save_LDFLAGS"]) + if test "$lt_cv_irix_exported_symbol" = yes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='${wl}' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test "$GCC" = yes; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test x$host_vendor = xsni; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting ${shlibpath_var} if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report which library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC="$lt_save_CC" +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to `libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_caught_CXX_error" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test "$GXX" = yes; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + if test "$with_gnu_ld" = yes; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared + # libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; + else + $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile="$lt_outputfile.exe" + lt_tool_outputfile="$lt_tool_outputfile.exe" + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + gnu*) + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd2*) + # C++ shared libraries are fairly broken + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + openbsd*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + + _LT_TAGVAR(GCC, $1)="$GXX" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test "$_lt_caught_CXX_error" != yes + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case ${2} in + .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; + *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case ${prev}${p} in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" || + test $p = "-R"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test "$pre_test_object_deps_done" = no; then + case ${prev} in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)="$p" + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)="$p" + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC* | sunCC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test "X$F77" = "Xno"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_F77" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$G77" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC="$lt_save_CC" + CFLAGS="$lt_save_CFLAGS" +fi # test "$_lt_disable_F77" != yes + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test "X$FC" = "Xno"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test "$_lt_disable_FC" != yes; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC="$CC" + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test "$can_build_shared" = "no" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test "$enable_shared" = yes || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" + _LT_TAGVAR(LD, $1)="$LD" + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test "$_lt_disable_FC" != yes + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)="$LD" +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to `libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) +# Try some XSI features +xsi_shell=no +( _lt_dummy="a/b/c" + test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ + = c,a/b,b/c, \ + && eval 'test $(( 1 + 1 )) -eq 2 \ + && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ + && xsi_shell=yes +AC_MSG_RESULT([$xsi_shell]) +_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) + +AC_MSG_CHECKING([whether the shell understands "+="]) +lt_shell_append=no +( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ + >/dev/null 2>&1 \ + && lt_shell_append=yes +AC_MSG_RESULT([$lt_shell_append]) +_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) +# ------------------------------------------------------ +# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and +# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. +m4_defun([_LT_PROG_FUNCTION_REPLACE], +[dnl { +sed -e '/^$1 ()$/,/^} # $1 /c\ +$1 ()\ +{\ +m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) +} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") +test 0 -eq $? || _lt_function_replace_fail=: +]) + + +# _LT_PROG_REPLACE_SHELLFNS +# ------------------------- +# Replace existing portable implementations of several shell functions with +# equivalent extended shell implementations where those features are available.. +m4_defun([_LT_PROG_REPLACE_SHELLFNS], +[if test x"$xsi_shell" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl + case ${1} in + */*) func_dirname_result="${1%/*}${2}" ;; + * ) func_dirname_result="${3}" ;; + esac + func_basename_result="${1##*/}"]) + + _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary parameter first. + func_stripname_result=${3} + func_stripname_result=${func_stripname_result#"${1}"} + func_stripname_result=${func_stripname_result%"${2}"}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl + func_split_long_opt_name=${1%%=*} + func_split_long_opt_arg=${1#*=}]) + + _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) + + _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl + case ${1} in + *.lo) func_lo2o_result=${1%.lo}.${objext} ;; + *) func_lo2o_result=${1} ;; + esac]) + + _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) + + _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) + + _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) +fi + +if test x"$lt_shell_append" = xyes; then + _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) + + _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl + func_quote_for_eval "${2}" +dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ + eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) + + # Save a `func_append' function call where possible by direct use of '+=' + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +else + # Save a `func_append' function call even when '+=' is not available + sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ + && mv -f "$cfgfile.tmp" "$cfgfile" \ + || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") + test 0 -eq $? || _lt_function_replace_fail=: +fi + +if test x"$_lt_function_replace_fail" = x":"; then + AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) +fi +]) + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine which file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4 new file mode 100644 index 00000000..5d9acd8e --- /dev/null +++ b/m4/ltoptions.m4 @@ -0,0 +1,384 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file 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. + +# serial 7 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option `$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the `shared' and +# `disable-shared' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the `static' and +# `disable-static' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the `fast-install' +# and `disable-fast-install' LT_INIT options. +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the `disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# LT_INIT options. +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for lt_pkg in $withval; do + IFS="$lt_save_ifs" + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [pic_mode=default]) + +test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the `pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/m4/ltsugar.m4 b/m4/ltsugar.m4 new file mode 100644 index 00000000..9000a057 --- /dev/null +++ b/m4/ltsugar.m4 @@ -0,0 +1,123 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file 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. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59 which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/m4/ltversion.m4 b/m4/ltversion.m4 new file mode 100644 index 00000000..07a8602d --- /dev/null +++ b/m4/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file 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. + +# @configure_input@ + +# serial 3337 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.2]) +m4_define([LT_PACKAGE_REVISION], [1.3337]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.2' +macro_revision='1.3337' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/m4/lt~obsolete.m4 b/m4/lt~obsolete.m4 new file mode 100644 index 00000000..c573da90 --- /dev/null +++ b/m4/lt~obsolete.m4 @@ -0,0 +1,98 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file 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. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/m4/tcl.m4 b/m4/tcl.m4 new file mode 100644 index 00000000..55c0e06a --- /dev/null +++ b/m4/tcl.m4 @@ -0,0 +1,4055 @@ +# tcl.m4 -- +# +# This file provides a set of autoconf macros to help TEA-enable +# a Tcl extension. +# +# Copyright (c) 1999-2000 Ajuba Solutions. +# Copyright (c) 2002-2005 ActiveState Corporation. +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# +# RCS: @(#) $Id: tcl.m4,v 1.157 2010/12/15 05:35:07 stwo Exp $ + +AC_PREREQ(2.57) + +dnl TEA extensions pass us the version of TEA they think they +dnl are compatible with (must be set in TEA_INIT below) +dnl TEA_VERSION="3.9" + +# Possible values for key variables defined: +# +# TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem') +# TEA_PLATFORM - windows unix +# + +#------------------------------------------------------------------------ +# TEA_PATH_TCLCONFIG -- +# +# Locate the tclConfig.sh file and perform a sanity check on +# the Tcl compile flags +# +# Arguments: +# none +# +# Results: +# +# Adds the following arguments to configure: +# --with-tcl=... +# +# Defines the following vars: +# TCL_BIN_DIR Full path to the directory containing +# the tclConfig.sh file +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PATH_TCLCONFIG], [ + dnl TEA specific: Make sure we are initialized + AC_REQUIRE([TEA_INIT]) + # + # Ok, lets find the tcl configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tcl + # + + if test x"${no_tcl}" = x ; then + # we reset no_tcl in case something fails here + no_tcl=true + AC_ARG_WITH(tcl, + AC_HELP_STRING([--with-tcl], + [directory containing tcl configuration (tclConfig.sh)]), + with_tclconfig="${withval}") + AC_MSG_CHECKING([for Tcl configuration]) + AC_CACHE_VAL(ac_cv_c_tclconfig,[ + + # First check to see if --with-tcl was specified. + if test x"${with_tclconfig}" != x ; then + case "${with_tclconfig}" in + */tclConfig.sh ) + if test -f "${with_tclconfig}"; then + AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) + with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" + fi ;; + esac + if test -f "${with_tclconfig}/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" + else + AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) + fi + fi + + # then check for a private Tcl installation + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ../tcl \ + `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../tcl \ + `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../../tcl \ + `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tcl.framework/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`" + break + fi + done + fi + + # TEA specific: on Windows, check in common installation locations + if test "${TEA_PLATFORM}" = "windows" \ + -a x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + `ls -d /usr/lib64 2>/dev/null` \ + ; do + if test -f "$i/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tclconfig}" = x ; then + for i in \ + ${srcdir}/../tcl \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tclConfig.sh" ; then + ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + ]) + + if test x"${ac_cv_c_tclconfig}" = x ; then + TCL_BIN_DIR="# no Tcl configs found" + AC_MSG_ERROR([Can't find Tcl configuration definitions]) + else + no_tcl= + TCL_BIN_DIR="${ac_cv_c_tclconfig}" + AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) + fi + fi +]) + +#------------------------------------------------------------------------ +# TEA_PATH_TKCONFIG -- +# +# Locate the tkConfig.sh file +# +# Arguments: +# none +# +# Results: +# +# Adds the following arguments to configure: +# --with-tk=... +# +# Defines the following vars: +# TK_BIN_DIR Full path to the directory containing +# the tkConfig.sh file +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PATH_TKCONFIG], [ + # + # Ok, lets find the tk configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-tk + # + + if test x"${no_tk}" = x ; then + # we reset no_tk in case something fails here + no_tk=true + AC_ARG_WITH(tk, + AC_HELP_STRING([--with-tk], + [directory containing tk configuration (tkConfig.sh)]), + with_tkconfig="${withval}") + AC_MSG_CHECKING([for Tk configuration]) + AC_CACHE_VAL(ac_cv_c_tkconfig,[ + + # First check to see if --with-tkconfig was specified. + if test x"${with_tkconfig}" != x ; then + case "${with_tkconfig}" in + */tkConfig.sh ) + if test -f "${with_tkconfig}"; then + AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) + with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" + fi ;; + esac + if test -f "${with_tkconfig}/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" + else + AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) + fi + fi + + # then check for a private Tk library + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ../tk \ + `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../tk \ + `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ + ../../../tk \ + `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + + # on Darwin, check in Framework installation locations + if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ + `ls -d /Library/Frameworks 2>/dev/null` \ + `ls -d /Network/Library/Frameworks 2>/dev/null` \ + `ls -d /System/Library/Frameworks 2>/dev/null` \ + ; do + if test -f "$i/Tk.framework/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`" + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + `ls -d /usr/lib64 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # TEA specific: on Windows, check in common installation locations + if test "${TEA_PLATFORM}" = "windows" \ + -a x"${ac_cv_c_tkconfig}" = x ; then + for i in `ls -d C:/Tcl/lib 2>/dev/null` \ + `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ + ; do + if test -f "$i/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i; pwd)`" + break + fi + done + fi + + # check in a few other private locations + if test x"${ac_cv_c_tkconfig}" = x ; then + for i in \ + ${srcdir}/../tk \ + `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do + if test "${TEA_PLATFORM}" = "windows" \ + -a -f "$i/win/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/win; pwd)`" + break + fi + if test -f "$i/unix/tkConfig.sh" ; then + ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" + break + fi + done + fi + ]) + + if test x"${ac_cv_c_tkconfig}" = x ; then + TK_BIN_DIR="# no Tk configs found" + AC_MSG_ERROR([Can't find Tk configuration definitions]) + else + no_tk= + TK_BIN_DIR="${ac_cv_c_tkconfig}" + AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) + fi + fi +]) + +#------------------------------------------------------------------------ +# TEA_LOAD_TCLCONFIG -- +# +# Load the tclConfig.sh file +# +# Arguments: +# +# Requires the following vars to be set: +# TCL_BIN_DIR +# +# Results: +# +# Subst the following vars: +# TCL_BIN_DIR +# TCL_SRC_DIR +# TCL_LIB_FILE +# +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_LOAD_TCLCONFIG], [ + AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) + + if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then + AC_MSG_RESULT([loading]) + . "${TCL_BIN_DIR}/tclConfig.sh" + else + AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) + fi + + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" + eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" + + # If the TCL_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TCL_LIB_SPEC will be set to the value + # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC + # instead of TCL_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TCL_BIN_DIR}/Makefile" ; then + TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}" + TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}" + TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}" + elif test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tcl.framework installed in an arbitrary location. + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then + for i in "`cd "${TCL_BIN_DIR}"; pwd`" \ + "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do + if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then + TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}" + break + fi + done + fi + if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then + TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}" + TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" + fi + ;; + esac + fi + + # eval is required to do the TCL_DBGX substitution + eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" + eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" + eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" + eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" + + AC_SUBST(TCL_VERSION) + AC_SUBST(TCL_PATCH_LEVEL) + AC_SUBST(TCL_BIN_DIR) + AC_SUBST(TCL_SRC_DIR) + + AC_SUBST(TCL_LIB_FILE) + AC_SUBST(TCL_LIB_FLAG) + AC_SUBST(TCL_LIB_SPEC) + + AC_SUBST(TCL_STUB_LIB_FILE) + AC_SUBST(TCL_STUB_LIB_FLAG) + AC_SUBST(TCL_STUB_LIB_SPEC) + + case "`uname -s`" in + *CYGWIN_*) + AC_MSG_CHECKING([for cygwin variant]) + case ${TCL_EXTRA_CFLAGS} in + *-mwin32*|*-mno-cygwin*) + TEA_PLATFORM="windows" + CFLAGS="$CFLAGS -mwin32" + AC_MSG_RESULT([win32]) + ;; + *) + TEA_PLATFORM="unix" + AC_MSG_RESULT([unix]) + ;; + esac + EXEEXT=".exe" + ;; + *) + ;; + esac + + # The BUILD_$pkg is to define the correct extern storage class + # handling when making this package + AC_DEFINE_UNQUOTED(BUILD_${PACKAGE_NAME}, [], + [Building extension source?]) + # Do this here as we have fully defined TEA_PLATFORM now + if test "${TEA_PLATFORM}" = "windows" ; then + CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp" + fi + + # TEA specific: + AC_SUBST(CLEANFILES) + AC_SUBST(TCL_LIBS) + AC_SUBST(TCL_DEFS) + AC_SUBST(TCL_EXTRA_CFLAGS) + AC_SUBST(TCL_LD_FLAGS) + AC_SUBST(TCL_SHLIB_LD_LIBS) +]) + +#------------------------------------------------------------------------ +# TEA_LOAD_TKCONFIG -- +# +# Load the tkConfig.sh file +# +# Arguments: +# +# Requires the following vars to be set: +# TK_BIN_DIR +# +# Results: +# +# Sets the following vars that should be in tkConfig.sh: +# TK_BIN_DIR +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_LOAD_TKCONFIG], [ + AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) + + if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then + AC_MSG_RESULT([loading]) + . "${TK_BIN_DIR}/tkConfig.sh" + else + AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) + fi + + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FILE=\"${TK_LIB_FILE}\"" + eval "TK_STUB_LIB_FILE=\"${TK_STUB_LIB_FILE}\"" + + # If the TK_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable TK_LIB_SPEC will be set to the value + # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC + # instead of TK_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + if test -f "${TK_BIN_DIR}/Makefile" ; then + TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}" + TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}" + TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}" + elif test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use the libraries + # from the framework at the given location so that linking works + # against Tk.framework installed in an arbitrary location. + case ${TK_DEFS} in + *TK_FRAMEWORK*) + if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then + for i in "`cd "${TK_BIN_DIR}"; pwd`" \ + "`cd "${TK_BIN_DIR}"/../..; pwd`"; do + if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then + TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}" + break + fi + done + fi + if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then + TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}" + TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" + fi + ;; + esac + fi + + # eval is required to do the TK_DBGX substitution + eval "TK_LIB_FLAG=\"${TK_LIB_FLAG}\"" + eval "TK_LIB_SPEC=\"${TK_LIB_SPEC}\"" + eval "TK_STUB_LIB_FLAG=\"${TK_STUB_LIB_FLAG}\"" + eval "TK_STUB_LIB_SPEC=\"${TK_STUB_LIB_SPEC}\"" + + # TEA specific: Ensure windowingsystem is defined + if test "${TEA_PLATFORM}" = "unix" ; then + case ${TK_DEFS} in + *MAC_OSX_TK*) + AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?]) + TEA_WINDOWINGSYSTEM="aqua" + ;; + *) + TEA_WINDOWINGSYSTEM="x11" + ;; + esac + elif test "${TEA_PLATFORM}" = "windows" ; then + TEA_WINDOWINGSYSTEM="win32" + fi + + AC_SUBST(TK_VERSION) + AC_SUBST(TK_BIN_DIR) + AC_SUBST(TK_SRC_DIR) + + AC_SUBST(TK_LIB_FILE) + AC_SUBST(TK_LIB_FLAG) + AC_SUBST(TK_LIB_SPEC) + + AC_SUBST(TK_STUB_LIB_FILE) + AC_SUBST(TK_STUB_LIB_FLAG) + AC_SUBST(TK_STUB_LIB_SPEC) + + # TEA specific: + AC_SUBST(TK_LIBS) + AC_SUBST(TK_XINCLUDES) +]) + +#------------------------------------------------------------------------ +# TEA_PROG_TCLSH +# Determine the fully qualified path name of the tclsh executable +# in the Tcl build directory or the tclsh installed in a bin +# directory. This macro will correctly determine the name +# of the tclsh executable even if tclsh has not yet been +# built in the build directory. The tclsh found is always +# associated with a tclConfig.sh file. This tclsh should be used +# only for running extension test cases. It should never be +# or generation of files (like pkgIndex.tcl) at build time. +# +# Arguments +# none +# +# Results +# Subst's the following values: +# TCLSH_PROG +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PROG_TCLSH], [ + AC_MSG_CHECKING([for tclsh]) + if test -f "${TCL_BIN_DIR}/Makefile" ; then + # tclConfig.sh is in Tcl build directory + if test "${TEA_PLATFORM}" = "windows"; then + TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" + else + TCLSH_PROG="${TCL_BIN_DIR}/tclsh" + fi + else + # tclConfig.sh is in install location + if test "${TEA_PLATFORM}" = "windows"; then + TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${TCL_DBGX}${EXEEXT}" + else + TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}${TCL_DBGX}" + fi + list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/bin 2>/dev/null`" + for i in $list ; do + if test -f "$i/${TCLSH_PROG}" ; then + REAL_TCL_BIN_DIR="`cd "$i"; pwd`/" + break + fi + done + TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}" + fi + AC_MSG_RESULT([${TCLSH_PROG}]) + AC_SUBST(TCLSH_PROG) +]) + +#------------------------------------------------------------------------ +# TEA_PROG_WISH +# Determine the fully qualified path name of the wish executable +# in the Tk build directory or the wish installed in a bin +# directory. This macro will correctly determine the name +# of the wish executable even if wish has not yet been +# built in the build directory. The wish found is always +# associated with a tkConfig.sh file. This wish should be used +# only for running extension test cases. It should never be +# or generation of files (like pkgIndex.tcl) at build time. +# +# Arguments +# none +# +# Results +# Subst's the following values: +# WISH_PROG +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PROG_WISH], [ + AC_MSG_CHECKING([for wish]) + if test -f "${TK_BIN_DIR}/Makefile" ; then + # tkConfig.sh is in Tk build directory + if test "${TEA_PLATFORM}" = "windows"; then + WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" + else + WISH_PROG="${TK_BIN_DIR}/wish" + fi + else + # tkConfig.sh is in install location + if test "${TEA_PLATFORM}" = "windows"; then + WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${TK_DBGX}${EXEEXT}" + else + WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}${TK_DBGX}" + fi + list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \ + `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \ + `ls -d ${TK_PREFIX}/bin 2>/dev/null`" + for i in $list ; do + if test -f "$i/${WISH_PROG}" ; then + REAL_TK_BIN_DIR="`cd "$i"; pwd`/" + break + fi + done + WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}" + fi + AC_MSG_RESULT([${WISH_PROG}]) + AC_SUBST(WISH_PROG) +]) + +#------------------------------------------------------------------------ +# TEA_ENABLE_SHARED -- +# +# Allows the building of shared libraries +# +# Arguments: +# none +# +# Results: +# +# Adds the following arguments to configure: +# --enable-shared=yes|no +# +# Defines the following vars: +# STATIC_BUILD Used for building import/export libraries +# on Windows. +# +# Sets the following vars: +# SHARED_BUILD Value of 1 or 0 +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_ENABLE_SHARED], [ + AC_MSG_CHECKING([how to build libraries]) + AC_ARG_ENABLE(shared, + AC_HELP_STRING([--enable-shared], + [build and link with shared libraries (default: on)]), + [tcl_ok=$enableval], [tcl_ok=yes]) + + if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + tcl_ok=$enableval + else + tcl_ok=yes + fi + + if test "$tcl_ok" = "yes" ; then + AC_MSG_RESULT([shared]) + SHARED_BUILD=1 + else + AC_MSG_RESULT([static]) + SHARED_BUILD=0 + AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) + fi + AC_SUBST(SHARED_BUILD) +]) + +#------------------------------------------------------------------------ +# TEA_ENABLE_THREADS -- +# +# Specify if thread support should be enabled. If "yes" is specified +# as an arg (optional), threads are enabled by default, "no" means +# threads are disabled. "yes" is the default. +# +# TCL_THREADS is checked so that if you are compiling an extension +# against a threaded core, your extension must be compiled threaded +# as well. +# +# Note that it is legal to have a thread enabled extension run in a +# threaded or non-threaded Tcl core, but a non-threaded extension may +# only run in a non-threaded Tcl core. +# +# Arguments: +# none +# +# Results: +# +# Adds the following arguments to configure: +# --enable-threads +# +# Sets the following vars: +# THREADS_LIBS Thread library(s) +# +# Defines the following vars: +# TCL_THREADS +# _REENTRANT +# _THREAD_SAFE +# +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_ENABLE_THREADS], [ + AC_ARG_ENABLE(threads, + AC_HELP_STRING([--enable-threads], + [build with threads]), + [tcl_ok=$enableval], [tcl_ok=yes]) + + if test "${enable_threads+set}" = set; then + enableval="$enable_threads" + tcl_ok=$enableval + else + tcl_ok=yes + fi + + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + TCL_THREADS=1 + + if test "${TEA_PLATFORM}" != "windows" ; then + # We are always OK on Windows, so check what this platform wants: + + # USE_THREAD_ALLOC tells us to try the special thread-based + # allocator that significantly reduces lock contention + AC_DEFINE(USE_THREAD_ALLOC, 1, + [Do we want to use the threaded memory allocator?]) + AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) + if test "`uname -s`" = "SunOS" ; then + AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, + [Do we really want to follow the standard? Yes we do!]) + fi + AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?]) + AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) + if test "$tcl_ok" = "no"; then + # Check a little harder for __pthread_mutex_init in the same + # library, as some systems hide it there until pthread.h is + # defined. We could alternatively do an AC_TRY_COMPILE with + # pthread.h, but that will work with libpthread really doesn't + # exist, like AIX 4.2. [Bug: 4359] + AC_CHECK_LIB(pthread, __pthread_mutex_init, + tcl_ok=yes, tcl_ok=no) + fi + + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -lpthread" + else + AC_CHECK_LIB(pthreads, pthread_mutex_init, + tcl_ok=yes, tcl_ok=no) + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -lpthreads" + else + AC_CHECK_LIB(c, pthread_mutex_init, + tcl_ok=yes, tcl_ok=no) + if test "$tcl_ok" = "no"; then + AC_CHECK_LIB(c_r, pthread_mutex_init, + tcl_ok=yes, tcl_ok=no) + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -pthread" + else + TCL_THREADS=0 + AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled]) + fi + fi + fi + fi + fi + else + TCL_THREADS=0 + fi + # Do checking message here to not mess up interleaved configure output + AC_MSG_CHECKING([for building with threads]) + if test "${TCL_THREADS}" = 1; then + AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?]) + AC_MSG_RESULT([yes (default)]) + else + AC_MSG_RESULT([no]) + fi + # TCL_THREADS sanity checking. See if our request for building with + # threads is the same as the way Tcl was built. If not, warn the user. + case ${TCL_DEFS} in + *THREADS=1*) + if test "${TCL_THREADS}" = "0"; then + AC_MSG_WARN([ + Building ${PACKAGE_NAME} without threads enabled, but building against Tcl + that IS thread-enabled. It is recommended to use --enable-threads.]) + fi + ;; + *) + if test "${TCL_THREADS}" = "1"; then + AC_MSG_WARN([ + --enable-threads requested, but building against a Tcl that is NOT + thread-enabled. This is an OK configuration that will also run in + a thread-enabled core.]) + fi + ;; + esac + AC_SUBST(TCL_THREADS) +]) + +#------------------------------------------------------------------------ +# TEA_ENABLE_SYMBOLS -- +# +# Specify if debugging symbols should be used. +# Memory (TCL_MEM_DEBUG) debugging can also be enabled. +# +# Arguments: +# none +# +# TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives +# the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted. +# Requires the following vars to be set in the Makefile: +# CFLAGS_DEFAULT +# LDFLAGS_DEFAULT +# +# Results: +# +# Adds the following arguments to configure: +# --enable-symbols +# +# Defines the following vars: +# CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true +# Sets to $(CFLAGS_OPTIMIZE) if false +# LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true +# Sets to $(LDFLAGS_OPTIMIZE) if false +# DBGX Formerly used as debug library extension; +# always blank now. +# +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_ENABLE_SYMBOLS], [ + dnl TEA specific: Make sure we are initialized + AC_REQUIRE([TEA_CONFIG_CFLAGS]) + AC_MSG_CHECKING([for build with symbols]) + AC_ARG_ENABLE(symbols, + AC_HELP_STRING([--enable-symbols], + [build with debugging symbols (default: off)]), + [tcl_ok=$enableval], [tcl_ok=no]) + DBGX="" + if test "$tcl_ok" = "no"; then + CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE}" + LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" + AC_MSG_RESULT([no]) + else + CFLAGS_DEFAULT="${CFLAGS_DEBUG}" + LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" + if test "$tcl_ok" = "yes"; then + AC_MSG_RESULT([yes (standard debugging)]) + fi + fi + # TEA specific: + if test "${TEA_PLATFORM}" != "windows" ; then + LDFLAGS_DEFAULT="${LDFLAGS}" + fi + AC_SUBST(CFLAGS_DEFAULT) + AC_SUBST(LDFLAGS_DEFAULT) + AC_SUBST(TCL_DBGX) + + if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then + AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) + fi + + if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then + if test "$tcl_ok" = "all"; then + AC_MSG_RESULT([enabled symbols mem debugging]) + else + AC_MSG_RESULT([enabled $tcl_ok debugging]) + fi + fi +]) + +#------------------------------------------------------------------------ +# TEA_ENABLE_LANGINFO -- +# +# Allows use of modern nl_langinfo check for better l10n. +# This is only relevant for Unix. +# +# Arguments: +# none +# +# Results: +# +# Adds the following arguments to configure: +# --enable-langinfo=yes|no (default is yes) +# +# Defines the following vars: +# HAVE_LANGINFO Triggers use of nl_langinfo if defined. +# +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_ENABLE_LANGINFO], [ + AC_ARG_ENABLE(langinfo, + AC_HELP_STRING([--enable-langinfo], + [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]), + [langinfo_ok=$enableval], [langinfo_ok=yes]) + + HAVE_LANGINFO=0 + if test "$langinfo_ok" = "yes"; then + AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no]) + fi + AC_MSG_CHECKING([whether to use nl_langinfo]) + if test "$langinfo_ok" = "yes"; then + AC_CACHE_VAL(tcl_cv_langinfo_h, [ + AC_TRY_COMPILE([#include ], [nl_langinfo(CODESET);], + [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])]) + AC_MSG_RESULT([$tcl_cv_langinfo_h]) + if test $tcl_cv_langinfo_h = yes; then + AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?]) + fi + else + AC_MSG_RESULT([$langinfo_ok]) + fi +]) + +#-------------------------------------------------------------------- +# TEA_CONFIG_SYSTEM +# +# Determine what the system is (some things cannot be easily checked +# on a feature-driven basis, alas). This can usually be done via the +# "uname" command. +# +# Arguments: +# none +# +# Results: +# Defines the following var: +# +# system - System/platform/version identification code. +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_CONFIG_SYSTEM], [ + AC_CACHE_CHECK([system version], tcl_cv_sys_version, [ + # TEA specific: + if test "${TEA_PLATFORM}" = "windows" ; then + tcl_cv_sys_version=windows + else + tcl_cv_sys_version=`uname -s`-`uname -r` + if test "$?" -ne 0 ; then + AC_MSG_WARN([can't find uname command]) + tcl_cv_sys_version=unknown + else + if test "`uname -s`" = "AIX" ; then + tcl_cv_sys_version=AIX-`uname -v`.`uname -r` + fi + fi + fi + ]) + system=$tcl_cv_sys_version +]) + +#-------------------------------------------------------------------- +# TEA_CONFIG_CFLAGS +# +# Try to determine the proper flags to pass to the compiler +# for building shared libraries and other such nonsense. +# +# Arguments: +# none +# +# Results: +# +# Defines and substitutes the following vars: +# +# DL_OBJS, DL_LIBS - removed for TEA, only needed by core. +# LDFLAGS - Flags to pass to the compiler when linking object +# files into an executable application binary such +# as tclsh. +# LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib", +# that tell the run-time dynamic linker where to look +# for shared libraries such as libtcl.so. Depends on +# the variable LIB_RUNTIME_DIR in the Makefile. Could +# be the same as CC_SEARCH_FLAGS if ${CC} is used to link. +# CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib", +# that tell the run-time dynamic linker where to look +# for shared libraries such as libtcl.so. Depends on +# the variable LIB_RUNTIME_DIR in the Makefile. +# SHLIB_CFLAGS - Flags to pass to cc when compiling the components +# of a shared library (may request position-independent +# code, among other things). +# SHLIB_LD - Base command to use for combining object files +# into a shared library. +# SHLIB_LD_LIBS - Dependent libraries for the linker to scan when +# creating shared libraries. This symbol typically +# goes at the end of the "ld" commands that build +# shared libraries. The value of the symbol defaults to +# "${LIBS}" if all of the dependent libraries should +# be specified when creating a shared library. If +# dependent libraries should not be specified (as on +# SunOS 4.x, where they cause the link to fail, or in +# general if Tcl and Tk aren't themselves shared +# libraries), then this symbol has an empty string +# as its value. +# SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable +# extensions. An empty string means we don't know how +# to use shared libraries on this platform. +# LIB_SUFFIX - Specifies everything that comes after the "libfoo" +# in a static or shared library name, using the $VERSION variable +# to put the version in the right place. This is used +# by platforms that need non-standard library names. +# Examples: ${VERSION}.so.1.1 on NetBSD, since it needs +# to have a version after the .so, and ${VERSION}.a +# on AIX, since a shared library needs to have +# a .a extension whereas shared objects for loadable +# extensions have a .so extension. Defaults to +# ${VERSION}${SHLIB_SUFFIX}. +# CFLAGS_DEBUG - +# Flags used when running the compiler in debug mode +# CFLAGS_OPTIMIZE - +# Flags used when running the compiler in optimize mode +# CFLAGS - Additional CFLAGS added as necessary (usually 64-bit) +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_CONFIG_CFLAGS], [ + dnl TEA specific: Make sure we are initialized + AC_REQUIRE([TEA_INIT]) + + # Step 0.a: Enable 64 bit support? + + AC_MSG_CHECKING([if 64bit support is requested]) + AC_ARG_ENABLE(64bit, + AC_HELP_STRING([--enable-64bit], + [enable 64bit support (default: off)]), + [do64bit=$enableval], [do64bit=no]) + AC_MSG_RESULT([$do64bit]) + + # Step 0.b: Enable Solaris 64 bit VIS support? + + AC_MSG_CHECKING([if 64bit Sparc VIS support is requested]) + AC_ARG_ENABLE(64bit-vis, + AC_HELP_STRING([--enable-64bit-vis], + [enable 64bit Sparc VIS support (default: off)]), + [do64bitVIS=$enableval], [do64bitVIS=no]) + AC_MSG_RESULT([$do64bitVIS]) + # Force 64bit on with VIS + AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes]) + + # Step 0.c: Check if visibility support is available. Do this here so + # that platform specific alternatives can be used below if this fails. + + AC_CACHE_CHECK([if compiler supports visibility "hidden"], + tcl_cv_cc_visibility_hidden, [ + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" + AC_TRY_LINK([ + extern __attribute__((__visibility__("hidden"))) void f(void); + void f(void) {}], [f();], tcl_cv_cc_visibility_hidden=yes, + tcl_cv_cc_visibility_hidden=no) + CFLAGS=$hold_cflags]) + AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [ + AC_DEFINE(MODULE_SCOPE, + [extern __attribute__((__visibility__("hidden")))], + [Compiler support for module scope symbols]) + ]) + + # Step 0.d: Disable -rpath support? + + AC_MSG_CHECKING([if rpath support is requested]) + AC_ARG_ENABLE(rpath, + AC_HELP_STRING([--disable-rpath], + [disable rpath support (default: on)]), + [doRpath=$enableval], [doRpath=yes]) + AC_MSG_RESULT([$doRpath]) + + # TEA specific: Cross-compiling options for Windows/CE builds? + + AS_IF([test "${TEA_PLATFORM}" = windows], [ + AC_MSG_CHECKING([if Windows/CE build is requested]) + AC_ARG_ENABLE(wince, + AC_HELP_STRING([--enable-wince], + [enable Win/CE support (where applicable)]), + [doWince=$enableval], [doWince=no]) + AC_MSG_RESULT([$doWince]) + ]) + + # Set the variable "system" to hold the name and version number + # for the system. + + TEA_CONFIG_SYSTEM + + # Require ranlib early so we can override it in special cases below. + + AC_REQUIRE([AC_PROG_RANLIB]) + + # Set configuration options based on system name and version. + # This is similar to Tcl's unix/tcl.m4 except that we've added a + # "windows" case and removed some core-only vars. + + do64bit_ok=no + # default to '{$LIBS}' and set to "" on per-platform necessary basis + SHLIB_LD_LIBS='${LIBS}' + # When ld needs options to work in 64-bit mode, put them in + # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] + # is disabled by the user. [Bug 1016796] + LDFLAGS_ARCH="" + UNSHARED_LIB_SUFFIX="" + # TEA specific: use PACKAGE_VERSION instead of VERSION + TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' + ECHO_VERSION='`echo ${PACKAGE_VERSION}`' + TCL_LIB_VERSIONS_OK=ok + CFLAGS_DEBUG=-g + CFLAGS_OPTIMIZE=-O + AS_IF([test "$GCC" = yes], [ + # TEA specific: + CFLAGS_OPTIMIZE=-O2 + CFLAGS_WARNING="-Wall" + ], [CFLAGS_WARNING=""]) + AC_CHECK_TOOL(AR, ar) + STLIB_LD='${AR} cr' + LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" + AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION="1.0"]) + case $system in + # TEA specific: + windows) + # This is a 2-stage check to make sure we have the 64-bit SDK + # We have to know where the SDK is installed. + # This magic is based on MS Platform SDK for Win2003 SP1 - hobbs + # MACHINE is IX86 for LINK, but this is used by the manifest, + # which requires x86|amd64|ia64. + MACHINE="X86" + if test "$do64bit" != "no" ; then + if test "x${MSSDK}x" = "xx" ; then + MSSDK="C:/Progra~1/Microsoft Platform SDK" + fi + MSSDK=`echo "$MSSDK" | sed -e 's!\\\!/!g'` + PATH64="" + case "$do64bit" in + amd64|x64|yes) + MACHINE="AMD64" ; # default to AMD64 64-bit build + PATH64="${MSSDK}/Bin/Win64/x86/AMD64" + ;; + ia64) + MACHINE="IA64" + PATH64="${MSSDK}/Bin/Win64" + ;; + esac + if test "$GCC" != "yes" -a ! -d "${PATH64}" ; then + AC_MSG_WARN([Could not find 64-bit $MACHINE SDK to enable 64bit mode]) + AC_MSG_WARN([Ensure latest Platform SDK is installed]) + do64bit="no" + else + AC_MSG_RESULT([ Using 64-bit $MACHINE mode]) + do64bit_ok="yes" + fi + fi + + if test "$doWince" != "no" ; then + if test "$do64bit" != "no" ; then + AC_MSG_ERROR([Windows/CE and 64-bit builds incompatible]) + fi + if test "$GCC" = "yes" ; then + AC_MSG_ERROR([Windows/CE and GCC builds incompatible]) + fi + TEA_PATH_CELIB + # Set defaults for common evc4/PPC2003 setup + # Currently Tcl requires 300+, possibly 420+ for sockets + CEVERSION=420; # could be 211 300 301 400 420 ... + TARGETCPU=ARMV4; # could be ARMV4 ARM MIPS SH3 X86 ... + ARCH=ARM; # could be ARM MIPS X86EM ... + PLATFORM="Pocket PC 2003"; # or "Pocket PC 2002" + if test "$doWince" != "yes"; then + # If !yes then the user specified something + # Reset ARCH to allow user to skip specifying it + ARCH= + eval `echo $doWince | awk -F, '{ \ + if (length([$]1)) { printf "CEVERSION=\"%s\"\n", [$]1; \ + if ([$]1 < 400) { printf "PLATFORM=\"Pocket PC 2002\"\n" } }; \ + if (length([$]2)) { printf "TARGETCPU=\"%s\"\n", toupper([$]2) }; \ + if (length([$]3)) { printf "ARCH=\"%s\"\n", toupper([$]3) }; \ + if (length([$]4)) { printf "PLATFORM=\"%s\"\n", [$]4 }; \ + }'` + if test "x${ARCH}" = "x" ; then + ARCH=$TARGETCPU; + fi + fi + OSVERSION=WCE$CEVERSION; + if test "x${WCEROOT}" = "x" ; then + WCEROOT="C:/Program Files/Microsoft eMbedded C++ 4.0" + if test ! -d "${WCEROOT}" ; then + WCEROOT="C:/Program Files/Microsoft eMbedded Tools" + fi + fi + if test "x${SDKROOT}" = "x" ; then + SDKROOT="C:/Program Files/Windows CE Tools" + if test ! -d "${SDKROOT}" ; then + SDKROOT="C:/Windows CE Tools" + fi + fi + WCEROOT=`echo "$WCEROOT" | sed -e 's!\\\!/!g'` + SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` + if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" \ + -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then + AC_MSG_ERROR([could not find PocketPC SDK or target compiler to enable WinCE mode [$CEVERSION,$TARGETCPU,$ARCH,$PLATFORM]]) + doWince="no" + else + # We could PATH_NOSPACE these, but that's not important, + # as long as we quote them when used. + CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" + if test -d "${CEINCLUDE}/${TARGETCPU}" ; then + CEINCLUDE="${CEINCLUDE}/${TARGETCPU}" + fi + CELIBPATH="${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}" + fi + fi + + if test "$GCC" != "yes" ; then + if test "${SHARED_BUILD}" = "0" ; then + runtime=-MT + else + runtime=-MD + fi + + if test "$do64bit" != "no" ; then + # All this magic is necessary for the Win64 SDK RC1 - hobbs + CC="\"${PATH64}/cl.exe\"" + CFLAGS="${CFLAGS} -I\"${MSSDK}/Include\" -I\"${MSSDK}/Include/crt\" -I\"${MSSDK}/Include/crt/sys\"" + RC="\"${MSSDK}/bin/rc.exe\"" + lflags="-nologo -MACHINE:${MACHINE} -LIBPATH:\"${MSSDK}/Lib/${MACHINE}\"" + LINKBIN="\"${PATH64}/link.exe\"" + CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" + CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" + # Avoid 'unresolved external symbol __security_cookie' + # errors, c.f. http://support.microsoft.com/?id=894573 + TEA_ADD_LIBS([bufferoverflowU.lib]) + elif test "$doWince" != "no" ; then + CEBINROOT="${WCEROOT}/EVC/${OSVERSION}/bin" + if test "${TARGETCPU}" = "X86"; then + CC="\"${CEBINROOT}/cl.exe\"" + else + CC="\"${CEBINROOT}/cl${ARCH}.exe\"" + fi + CFLAGS="$CFLAGS -I\"${CELIB_DIR}/inc\" -I\"${CEINCLUDE}\"" + RC="\"${WCEROOT}/Common/EVC/bin/rc.exe\"" + arch=`echo ${ARCH} | awk '{print tolower([$]0)}'` + defs="${ARCH} _${ARCH}_ ${arch} PALM_SIZE _MT _WINDOWS" + if test "${SHARED_BUILD}" = "1" ; then + # Static CE builds require static celib as well + defs="${defs} _DLL" + fi + for i in $defs ; do + AC_DEFINE_UNQUOTED($i, 1, [WinCE def ]$i) + done + AC_DEFINE_UNQUOTED(_WIN32_WCE, $CEVERSION, [_WIN32_WCE version]) + AC_DEFINE_UNQUOTED(UNDER_CE, $CEVERSION, [UNDER_CE version]) + CFLAGS_DEBUG="-nologo -Zi -Od" + CFLAGS_OPTIMIZE="-nologo -Ox" + lversion=`echo ${CEVERSION} | sed -e 's/\(.\)\(..\)/\1\.\2/'` + lflags="-MACHINE:${ARCH} -LIBPATH:\"${CELIBPATH}\" -subsystem:windowsce,${lversion} -nologo" + LINKBIN="\"${CEBINROOT}/link.exe\"" + AC_SUBST(CELIB_DIR) + else + RC="rc" + lflags="-nologo" + LINKBIN="link" + CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" + CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" + fi + fi + + if test "$GCC" = "yes"; then + # mingw gcc mode + AC_CHECK_TOOL(RC, windres) + CFLAGS_DEBUG="-g" + CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" + SHLIB_LD="$CC -shared" + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" + LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" + else + SHLIB_LD="${LINKBIN} -dll ${lflags}" + # link -lib only works when -lib is the first arg + STLIB_LD="${LINKBIN} -lib ${lflags}" + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' + PATHTYPE=-w + # For information on what debugtype is most useful, see: + # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp + # and also + # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx + # This essentially turns it all on. + LDFLAGS_DEBUG="-debug -debugtype:cv" + LDFLAGS_OPTIMIZE="-release" + if test "$doWince" != "no" ; then + LDFLAGS_CONSOLE="-link ${lflags}" + LDFLAGS_WINDOW=${LDFLAGS_CONSOLE} + else + LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" + LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" + fi + fi + + SHLIB_SUFFIX=".dll" + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' + + TCL_LIB_VERSIONS_OK=nodots + ;; + AIX-*) + AS_IF([test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"], [ + # AIX requires the _r compiler when gcc isn't being used + case "${CC}" in + *_r|*_r\ *) + # ok ... + ;; + *) + # Make sure only first arg gets _r + CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'` + ;; + esac + AC_MSG_RESULT([Using $CC for compiling with threads]) + ]) + LIBS="$LIBS -lc" + SHLIB_CFLAGS="" + SHLIB_SUFFIX=".so" + + LD_LIBRARY_PATH_VAR="LIBPATH" + + # Check to enable 64-bit flags for compiler/linker + AS_IF([test "$do64bit" = yes], [ + AS_IF([test "$GCC" = yes], [ + AC_MSG_WARN([64bit mode not supported with GCC on $system]) + ], [ + do64bit_ok=yes + CFLAGS="$CFLAGS -q64" + LDFLAGS_ARCH="-q64" + RANLIB="${RANLIB} -X64" + AR="${AR} -X64" + SHLIB_LD_FLAGS="-b64" + ]) + ]) + + AS_IF([test "`uname -m`" = ia64], [ + # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC + SHLIB_LD="/usr/ccs/bin/ld -G -z text" + AS_IF([test "$GCC" = yes], [ + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + ], [ + CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' + ]) + LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' + ], [ + AS_IF([test "$GCC" = yes], [ + SHLIB_LD='${CC} -shared -Wl,-bexpall' + ], [ + SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry" + LDFLAGS="$LDFLAGS -brtl" + ]) + SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}" + CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + ]) + ;; + BeOS*) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD='${CC} -nostart' + SHLIB_SUFFIX=".so" + + #----------------------------------------------------------- + # Check for inet_ntoa in -lbind, for BeOS (which also needs + # -lsocket, even if the network functions are in -lnet which + # is always linked to, for compatibility. + #----------------------------------------------------------- + AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"]) + ;; + BSD/OS-4.*) + SHLIB_CFLAGS="-export-dynamic -fPIC" + SHLIB_LD='${CC} -shared' + SHLIB_SUFFIX=".so" + LDFLAGS="$LDFLAGS -export-dynamic" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + CYGWIN_*) + SHLIB_CFLAGS="" + SHLIB_LD='${CC} -shared' + SHLIB_SUFFIX=".dll" + EXE_SUFFIX=".exe" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + Haiku*) + LDFLAGS="$LDFLAGS -Wl,--export-dynamic" + SHLIB_CFLAGS="-fPIC" + SHLIB_SUFFIX=".so" + SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' + AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"]) + ;; + HP-UX-*.11.*) + # Use updated header definitions where possible + AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?]) + # TEA specific: Needed by Tcl, but not most extensions + #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) + #LIBS="$LIBS -lxnet" # Use the XOPEN network library + + AS_IF([test "`uname -m`" = ia64], [ + SHLIB_SUFFIX=".so" + # Use newer C++ library for C++ extensions + #if test "$GCC" != "yes" ; then + # CPPFLAGS="-AA" + #fi + ], [ + SHLIB_SUFFIX=".sl" + ]) + AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) + AS_IF([test "$tcl_ok" = yes], [ + LDFLAGS="$LDFLAGS -Wl,-E" + CC_SEARCH_FLAGS='-Wl,+s,+b,${LIB_RUNTIME_DIR}:.' + LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' + LD_LIBRARY_PATH_VAR="SHLIB_PATH" + ]) + AS_IF([test "$GCC" = yes], [ + SHLIB_LD='${CC} -shared' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + ], [ + CFLAGS="$CFLAGS -z" + # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc + #CFLAGS="$CFLAGS +DAportable" + SHLIB_CFLAGS="+z" + SHLIB_LD="ld -b" + ]) + + # Check to enable 64-bit flags for compiler/linker + AS_IF([test "$do64bit" = "yes"], [ + AS_IF([test "$GCC" = yes], [ + case `${CC} -dumpmachine` in + hppa64*) + # 64-bit gcc in use. Fix flags for GNU ld. + do64bit_ok=yes + SHLIB_LD='${CC} -shared' + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + ;; + *) + AC_MSG_WARN([64bit mode not supported with GCC on $system]) + ;; + esac + ], [ + do64bit_ok=yes + CFLAGS="$CFLAGS +DD64" + LDFLAGS_ARCH="+DD64" + ]) + ]) ;; + IRIX-6.*) + SHLIB_CFLAGS="" + SHLIB_LD="ld -n32 -shared -rdata_shared" + SHLIB_SUFFIX=".so" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) + AS_IF([test "$GCC" = yes], [ + CFLAGS="$CFLAGS -mabi=n32" + LDFLAGS="$LDFLAGS -mabi=n32" + ], [ + case $system in + IRIX-6.3) + # Use to build 6.2 compatible binaries on 6.3. + CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" + ;; + *) + CFLAGS="$CFLAGS -n32" + ;; + esac + LDFLAGS="$LDFLAGS -n32" + ]) + ;; + IRIX64-6.*) + SHLIB_CFLAGS="" + SHLIB_LD="ld -n32 -shared -rdata_shared" + SHLIB_SUFFIX=".so" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) + + # Check to enable 64-bit flags for compiler/linker + + AS_IF([test "$do64bit" = yes], [ + AS_IF([test "$GCC" = yes], [ + AC_MSG_WARN([64bit mode not supported by gcc]) + ], [ + do64bit_ok=yes + SHLIB_LD="ld -64 -shared -rdata_shared" + CFLAGS="$CFLAGS -64" + LDFLAGS_ARCH="-64" + ]) + ]) + ;; + Linux*) + SHLIB_CFLAGS="-fPIC" + SHLIB_SUFFIX=".so" + + # TEA specific: + CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" + + # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS + SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS_DEFAULT}' + LDFLAGS="$LDFLAGS -Wl,--export-dynamic" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) + AS_IF([test $do64bit = yes], [ + AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ + hold_cflags=$CFLAGS + CFLAGS="$CFLAGS -m64" + AC_TRY_LINK(,, tcl_cv_cc_m64=yes, tcl_cv_cc_m64=no) + CFLAGS=$hold_cflags]) + AS_IF([test $tcl_cv_cc_m64 = yes], [ + CFLAGS="$CFLAGS -m64" + do64bit_ok=yes + ]) + ]) + + # The combo of gcc + glibc has a bug related to inlining of + # functions like strtod(). The -fno-builtin flag should address + # this problem but it does not work. The -fno-inline flag is kind + # of overkill but it works. Disable inlining only when one of the + # files in compat/*.c is being linked in. + + AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) + + ;; + GNU*) + SHLIB_CFLAGS="-fPIC" + SHLIB_SUFFIX=".so" + + SHLIB_LD='${CC} -shared' + LDFLAGS="$LDFLAGS -Wl,--export-dynamic" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) + ;; + Lynx*) + SHLIB_CFLAGS="-fPIC" + SHLIB_SUFFIX=".so" + CFLAGS_OPTIMIZE=-02 + SHLIB_LD='${CC} -shared' + LD_FLAGS="-Wl,--export-dynamic" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + ;; + OpenBSD-*) + arch=`arch -s` + case "$arch" in + m88k|vax) + SHLIB_SUFFIX="" + SHARED_LIB_SUFFIX="" + ;; + *) + SHLIB_CFLAGS="-fPIC" + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_SUFFIX=".so" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' + ;; + esac + case "$arch" in + m88k|vax) + CFLAGS_OPTIMIZE="-O1" + ;; + *) + CFLAGS_OPTIMIZE="-O2" + ;; + esac + AC_CACHE_CHECK([for ELF], tcl_cv_ld_elf, [ + AC_EGREP_CPP(yes, [ +#ifdef __ELF__ + yes +#endif + ], tcl_cv_ld_elf=yes, tcl_cv_ld_elf=no)]) + AS_IF([test $tcl_cv_ld_elf = yes], [ + LDFLAGS=-Wl,-export-dynamic + ], [LDFLAGS=""]) + AS_IF([test "${TCL_THREADS}" = "1"], [ + # On OpenBSD: Compile with -pthread + # Don't link with -lpthread + LIBS=`echo $LIBS | sed s/-lpthread//` + CFLAGS="$CFLAGS -pthread" + ]) + # OpenBSD doesn't do version numbers with dots. + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + TCL_LIB_VERSIONS_OK=nodots + ;; + NetBSD-*|FreeBSD-[[3-4]].*) + # FreeBSD 3.* and greater have ELF. + # NetBSD 2.* has ELF and can use 'cc -shared' to build shared libs + SHLIB_CFLAGS="-fPIC" + SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' + SHLIB_SUFFIX=".so" + LDFLAGS="$LDFLAGS -export-dynamic" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}']) + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + AS_IF([test "${TCL_THREADS}" = "1"], [ + # The -pthread needs to go in the CFLAGS, not LIBS + LIBS=`echo $LIBS | sed s/-pthread//` + CFLAGS="$CFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + ]) + case $system in + FreeBSD-3.*) + # FreeBSD-3 doesn't handle version numbers with dots. + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so' + TCL_LIB_VERSIONS_OK=nodots + ;; + esac + ;; + FreeBSD-*) + # This configuration from FreeBSD Ports. + SHLIB_CFLAGS="-fPIC" + SHLIB_LD="${CC} -shared" + TCL_SHLIB_LD_EXTRAS="-soname \$[@]" + SHLIB_SUFFIX=".so" + LDFLAGS="" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) + AS_IF([test "${TCL_THREADS}" = "1"], [ + # The -pthread needs to go in the LDFLAGS, not LIBS + LIBS=`echo $LIBS | sed s/-pthread//` + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) + # Version numbers are dot-stripped by system policy. + TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .` + UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' + SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1' + TCL_LIB_VERSIONS_OK=nodots + ;; + Darwin-*) + CFLAGS_OPTIMIZE="-Os" + SHLIB_CFLAGS="-fno-common" + # To avoid discrepancies between what headers configure sees during + # preprocessing tests and compiling tests, move any -isysroot and + # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: + CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ + awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ + if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`" + CFLAGS="`echo " ${CFLAGS}" | \ + awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ + if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`" + AS_IF([test $do64bit = yes], [ + case `arch` in + ppc) + AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag], + tcl_cv_cc_arch_ppc64, [ + hold_cflags=$CFLAGS + CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" + AC_TRY_LINK(,, tcl_cv_cc_arch_ppc64=yes, + tcl_cv_cc_arch_ppc64=no) + CFLAGS=$hold_cflags]) + AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [ + CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" + do64bit_ok=yes + ]);; + i386) + AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag], + tcl_cv_cc_arch_x86_64, [ + hold_cflags=$CFLAGS + CFLAGS="$CFLAGS -arch x86_64" + AC_TRY_LINK(,, tcl_cv_cc_arch_x86_64=yes, + tcl_cv_cc_arch_x86_64=no) + CFLAGS=$hold_cflags]) + AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [ + CFLAGS="$CFLAGS -arch x86_64" + do64bit_ok=yes + ]);; + *) + AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);; + esac + ], [ + # Check for combined 32-bit and 64-bit fat build + AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ + && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [ + fat_32_64=yes]) + ]) + # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS + SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}' + AC_CACHE_CHECK([if ld accepts -single_module flag], tcl_cv_ld_single_module, [ + hold_ldflags=$LDFLAGS + LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" + AC_TRY_LINK(, [int i;], tcl_cv_ld_single_module=yes, tcl_cv_ld_single_module=no) + LDFLAGS=$hold_ldflags]) + AS_IF([test $tcl_cv_ld_single_module = yes], [ + SHLIB_LD="${SHLIB_LD} -Wl,-single_module" + ]) + # TEA specific: link shlib with current and compatiblity version flags + vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` + SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" + SHLIB_SUFFIX=".dylib" + # Don't use -prebind when building for Mac OS X 10.4 or later only: + AS_IF([test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int([$]2)}'`" -lt 4 -a \ + "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int([$]2)}'`" -lt 4], [ + LDFLAGS="$LDFLAGS -prebind"]) + LDFLAGS="$LDFLAGS -headerpad_max_install_names" + AC_CACHE_CHECK([if ld accepts -search_paths_first flag], + tcl_cv_ld_search_paths_first, [ + hold_ldflags=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-search_paths_first" + AC_TRY_LINK(, [int i;], tcl_cv_ld_search_paths_first=yes, + tcl_cv_ld_search_paths_first=no) + LDFLAGS=$hold_ldflags]) + AS_IF([test $tcl_cv_ld_search_paths_first = yes], [ + LDFLAGS="$LDFLAGS -Wl,-search_paths_first" + ]) + AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ + AC_DEFINE(MODULE_SCOPE, [__private_extern__], + [Compiler support for module scope symbols]) + tcl_cv_cc_visibility_hidden=yes + ]) + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" + # TEA specific: for combined 32 & 64 bit fat builds of Tk + # extensions, verify that 64-bit build is possible. + AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [ + AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [ + AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [ + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' + done + CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" + LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11" + AC_TRY_LINK([#include ], [XrmInitialize();], + tcl_cv_lib_x11_64=yes, tcl_cv_lib_x11_64=no) + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval $v'="$hold_'$v'"' + done]) + ]) + AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [ + AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [ + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' + done + CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}" + LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}" + AC_TRY_LINK([#include ], [Tk_InitStubs(NULL, "", 0);], + tcl_cv_lib_tk_64=yes, tcl_cv_lib_tk_64=no) + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval $v'="$hold_'$v'"' + done]) + ]) + # remove 64-bit arch flags from CFLAGS et al. if configuration + # does not support 64-bit. + AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [ + AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags]) + for v in CFLAGS CPPFLAGS LDFLAGS; do + eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' + done]) + ]) + ;; + OS/390-*) + CFLAGS_OPTIMIZE="" # Optimizer is buggy + AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h + [Should OS/390 do the right thing with sockets?]) + ;; + OSF1-V*) + # Digital OSF/1 + SHLIB_CFLAGS="" + AS_IF([test "$SHARED_BUILD" = 1], [ + SHLIB_LD='ld -shared -expect_unresolved "*"' + ], [ + SHLIB_LD='ld -non_shared -expect_unresolved "*"' + ]) + SHLIB_SUFFIX=".so" + AS_IF([test $doRpath = yes], [ + CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) + AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [ + CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"]) + # see pthread_intro(3) for pthread support on osf1, k.furukawa + AS_IF([test "${TCL_THREADS}" = 1], [ + CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" + CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" + LIBS=`echo $LIBS | sed s/-lpthreads//` + AS_IF([test "$GCC" = yes], [ + LIBS="$LIBS -lpthread -lmach -lexc" + ], [ + CFLAGS="$CFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + ]) + ]) + ;; + QNX-6*) + # QNX RTP + # This may work for all QNX, but it was only reported for v6. + SHLIB_CFLAGS="-fPIC" + SHLIB_LD="ld -Bshareable -x" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + SCO_SV-3.2*) + AS_IF([test "$GCC" = yes], [ + SHLIB_CFLAGS="-fPIC -melf" + LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" + ], [ + SHLIB_CFLAGS="-Kpic -belf" + LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" + ]) + SHLIB_LD="ld -G" + SHLIB_LD_LIBS="" + SHLIB_SUFFIX=".so" + CC_SEARCH_FLAGS="" + LD_SEARCH_FLAGS="" + ;; + SunOS-5.[[0-6]]) + # Careful to not let 5.10+ fall into this case + + # Note: If _REENTRANT isn't defined, then Solaris + # won't define thread-safe library routines. + + AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) + AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, + [Do we really want to follow the standard? Yes we do!]) + + SHLIB_CFLAGS="-KPIC" + SHLIB_SUFFIX=".so" + AS_IF([test "$GCC" = yes], [ + SHLIB_LD='${CC} -shared' + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + ], [ + SHLIB_LD="/usr/ccs/bin/ld -G -z text" + CC_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + ]) + ;; + SunOS-5*) + # Note: If _REENTRANT isn't defined, then Solaris + # won't define thread-safe library routines. + + AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) + AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, + [Do we really want to follow the standard? Yes we do!]) + + SHLIB_CFLAGS="-KPIC" + + # Check to enable 64-bit flags for compiler/linker + AS_IF([test "$do64bit" = yes], [ + arch=`isainfo` + AS_IF([test "$arch" = "sparcv9 sparc"], [ + AS_IF([test "$GCC" = yes], [ + AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [ + AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system]) + ], [ + do64bit_ok=yes + CFLAGS="$CFLAGS -m64 -mcpu=v9" + LDFLAGS="$LDFLAGS -m64 -mcpu=v9" + SHLIB_CFLAGS="-fPIC" + ]) + ], [ + do64bit_ok=yes + AS_IF([test "$do64bitVIS" = yes], [ + CFLAGS="$CFLAGS -xarch=v9a" + LDFLAGS_ARCH="-xarch=v9a" + ], [ + CFLAGS="$CFLAGS -xarch=v9" + LDFLAGS_ARCH="-xarch=v9" + ]) + # Solaris 64 uses this as well + #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" + ]) + ], [AS_IF([test "$arch" = "amd64 i386"], [ + AS_IF([test "$GCC" = yes], [ + case $system in + SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) + do64bit_ok=yes + CFLAGS="$CFLAGS -m64" + LDFLAGS="$LDFLAGS -m64";; + *) + AC_MSG_WARN([64bit mode not supported with GCC on $system]);; + esac + ], [ + do64bit_ok=yes + case $system in + SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) + CFLAGS="$CFLAGS -m64" + LDFLAGS="$LDFLAGS -m64";; + *) + CFLAGS="$CFLAGS -xarch=amd64" + LDFLAGS="$LDFLAGS -xarch=amd64";; + esac + ]) + ], [AC_MSG_WARN([64bit mode not supported for $arch])])]) + ]) + + SHLIB_SUFFIX=".so" + AS_IF([test "$GCC" = yes], [ + SHLIB_LD='${CC} -shared' + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} + AS_IF([test "$do64bit_ok" = yes], [ + AS_IF([test "$arch" = "sparcv9 sparc"], [ + # We need to specify -static-libgcc or we need to + # add the path to the sparv9 libgcc. + # JH: static-libgcc is necessary for core Tcl, but may + # not be necessary for extensions. + SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" + # for finding sparcv9 libgcc, get the regular libgcc + # path, remove so name and append 'sparcv9' + #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." + #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" + ], [AS_IF([test "$arch" = "amd64 i386"], [ + # JH: static-libgcc is necessary for core Tcl, but may + # not be necessary for extensions. + SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" + ])]) + ]) + ], [ + case $system in + SunOS-5.[[1-9]][[0-9]]*) + # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS + SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';; + *) + SHLIB_LD='/usr/ccs/bin/ld -G -z text';; + esac + CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' + LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' + ]) + ;; + esac + + AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [ + AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform]) + ]) + +dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so +dnl # until the end of configure, as configure's compile and link tests use +dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's +dnl # preprocessing tests use only CPPFLAGS. + AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""]) + + # Add in the arch flags late to ensure it wasn't removed. + # Not necessary in TEA, but this is aligned with core + LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" + + # If we're running gcc, then change the C flags for compiling shared + # libraries to the right flags for gcc, instead of those for the + # standard manufacturer compiler. + + AS_IF([test "$GCC" = yes], [ + case $system in + AIX-*) ;; + BSD/OS*) ;; + CYGWIN_*) ;; + IRIX*) ;; + NetBSD-*|FreeBSD-*|OpenBSD-*) ;; + Darwin-*) ;; + SCO_SV-3.2*) ;; + windows) ;; + *) SHLIB_CFLAGS="-fPIC" ;; + esac]) + + AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ + AC_DEFINE(MODULE_SCOPE, [extern], + [No Compiler support for module scope symbols]) + AC_DEFINE(NO_VIZ, [], [No visibility hidden passed to zlib?]) + ]) + + AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [ + # TEA specific: use PACKAGE_VERSION instead of VERSION + SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}']) + AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [ + # TEA specific: use PACKAGE_VERSION instead of VERSION + UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a']) + + AC_SUBST(CFLAGS_DEBUG) + AC_SUBST(CFLAGS_OPTIMIZE) + AC_SUBST(CFLAGS_WARNING) + + AC_SUBST(STLIB_LD) + AC_SUBST(SHLIB_LD) + + AC_SUBST(SHLIB_LD_LIBS) + AC_SUBST(SHLIB_CFLAGS) + + AC_SUBST(LD_LIBRARY_PATH_VAR) + + # These must be called after we do the basic CFLAGS checks and + # verify any possible 64-bit or similar switches are necessary + TEA_TCL_EARLY_FLAGS + TEA_TCL_64BIT_FLAGS +]) + +#-------------------------------------------------------------------- +# TEA_SERIAL_PORT +# +# Determine which interface to use to talk to the serial port. +# Note that #include lines must begin in leftmost column for +# some compilers to recognize them as preprocessor directives, +# and some build environments have stdin not pointing at a +# pseudo-terminal (usually /dev/null instead.) +# +# Arguments: +# none +# +# Results: +# +# Defines only one of the following vars: +# HAVE_SYS_MODEM_H +# USE_TERMIOS +# USE_TERMIO +# USE_SGTTY +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_SERIAL_PORT], [ + AC_CHECK_HEADERS(sys/modem.h) + AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [ + AC_TRY_RUN([ +#include + +int main() { + struct termios t; + if (tcgetattr(0, &t) == 0) { + cfsetospeed(&t, 0); + t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; + return 0; + } + return 1; +}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) + if test $tcl_cv_api_serial = no ; then + AC_TRY_RUN([ +#include + +int main() { + struct termio t; + if (ioctl(0, TCGETA, &t) == 0) { + t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; + return 0; + } + return 1; +}], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) + fi + if test $tcl_cv_api_serial = no ; then + AC_TRY_RUN([ +#include + +int main() { + struct sgttyb t; + if (ioctl(0, TIOCGETP, &t) == 0) { + t.sg_ospeed = 0; + t.sg_flags |= ODDP | EVENP | RAW; + return 0; + } + return 1; +}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=no, tcl_cv_api_serial=no) + fi + if test $tcl_cv_api_serial = no ; then + AC_TRY_RUN([ +#include +#include + +int main() { + struct termios t; + if (tcgetattr(0, &t) == 0 + || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { + cfsetospeed(&t, 0); + t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; + return 0; + } + return 1; +}], tcl_cv_api_serial=termios, tcl_cv_api_serial=no, tcl_cv_api_serial=no) + fi + if test $tcl_cv_api_serial = no; then + AC_TRY_RUN([ +#include +#include + +int main() { + struct termio t; + if (ioctl(0, TCGETA, &t) == 0 + || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { + t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; + return 0; + } + return 1; + }], tcl_cv_api_serial=termio, tcl_cv_api_serial=no, tcl_cv_api_serial=no) + fi + if test $tcl_cv_api_serial = no; then + AC_TRY_RUN([ +#include +#include + +int main() { + struct sgttyb t; + if (ioctl(0, TIOCGETP, &t) == 0 + || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { + t.sg_ospeed = 0; + t.sg_flags |= ODDP | EVENP | RAW; + return 0; + } + return 1; +}], tcl_cv_api_serial=sgtty, tcl_cv_api_serial=none, tcl_cv_api_serial=none) + fi]) + case $tcl_cv_api_serial in + termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);; + termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);; + sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);; + esac +]) + +#-------------------------------------------------------------------- +# TEA_MISSING_POSIX_HEADERS +# +# Supply substitutes for missing POSIX header files. Special +# notes: +# - stdlib.h doesn't define strtol, strtoul, or +# strtod in some versions of SunOS +# - some versions of string.h don't declare procedures such +# as strstr +# +# Arguments: +# none +# +# Results: +# +# Defines some of the following vars: +# NO_DIRENT_H +# NO_ERRNO_H +# NO_VALUES_H +# HAVE_LIMITS_H or NO_LIMITS_H +# NO_STDLIB_H +# NO_STRING_H +# NO_SYS_WAIT_H +# NO_DLFCN_H +# HAVE_SYS_PARAM_H +# +# HAVE_STRING_H ? +# +# tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and +# CHECK on limits.h +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_MISSING_POSIX_HEADERS], [ + AC_CACHE_CHECK([dirent.h], tcl_cv_dirent_h, [ + AC_TRY_LINK([#include +#include ], [ +#ifndef _POSIX_SOURCE +# ifdef __Lynx__ + /* + * Generate compilation error to make the test fail: Lynx headers + * are only valid if really in the POSIX environment. + */ + + missing_procedure(); +# endif +#endif +DIR *d; +struct dirent *entryPtr; +char *p; +d = opendir("foobar"); +entryPtr = readdir(d); +p = entryPtr->d_name; +closedir(d); +], tcl_cv_dirent_h=yes, tcl_cv_dirent_h=no)]) + + if test $tcl_cv_dirent_h = no; then + AC_DEFINE(NO_DIRENT_H, 1, [Do we have ?]) + fi + + # TEA specific: + AC_CHECK_HEADER(errno.h, , [AC_DEFINE(NO_ERRNO_H, 1, [Do we have ?])]) + AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have ?])]) + AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have ?])]) + AC_CHECK_HEADER(limits.h, + [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have ?])], + [AC_DEFINE(NO_LIMITS_H, 1, [Do we have ?])]) + AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0) + AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0) + AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0) + AC_EGREP_HEADER(strtod, stdlib.h, , tcl_ok=0) + if test $tcl_ok = 0; then + AC_DEFINE(NO_STDLIB_H, 1, [Do we have ?]) + fi + AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0) + AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0) + AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0) + + # See also memmove check below for a place where NO_STRING_H can be + # set and why. + + if test $tcl_ok = 0; then + AC_DEFINE(NO_STRING_H, 1, [Do we have ?]) + fi + + AC_CHECK_HEADER(sys/wait.h, , [AC_DEFINE(NO_SYS_WAIT_H, 1, [Do we have ?])]) + AC_CHECK_HEADER(dlfcn.h, , [AC_DEFINE(NO_DLFCN_H, 1, [Do we have ?])]) + + # OS/390 lacks sys/param.h (and doesn't need it, by chance). + AC_HAVE_HEADERS(sys/param.h) +]) + +#-------------------------------------------------------------------- +# TEA_PATH_X +# +# Locate the X11 header files and the X11 library archive. Try +# the ac_path_x macro first, but if it doesn't find the X stuff +# (e.g. because there's no xmkmf program) then check through +# a list of possible directories. Under some conditions the +# autoconf macro will return an include directory that contains +# no include files, so double-check its result just to be safe. +# +# This should be called after TEA_CONFIG_CFLAGS as setting the +# LIBS line can confuse some configure macro magic. +# +# Arguments: +# none +# +# Results: +# +# Sets the following vars: +# XINCLUDES +# XLIBSW +# PKG_LIBS (appends to) +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_PATH_X], [ + if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then + TEA_PATH_UNIX_X + fi +]) + +AC_DEFUN([TEA_PATH_UNIX_X], [ + AC_PATH_X + not_really_there="" + if test "$no_x" = ""; then + if test "$x_includes" = ""; then + AC_TRY_CPP([#include ], , not_really_there="yes") + else + if test ! -r $x_includes/X11/Intrinsic.h; then + not_really_there="yes" + fi + fi + fi + if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then + AC_MSG_CHECKING([for X11 header files]) + found_xincludes="no" + AC_TRY_CPP([#include ], found_xincludes="yes", found_xincludes="no") + if test "$found_xincludes" = "no"; then + dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" + for i in $dirs ; do + if test -r $i/X11/Intrinsic.h; then + AC_MSG_RESULT([$i]) + XINCLUDES=" -I$i" + found_xincludes="yes" + break + fi + done + fi + else + if test "$x_includes" != ""; then + XINCLUDES="-I$x_includes" + found_xincludes="yes" + fi + fi + if test "$found_xincludes" = "no"; then + AC_MSG_RESULT([couldn't find any!]) + fi + + if test "$no_x" = yes; then + AC_MSG_CHECKING([for X11 libraries]) + XLIBSW=nope + dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" + for i in $dirs ; do + if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then + AC_MSG_RESULT([$i]) + XLIBSW="-L$i -lX11" + x_libraries="$i" + break + fi + done + else + if test "$x_libraries" = ""; then + XLIBSW=-lX11 + else + XLIBSW="-L$x_libraries -lX11" + fi + fi + if test "$XLIBSW" = nope ; then + AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) + fi + if test "$XLIBSW" = nope ; then + AC_MSG_RESULT([could not find any! Using -lX11.]) + XLIBSW=-lX11 + fi + # TEA specific: + if test x"${XLIBSW}" != x ; then + PKG_LIBS="${PKG_LIBS} ${XLIBSW}" + fi +]) + +#-------------------------------------------------------------------- +# TEA_BLOCKING_STYLE +# +# The statements below check for systems where POSIX-style +# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. +# On these systems (mostly older ones), use the old BSD-style +# FIONBIO approach instead. +# +# Arguments: +# none +# +# Results: +# +# Defines some of the following vars: +# HAVE_SYS_IOCTL_H +# HAVE_SYS_FILIO_H +# USE_FIONBIO +# O_NONBLOCK +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_BLOCKING_STYLE], [ + AC_CHECK_HEADERS(sys/ioctl.h) + AC_CHECK_HEADERS(sys/filio.h) + TEA_CONFIG_SYSTEM + AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O]) + case $system in + OSF*) + AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) + AC_MSG_RESULT([FIONBIO]) + ;; + *) + AC_MSG_RESULT([O_NONBLOCK]) + ;; + esac +]) + +#-------------------------------------------------------------------- +# TEA_TIME_HANDLER +# +# Checks how the system deals with time.h, what time structures +# are used on the system, and what fields the structures have. +# +# Arguments: +# none +# +# Results: +# +# Defines some of the following vars: +# USE_DELTA_FOR_TZ +# HAVE_TM_GMTOFF +# HAVE_TM_TZADJ +# HAVE_TIMEZONE_VAR +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_TIME_HANDLER], [ + AC_CHECK_HEADERS(sys/time.h) + AC_HEADER_TIME + AC_STRUCT_TIMEZONE + + AC_CHECK_FUNCS(gmtime_r localtime_r) + + AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [ + AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_tzadj;], + tcl_cv_member_tm_tzadj=yes, tcl_cv_member_tm_tzadj=no)]) + if test $tcl_cv_member_tm_tzadj = yes ; then + AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?]) + fi + + AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [ + AC_TRY_COMPILE([#include ], [struct tm tm; tm.tm_gmtoff;], + tcl_cv_member_tm_gmtoff=yes, tcl_cv_member_tm_gmtoff=no)]) + if test $tcl_cv_member_tm_gmtoff = yes ; then + AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?]) + fi + + # + # Its important to include time.h in this check, as some systems + # (like convex) have timezone functions, etc. + # + AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [ + AC_TRY_COMPILE([#include ], + [extern long timezone; + timezone += 1; + exit (0);], + tcl_cv_timezone_long=yes, tcl_cv_timezone_long=no)]) + if test $tcl_cv_timezone_long = yes ; then + AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) + else + # + # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. + # + AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [ + AC_TRY_COMPILE([#include ], + [extern time_t timezone; + timezone += 1; + exit (0);], + tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)]) + if test $tcl_cv_timezone_time = yes ; then + AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) + fi + fi +]) + +#-------------------------------------------------------------------- +# TEA_BUGGY_STRTOD +# +# Under Solaris 2.4, strtod returns the wrong value for the +# terminating character under some conditions. Check for this +# and if the problem exists use a substitute procedure +# "fixstrtod" (provided by Tcl) that corrects the error. +# Also, on Compaq's Tru64 Unix 5.0, +# strtod(" ") returns 0.0 instead of a failure to convert. +# +# Arguments: +# none +# +# Results: +# +# Might defines some of the following vars: +# strtod (=fixstrtod) +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_BUGGY_STRTOD], [ + AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0) + if test "$tcl_strtod" = 1; then + AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[ + AC_TRY_RUN([ + extern double strtod(); + int main() { + char *infString="Inf", *nanString="NaN", *spaceString=" "; + char *term; + double value; + value = strtod(infString, &term); + if ((term != infString) && (term[-1] == 0)) { + exit(1); + } + value = strtod(nanString, &term); + if ((term != nanString) && (term[-1] == 0)) { + exit(1); + } + value = strtod(spaceString, &term); + if (term == (spaceString+1)) { + exit(1); + } + exit(0); + }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy, + tcl_cv_strtod_buggy=buggy)]) + if test "$tcl_cv_strtod_buggy" = buggy; then + AC_LIBOBJ([fixstrtod]) + USE_COMPAT=1 + AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?]) + fi + fi +]) + +#-------------------------------------------------------------------- +# TEA_TCL_LINK_LIBS +# +# Search for the libraries needed to link the Tcl shell. +# Things like the math library (-lm) and socket stuff (-lsocket vs. +# -lnsl) are dealt with here. +# +# Arguments: +# Requires the following vars to be set in the Makefile: +# DL_LIBS (not in TEA, only needed in core) +# LIBS +# MATH_LIBS +# +# Results: +# +# Subst's the following var: +# TCL_LIBS +# MATH_LIBS +# +# Might append to the following vars: +# LIBS +# +# Might define the following vars: +# HAVE_NET_ERRNO_H +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_TCL_LINK_LIBS], [ + #-------------------------------------------------------------------- + # On a few very rare systems, all of the libm.a stuff is + # already in libc.a. Set compiler flags accordingly. + # Also, Linux requires the "ieee" library for math to work + # right (and it must appear before "-lm"). + #-------------------------------------------------------------------- + + AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") + AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"]) + + #-------------------------------------------------------------------- + # Interactive UNIX requires -linet instead of -lsocket, plus it + # needs net/errno.h to define the socket-related error codes. + #-------------------------------------------------------------------- + + AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"]) + AC_CHECK_HEADER(net/errno.h, [ + AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have ?])]) + + #-------------------------------------------------------------------- + # Check for the existence of the -lsocket and -lnsl libraries. + # The order here is important, so that they end up in the right + # order in the command line generated by make. Here are some + # special considerations: + # 1. Use "connect" and "accept" to check for -lsocket, and + # "gethostbyname" to check for -lnsl. + # 2. Use each function name only once: can't redo a check because + # autoconf caches the results of the last check and won't redo it. + # 3. Use -lnsl and -lsocket only if they supply procedures that + # aren't already present in the normal libraries. This is because + # IRIX 5.2 has libraries, but they aren't needed and they're + # bogus: they goof up name resolution if used. + # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. + # To get around this problem, check for both libraries together + # if -lsocket doesn't work by itself. + #-------------------------------------------------------------------- + + tcl_checkBoth=0 + AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1) + if test "$tcl_checkSocket" = 1; then + AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt, + LIBS="$LIBS -lsocket", tcl_checkBoth=1)]) + fi + if test "$tcl_checkBoth" = 1; then + tk_oldLibs=$LIBS + LIBS="$LIBS -lsocket -lnsl" + AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs]) + fi + AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, + [LIBS="$LIBS -lnsl"])]) + + # TEA specific: Don't perform the eval of the libraries here because + # DL_LIBS won't be set until we call TEA_CONFIG_CFLAGS + + TCL_LIBS='${DL_LIBS} ${LIBS} ${MATH_LIBS}' + AC_SUBST(TCL_LIBS) + AC_SUBST(MATH_LIBS) +]) + +#-------------------------------------------------------------------- +# TEA_TCL_EARLY_FLAGS +# +# Check for what flags are needed to be passed so the correct OS +# features are available. +# +# Arguments: +# None +# +# Results: +# +# Might define the following vars: +# _ISOC99_SOURCE +# _LARGEFILE64_SOURCE +# _LARGEFILE_SOURCE64 +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_TCL_EARLY_FLAG],[ + AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), + AC_TRY_COMPILE([$2], $3, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no, + AC_TRY_COMPILE([[#define ]$1[ 1 +]$2], $3, + [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, + [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no))) + if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then + AC_DEFINE($1, 1, [Add the ]$1[ flag when building]) + tcl_flags="$tcl_flags $1" + fi +]) + +AC_DEFUN([TEA_TCL_EARLY_FLAGS],[ + AC_MSG_CHECKING([for required early compiler flags]) + tcl_flags="" + TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include ], + [char *p = (char *)strtoll; char *q = (char *)strtoull;]) + TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include ], + [struct stat64 buf; int i = stat64("/", &buf);]) + TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include ], + [char *p = (char *)open64;]) + if test "x${tcl_flags}" = "x" ; then + AC_MSG_RESULT([none]) + else + AC_MSG_RESULT([${tcl_flags}]) + fi +]) + +#-------------------------------------------------------------------- +# TEA_TCL_64BIT_FLAGS +# +# Check for what is defined in the way of 64-bit features. +# +# Arguments: +# None +# +# Results: +# +# Might define the following vars: +# TCL_WIDE_INT_IS_LONG +# TCL_WIDE_INT_TYPE +# HAVE_STRUCT_DIRENT64 +# HAVE_STRUCT_STAT64 +# HAVE_TYPE_OFF64_T +# +#-------------------------------------------------------------------- + +AC_DEFUN([TEA_TCL_64BIT_FLAGS], [ + AC_MSG_CHECKING([for 64-bit integer type]) + AC_CACHE_VAL(tcl_cv_type_64bit,[ + tcl_cv_type_64bit=none + # See if the compiler knows natively about __int64 + AC_TRY_COMPILE(,[__int64 value = (__int64) 0;], + tcl_type_64bit=__int64, tcl_type_64bit="long long") + # See if we should use long anyway Note that we substitute in the + # type that is our current guess for a 64-bit type inside this check + # program, so it should be modified only carefully... + AC_TRY_COMPILE(,[switch (0) { + case 1: case (sizeof(]${tcl_type_64bit}[)==sizeof(long)): ; + }],tcl_cv_type_64bit=${tcl_type_64bit})]) + if test "${tcl_cv_type_64bit}" = none ; then + AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Are wide integers to be implemented with C 'long's?]) + AC_MSG_RESULT([using long]) + elif test "${tcl_cv_type_64bit}" = "__int64" \ + -a "${TEA_PLATFORM}" = "windows" ; then + # TEA specific: We actually want to use the default tcl.h checks in + # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* + AC_MSG_RESULT([using Tcl header defaults]) + else + AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit}, + [What type should be used to define wide integers?]) + AC_MSG_RESULT([${tcl_cv_type_64bit}]) + + # Now check for auxiliary declarations + AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ + AC_TRY_COMPILE([#include +#include ],[struct dirent64 p;], + tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)]) + if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) + fi + + AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ + AC_TRY_COMPILE([#include ],[struct stat64 p; +], + tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)]) + if test "x${tcl_cv_struct_stat64}" = "xyes" ; then + AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in ?]) + fi + + AC_CHECK_FUNCS(open64 lseek64) + AC_MSG_CHECKING([for off64_t]) + AC_CACHE_VAL(tcl_cv_type_off64_t,[ + AC_TRY_COMPILE([#include ],[off64_t offset; +], + tcl_cv_type_off64_t=yes,tcl_cv_type_off64_t=no)]) + dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the + dnl functions lseek64 and open64 are defined. + if test "x${tcl_cv_type_off64_t}" = "xyes" && \ + test "x${ac_cv_func_lseek64}" = "xyes" && \ + test "x${ac_cv_func_open64}" = "xyes" ; then + AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in ?]) + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi +]) + +## +## Here ends the standard Tcl configuration bits and starts the +## TEA specific functions +## + +#------------------------------------------------------------------------ +# TEA_INIT -- +# +# Init various Tcl Extension Architecture (TEA) variables. +# This should be the first called TEA_* macro. +# +# Arguments: +# none +# +# Results: +# +# Defines and substs the following vars: +# CYGPATH +# EXEEXT +# Defines only: +# TEA_VERSION +# TEA_INITED +# TEA_PLATFORM (windows or unix) +# +# "cygpath" is used on windows to generate native path names for include +# files. These variables should only be used with the compiler and linker +# since they generate native path names. +# +# EXEEXT +# Select the executable extension based on the host type. This +# is a lightweight replacement for AC_EXEEXT that doesn't require +# a compiler. +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_INIT], [ + # TEA extensions pass this us the version of TEA they think they + # are compatible with. + TEA_VERSION="3.9" + + AC_MSG_CHECKING([for correct TEA configuration]) + if test x"${PACKAGE_NAME}" = x ; then + AC_MSG_ERROR([ +The PACKAGE_NAME variable must be defined by your TEA configure.in]) + fi + if test x"$1" = x ; then + AC_MSG_ERROR([ +TEA version not specified.]) + elif test "$1" != "${TEA_VERSION}" ; then + AC_MSG_RESULT([warning: requested TEA version "$1", have "${TEA_VERSION}"]) + else + AC_MSG_RESULT([ok (TEA ${TEA_VERSION})]) + fi + case "`uname -s`" in + *win32*|*WIN32*|*MINGW32_*) + AC_CHECK_PROG(CYGPATH, cygpath, cygpath -w, echo) + EXEEXT=".exe" + TEA_PLATFORM="windows" + ;; + *CYGWIN_*) + CYGPATH=echo + EXEEXT=".exe" + # TEA_PLATFORM is determined later in LOAD_TCLCONFIG + ;; + *) + CYGPATH=echo + # Maybe we are cross-compiling.... + case ${host_alias} in + *mingw32*) + EXEEXT=".exe" + TEA_PLATFORM="windows" + ;; + *) + EXEEXT="" + TEA_PLATFORM="unix" + ;; + esac + ;; + esac + + # Check if exec_prefix is set. If not use fall back to prefix. + # Note when adjusted, so that TEA_PREFIX can correct for this. + # This is needed for recursive configures, since autoconf propagates + # $prefix, but not $exec_prefix (doh!). + if test x$exec_prefix = xNONE ; then + exec_prefix_default=yes + exec_prefix=$prefix + fi + + AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}]) + + AC_SUBST(EXEEXT) + AC_SUBST(CYGPATH) + + # This package name must be replaced statically for AC_SUBST to work + AC_SUBST(PKG_LIB_FILE) + # Substitute STUB_LIB_FILE in case package creates a stub library too. + AC_SUBST(PKG_STUB_LIB_FILE) + + # We AC_SUBST these here to ensure they are subst'ed, + # in case the user doesn't call TEA_ADD_... + AC_SUBST(PKG_STUB_SOURCES) + AC_SUBST(PKG_STUB_OBJECTS) + AC_SUBST(PKG_TCL_SOURCES) + AC_SUBST(PKG_HEADERS) + AC_SUBST(PKG_INCLUDES) + AC_SUBST(PKG_LIBS) + AC_SUBST(PKG_CFLAGS) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_SOURCES -- +# +# Specify one or more source files. Users should check for +# the right platform before adding to their list. +# It is not important to specify the directory, as long as it is +# in the generic, win or unix subdirectory of $(srcdir). +# +# Arguments: +# one or more file names +# +# Results: +# +# Defines and substs the following vars: +# PKG_SOURCES +# PKG_OBJECTS +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_SOURCES], [ + vars="$@" + for i in $vars; do + case $i in + [\$]*) + # allow $-var names + PKG_SOURCES="$PKG_SOURCES $i" + PKG_OBJECTS="$PKG_OBJECTS $i" + ;; + *) + # check for existence - allows for generic/win/unix VPATH + # To add more dirs here (like 'src'), you have to update VPATH + # in Makefile.in as well + if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ + -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ + -a ! -f "${srcdir}/macosx/$i" \ + ; then + AC_MSG_ERROR([could not find source file '$i']) + fi + PKG_SOURCES="$PKG_SOURCES $i" + # this assumes it is in a VPATH dir + i=`basename $i` + # handle user calling this before or after TEA_SETUP_COMPILER + if test x"${OBJEXT}" != x ; then + j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" + else + j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" + fi + PKG_OBJECTS="$PKG_OBJECTS $j" + ;; + esac + done + AC_SUBST(PKG_SOURCES) + AC_SUBST(PKG_OBJECTS) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_STUB_SOURCES -- +# +# Specify one or more source files. Users should check for +# the right platform before adding to their list. +# It is not important to specify the directory, as long as it is +# in the generic, win or unix subdirectory of $(srcdir). +# +# Arguments: +# one or more file names +# +# Results: +# +# Defines and substs the following vars: +# PKG_STUB_SOURCES +# PKG_STUB_OBJECTS +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_STUB_SOURCES], [ + vars="$@" + for i in $vars; do + # check for existence - allows for generic/win/unix VPATH + if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ + -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ + -a ! -f "${srcdir}/macosx/$i" \ + ; then + AC_MSG_ERROR([could not find stub source file '$i']) + fi + PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" + # this assumes it is in a VPATH dir + i=`basename $i` + # handle user calling this before or after TEA_SETUP_COMPILER + if test x"${OBJEXT}" != x ; then + j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" + else + j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" + fi + PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" + done + AC_SUBST(PKG_STUB_SOURCES) + AC_SUBST(PKG_STUB_OBJECTS) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_TCL_SOURCES -- +# +# Specify one or more Tcl source files. These should be platform +# independent runtime files. +# +# Arguments: +# one or more file names +# +# Results: +# +# Defines and substs the following vars: +# PKG_TCL_SOURCES +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_TCL_SOURCES], [ + vars="$@" + for i in $vars; do + # check for existence, be strict because it is installed + if test ! -f "${srcdir}/$i" ; then + AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i']) + fi + PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" + done + AC_SUBST(PKG_TCL_SOURCES) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_HEADERS -- +# +# Specify one or more source headers. Users should check for +# the right platform before adding to their list. +# +# Arguments: +# one or more file names +# +# Results: +# +# Defines and substs the following vars: +# PKG_HEADERS +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_HEADERS], [ + vars="$@" + for i in $vars; do + # check for existence, be strict because it is installed + if test ! -f "${srcdir}/$i" ; then + AC_MSG_ERROR([could not find header file '${srcdir}/$i']) + fi + PKG_HEADERS="$PKG_HEADERS $i" + done + AC_SUBST(PKG_HEADERS) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_INCLUDES -- +# +# Specify one or more include dirs. Users should check for +# the right platform before adding to their list. +# +# Arguments: +# one or more file names +# +# Results: +# +# Defines and substs the following vars: +# PKG_INCLUDES +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_INCLUDES], [ + vars="$@" + for i in $vars; do + PKG_INCLUDES="$PKG_INCLUDES $i" + done + AC_SUBST(PKG_INCLUDES) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_LIBS -- +# +# Specify one or more libraries. Users should check for +# the right platform before adding to their list. For Windows, +# libraries provided in "foo.lib" format will be converted to +# "-lfoo" when using GCC (mingw). +# +# Arguments: +# one or more file names +# +# Results: +# +# Defines and substs the following vars: +# PKG_LIBS +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_LIBS], [ + vars="$@" + for i in $vars; do + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then + # Convert foo.lib to -lfoo for GCC. No-op if not *.lib + i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.lib[$]/-l\1/i'` + fi + PKG_LIBS="$PKG_LIBS $i" + done + AC_SUBST(PKG_LIBS) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_CFLAGS -- +# +# Specify one or more CFLAGS. Users should check for +# the right platform before adding to their list. +# +# Arguments: +# one or more file names +# +# Results: +# +# Defines and substs the following vars: +# PKG_CFLAGS +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_CFLAGS], [ + PKG_CFLAGS="$PKG_CFLAGS $@" + AC_SUBST(PKG_CFLAGS) +]) + +#------------------------------------------------------------------------ +# TEA_ADD_CLEANFILES -- +# +# Specify one or more CLEANFILES. +# +# Arguments: +# one or more file names to clean target +# +# Results: +# +# Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG +#------------------------------------------------------------------------ +AC_DEFUN([TEA_ADD_CLEANFILES], [ + CLEANFILES="$CLEANFILES $@" +]) + +#------------------------------------------------------------------------ +# TEA_PREFIX -- +# +# Handle the --prefix=... option by defaulting to what Tcl gave +# +# Arguments: +# none +# +# Results: +# +# If --prefix or --exec-prefix was not specified, $prefix and +# $exec_prefix will be set to the values given to Tcl when it was +# configured. +#------------------------------------------------------------------------ +AC_DEFUN([TEA_PREFIX], [ + if test "${prefix}" = "NONE"; then + prefix_default=yes + if test x"${TCL_PREFIX}" != x; then + AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}]) + prefix=${TCL_PREFIX} + else + AC_MSG_NOTICE([--prefix defaulting to /usr/local]) + prefix=/usr/local + fi + fi + if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ + -o x"${exec_prefix_default}" = x"yes" ; then + if test x"${TCL_EXEC_PREFIX}" != x; then + AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) + exec_prefix=${TCL_EXEC_PREFIX} + else + AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}]) + exec_prefix=$prefix + fi + fi +]) + +#------------------------------------------------------------------------ +# TEA_SETUP_COMPILER_CC -- +# +# Do compiler checks the way we want. This is just a replacement +# for AC_PROG_CC in TEA configure.in files to make them cleaner. +# +# Arguments: +# none +# +# Results: +# +# Sets up CC var and other standard bits we need to make executables. +#------------------------------------------------------------------------ +AC_DEFUN([TEA_SETUP_COMPILER_CC], [ + # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) + # in this macro, they need to go into TEA_SETUP_COMPILER instead. + + # If the user did not set CFLAGS, set it now to keep + # the AC_PROG_CC macro from adding "-g -O2". + if test "${CFLAGS+set}" != "set" ; then + CFLAGS="" + fi + + AC_PROG_CC + AC_PROG_CPP + + #-------------------------------------------------------------------- + # Checks to see if the make program sets the $MAKE variable. + #-------------------------------------------------------------------- + + AC_PROG_MAKE_SET + + #-------------------------------------------------------------------- + # Find ranlib + #-------------------------------------------------------------------- + + AC_CHECK_TOOL(RANLIB, ranlib) + + #-------------------------------------------------------------------- + # Determines the correct binary file extension (.o, .obj, .exe etc.) + #-------------------------------------------------------------------- + + AC_OBJEXT + AC_EXEEXT +]) + +#------------------------------------------------------------------------ +# TEA_SETUP_COMPILER -- +# +# Do compiler checks that use the compiler. This must go after +# TEA_SETUP_COMPILER_CC, which does the actual compiler check. +# +# Arguments: +# none +# +# Results: +# +# Sets up CC var and other standard bits we need to make executables. +#------------------------------------------------------------------------ +AC_DEFUN([TEA_SETUP_COMPILER], [ + # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. + AC_REQUIRE([TEA_SETUP_COMPILER_CC]) + + #------------------------------------------------------------------------ + # If we're using GCC, see if the compiler understands -pipe. If so, use it. + # It makes compiling go faster. (This is only a performance feature.) + #------------------------------------------------------------------------ + + if test -z "$no_pipe" -a -n "$GCC"; then + AC_CACHE_CHECK([if the compiler understands -pipe], + tcl_cv_cc_pipe, [ + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" + AC_TRY_COMPILE(,, tcl_cv_cc_pipe=yes, tcl_cv_cc_pipe=no) + CFLAGS=$hold_cflags]) + if test $tcl_cv_cc_pipe = yes; then + CFLAGS="$CFLAGS -pipe" + fi + fi + + #-------------------------------------------------------------------- + # Common compiler flag setup + #-------------------------------------------------------------------- + + AC_C_BIGENDIAN + if test "${TEA_PLATFORM}" = "unix" ; then + TEA_TCL_LINK_LIBS + TEA_MISSING_POSIX_HEADERS + # Let the user call this, because if it triggers, they will + # need a compat/strtod.c that is correct. Users can also + # use Tcl_GetDouble(FromObj) instead. + #TEA_BUGGY_STRTOD + fi +]) + +#------------------------------------------------------------------------ +# TEA_MAKE_LIB -- +# +# Generate a line that can be used to build a shared/unshared library +# in a platform independent manner. +# +# Arguments: +# none +# +# Requires: +# +# Results: +# +# Defines the following vars: +# CFLAGS - Done late here to note disturb other AC macros +# MAKE_LIB - Command to execute to build the Tcl library; +# differs depending on whether or not Tcl is being +# compiled as a shared library. +# MAKE_SHARED_LIB Makefile rule for building a shared library +# MAKE_STATIC_LIB Makefile rule for building a static library +# MAKE_STUB_LIB Makefile rule for building a stub library +# VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL +# VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_MAKE_LIB], [ + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then + MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)" + MAKE_SHARED_LIB="\${SHLIB_LD} \${SHLIB_LD_LIBS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS)" + AC_EGREP_CPP([manifest needed], [ +#if defined(_MSC_VER) && _MSC_VER >= 1400 +print("manifest needed") +#endif + ], [ + # Could do a CHECK_PROG for mt, but should always be with MSVC8+ + VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi" + VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi" + MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}" + TEA_ADD_CLEANFILES([*.manifest]) + ]) + MAKE_STUB_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_STUB_OBJECTS)" + else + MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)" + MAKE_SHARED_LIB="\${SHLIB_LD} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" + MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)" + fi + + if test "${SHARED_BUILD}" = "1" ; then + MAKE_LIB="${MAKE_SHARED_LIB} " + else + MAKE_LIB="${MAKE_STATIC_LIB} " + fi + + #-------------------------------------------------------------------- + # Shared libraries and static libraries have different names. + # Use the double eval to make sure any variables in the suffix is + # substituted. (@@@ Might not be necessary anymore) + #-------------------------------------------------------------------- + + if test "${TEA_PLATFORM}" = "windows" ; then + if test "${SHARED_BUILD}" = "1" ; then + # We force the unresolved linking of symbols that are really in + # the private libraries of Tcl and Tk. + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" + if test x"${TK_BIN_DIR}" != x ; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" + fi + eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" + else + eval eval "PKG_LIB_FILE=${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" + fi + # Some packages build their own stubs libraries + eval eval "PKG_STUB_LIB_FILE=${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" + if test "$GCC" = "yes"; then + PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE} + fi + # These aren't needed on Windows (either MSVC or gcc) + RANLIB=: + RANLIB_STUB=: + else + RANLIB_STUB="${RANLIB}" + if test "${SHARED_BUILD}" = "1" ; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}" + if test x"${TK_BIN_DIR}" != x ; then + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" + fi + eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" + RANLIB=: + else + eval eval "PKG_LIB_FILE=lib${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" + fi + # Some packages build their own stubs libraries + eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" + fi + + # These are escaped so that only CFLAGS is picked up at configure time. + # The other values will be substituted at make time. + CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" + if test "${SHARED_BUILD}" = "1" ; then + CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" + fi + + AC_SUBST(MAKE_LIB) + AC_SUBST(MAKE_SHARED_LIB) + AC_SUBST(MAKE_STATIC_LIB) + AC_SUBST(MAKE_STUB_LIB) + AC_SUBST(RANLIB_STUB) + AC_SUBST(VC_MANIFEST_EMBED_DLL) + AC_SUBST(VC_MANIFEST_EMBED_EXE) +]) + +#------------------------------------------------------------------------ +# TEA_LIB_SPEC -- +# +# Compute the name of an existing object library located in libdir +# from the given base name and produce the appropriate linker flags. +# +# Arguments: +# basename The base name of the library without version +# numbers, extensions, or "lib" prefixes. +# extra_dir Extra directory in which to search for the +# library. This location is used first, then +# $prefix/$exec-prefix, then some defaults. +# +# Requires: +# TEA_INIT and TEA_PREFIX must be called first. +# +# Results: +# +# Defines the following vars: +# ${basename}_LIB_NAME The computed library name. +# ${basename}_LIB_SPEC The computed linker flags. +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_LIB_SPEC], [ + AC_MSG_CHECKING([for $1 library]) + + # Look in exec-prefix for the library (defined by TEA_PREFIX). + + tea_lib_name_dir="${exec_prefix}/lib" + + # Or in a user-specified location. + + if test x"$2" != x ; then + tea_extra_lib_dir=$2 + else + tea_extra_lib_dir=NONE + fi + + for i in \ + `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ + `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \ + `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ + `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \ + `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \ + `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \ + `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \ + `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \ + `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \ + `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do + if test -f "$i" ; then + tea_lib_name_dir=`dirname $i` + $1_LIB_NAME=`basename $i` + $1_LIB_PATH_NAME=$i + break + fi + done + + if test "${TEA_PLATFORM}" = "windows"; then + $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\" + else + # Strip off the leading "lib" and trailing ".a" or ".so" + + tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'` + $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}" + fi + + if test "x${$1_LIB_NAME}" = x ; then + AC_MSG_ERROR([not found]) + else + AC_MSG_RESULT([${$1_LIB_SPEC}]) + fi +]) + +#------------------------------------------------------------------------ +# TEA_PRIVATE_TCL_HEADERS -- +# +# Locate the private Tcl include files +# +# Arguments: +# +# Requires: +# TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has +# already been called. +# +# Results: +# +# Substs the following vars: +# TCL_TOP_DIR_NATIVE +# TCL_INCLUDES +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [ + # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh} + AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS]) + AC_MSG_CHECKING([for Tcl private include files]) + + TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}` + TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\" + + # Check to see if tclPort.h isn't already with the public headers + # Don't look for tclInt.h because that resides with tcl.h in the core + # sources, but the Port headers are in a different directory + if test "${TEA_PLATFORM}" = "windows" -a \ + -f "${ac_cv_c_tclh}/tclWinPort.h"; then + result="private headers found with public headers" + elif test "${TEA_PLATFORM}" = "unix" -a \ + -f "${ac_cv_c_tclh}/tclUnixPort.h"; then + result="private headers found with public headers" + else + TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\" + if test "${TEA_PLATFORM}" = "windows"; then + TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\" + else + TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\" + fi + # Overwrite the previous TCL_INCLUDES as this should capture both + # public and private headers in the same set. + # We want to ensure these are substituted so as not to require + # any *_NATIVE vars be defined in the Makefile + TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}" + if test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use + # the framework's Headers and PrivateHeaders directories + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + if test -d "${TCL_BIN_DIR}/Headers" -a \ + -d "${TCL_BIN_DIR}/PrivateHeaders"; then + TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}" + else + TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" + fi + ;; + esac + result="Using ${TCL_INCLUDES}" + else + if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then + AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}]) + fi + result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" + fi + fi + + AC_SUBST(TCL_TOP_DIR_NATIVE) + + AC_SUBST(TCL_INCLUDES) + AC_MSG_RESULT([${result}]) +]) + +#------------------------------------------------------------------------ +# TEA_PUBLIC_TCL_HEADERS -- +# +# Locate the installed public Tcl header files +# +# Arguments: +# None. +# +# Requires: +# CYGPATH must be set +# +# Results: +# +# Adds a --with-tclinclude switch to configure. +# Result is cached. +# +# Substs the following vars: +# TCL_INCLUDES +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [ + AC_MSG_CHECKING([for Tcl public headers]) + + AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval}) + + AC_CACHE_VAL(ac_cv_c_tclh, [ + # Use the value from --with-tclinclude, if it was given + + if test x"${with_tclinclude}" != x ; then + if test -f "${with_tclinclude}/tcl.h" ; then + ac_cv_c_tclh=${with_tclinclude} + else + AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h]) + fi + else + list="" + if test "`uname -s`" = "Darwin"; then + # If Tcl was built as a framework, attempt to use + # the framework's Headers directory + case ${TCL_DEFS} in + *TCL_FRAMEWORK*) + list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" + ;; + esac + fi + + # Look in the source dir only if Tcl is not installed, + # and in that situation, look there before installed locations. + if test -f "${TCL_BIN_DIR}/Makefile" ; then + list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" + fi + + # Check order: pkg --prefix location, Tcl's --prefix location, + # relative to directory of tclConfig.sh. + + eval "temp_includedir=${includedir}" + list="$list \ + `ls -d ${temp_includedir} 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" + if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then + list="$list /usr/local/include /usr/include" + if test x"${TCL_INCLUDE_SPEC}" != x ; then + d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` + list="$list `ls -d ${d} 2>/dev/null`" + fi + fi + for i in $list ; do + if test -f "$i/tcl.h" ; then + ac_cv_c_tclh=$i + break + fi + done + fi + ]) + + # Print a message based on how we determined the include path + + if test x"${ac_cv_c_tclh}" = x ; then + AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude]) + else + AC_MSG_RESULT([${ac_cv_c_tclh}]) + fi + + # Convert to a native path and substitute into the output files. + + INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` + + TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + AC_SUBST(TCL_INCLUDES) +]) + +#------------------------------------------------------------------------ +# TEA_PRIVATE_TK_HEADERS -- +# +# Locate the private Tk include files +# +# Arguments: +# +# Requires: +# TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has +# already been called. +# +# Results: +# +# Substs the following vars: +# TK_INCLUDES +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [ + # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh} + AC_REQUIRE([TEA_PUBLIC_TK_HEADERS]) + AC_MSG_CHECKING([for Tk private include files]) + + TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}` + TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\" + + # Check to see if tkPort.h isn't already with the public headers + # Don't look for tkInt.h because that resides with tk.h in the core + # sources, but the Port headers are in a different directory + if test "${TEA_PLATFORM}" = "windows" -a \ + -f "${ac_cv_c_tkh}/tkWinPort.h"; then + result="private headers found with public headers" + elif test "${TEA_PLATFORM}" = "unix" -a \ + -f "${ac_cv_c_tkh}/tkUnixPort.h"; then + result="private headers found with public headers" + else + TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\" + TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\" + if test "${TEA_PLATFORM}" = "windows"; then + TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\" + else + TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\" + fi + # Overwrite the previous TK_INCLUDES as this should capture both + # public and private headers in the same set. + # We want to ensure these are substituted so as not to require + # any *_NATIVE vars be defined in the Makefile + TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}" + # Detect and add ttk subdir + if test -d "${TK_SRC_DIR}/generic/ttk"; then + TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\"" + fi + if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then + TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\"" + fi + if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then + TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\"" + fi + if test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use + # the framework's Headers and PrivateHeaders directories + case ${TK_DEFS} in + *TK_FRAMEWORK*) + if test -d "${TK_BIN_DIR}/Headers" -a \ + -d "${TK_BIN_DIR}/PrivateHeaders"; then + TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}" + else + TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" + fi + ;; + esac + result="Using ${TK_INCLUDES}" + else + if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then + AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}]) + fi + result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}" + fi + fi + + AC_SUBST(TK_TOP_DIR_NATIVE) + AC_SUBST(TK_XLIB_DIR_NATIVE) + + AC_SUBST(TK_INCLUDES) + AC_MSG_RESULT([${result}]) +]) + +#------------------------------------------------------------------------ +# TEA_PUBLIC_TK_HEADERS -- +# +# Locate the installed public Tk header files +# +# Arguments: +# None. +# +# Requires: +# CYGPATH must be set +# +# Results: +# +# Adds a --with-tkinclude switch to configure. +# Result is cached. +# +# Substs the following vars: +# TK_INCLUDES +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [ + AC_MSG_CHECKING([for Tk public headers]) + + AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval}) + + AC_CACHE_VAL(ac_cv_c_tkh, [ + # Use the value from --with-tkinclude, if it was given + + if test x"${with_tkinclude}" != x ; then + if test -f "${with_tkinclude}/tk.h" ; then + ac_cv_c_tkh=${with_tkinclude} + else + AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h]) + fi + else + list="" + if test "`uname -s`" = "Darwin"; then + # If Tk was built as a framework, attempt to use + # the framework's Headers directory. + case ${TK_DEFS} in + *TK_FRAMEWORK*) + list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" + ;; + esac + fi + + # Look in the source dir only if Tk is not installed, + # and in that situation, look there before installed locations. + if test -f "${TK_BIN_DIR}/Makefile" ; then + list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" + fi + + # Check order: pkg --prefix location, Tk's --prefix location, + # relative to directory of tkConfig.sh, Tcl's --prefix location, + # relative to directory of tclConfig.sh. + + eval "temp_includedir=${includedir}" + list="$list \ + `ls -d ${temp_includedir} 2>/dev/null` \ + `ls -d ${TK_PREFIX}/include 2>/dev/null` \ + `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ + `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ + `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" + if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then + list="$list /usr/local/include /usr/include" + if test x"${TK_INCLUDE_SPEC}" != x ; then + d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'` + list="$list `ls -d ${d} 2>/dev/null`" + fi + fi + for i in $list ; do + if test -f "$i/tk.h" ; then + ac_cv_c_tkh=$i + break + fi + done + fi + ]) + + # Print a message based on how we determined the include path + + if test x"${ac_cv_c_tkh}" = x ; then + AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude]) + else + AC_MSG_RESULT([${ac_cv_c_tkh}]) + fi + + # Convert to a native path and substitute into the output files. + + INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` + + TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + + AC_SUBST(TK_INCLUDES) + + if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then + # On Windows and Aqua, we need the X compat headers + AC_MSG_CHECKING([for X11 header files]) + if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then + INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" + TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" + AC_SUBST(TK_XINCLUDES) + fi + AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}]) + fi +]) + +#------------------------------------------------------------------------ +# TEA_PATH_CONFIG -- +# +# Locate the ${1}Config.sh file and perform a sanity check on +# the ${1} compile flags. These are used by packages like +# [incr Tk] that load *Config.sh files from more than Tcl and Tk. +# +# Arguments: +# none +# +# Results: +# +# Adds the following arguments to configure: +# --with-$1=... +# +# Defines the following vars: +# $1_BIN_DIR Full path to the directory containing +# the $1Config.sh file +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PATH_CONFIG], [ + # + # Ok, lets find the $1 configuration + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-$1 + # + + if test x"${no_$1}" = x ; then + # we reset no_$1 in case something fails here + no_$1=true + AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval}) + AC_MSG_CHECKING([for $1 configuration]) + AC_CACHE_VAL(ac_cv_c_$1config,[ + + # First check to see if --with-$1 was specified. + if test x"${with_$1config}" != x ; then + case ${with_$1config} in + */$1Config.sh ) + if test -f ${with_$1config}; then + AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself]) + with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'` + fi;; + esac + if test -f "${with_$1config}/$1Config.sh" ; then + ac_cv_c_$1config=`(cd ${with_$1config}; pwd)` + else + AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh]) + fi + fi + + # then check for a private $1 installation + if test x"${ac_cv_c_$1config}" = x ; then + for i in \ + ../$1 \ + `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ + `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ + `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ + ../../$1 \ + `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ + `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ + `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ + ../../../$1 \ + `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ + `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ + `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ + ${srcdir}/../$1 \ + `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ + `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ + `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \ + `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ + ; do + if test -f "$i/$1Config.sh" ; then + ac_cv_c_$1config=`(cd $i; pwd)` + break + fi + if test -f "$i/unix/$1Config.sh" ; then + ac_cv_c_$1config=`(cd $i/unix; pwd)` + break + fi + done + fi + + # check in a few common install locations + if test x"${ac_cv_c_$1config}" = x ; then + for i in `ls -d ${libdir} 2>/dev/null` \ + `ls -d ${exec_prefix}/lib 2>/dev/null` \ + `ls -d ${prefix}/lib 2>/dev/null` \ + `ls -d /usr/local/lib 2>/dev/null` \ + `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/lib 2>/dev/null` \ + `ls -d /usr/lib64 2>/dev/null` \ + ; do + if test -f "$i/$1Config.sh" ; then + ac_cv_c_$1config=`(cd $i; pwd)` + break + fi + done + fi + ]) + + if test x"${ac_cv_c_$1config}" = x ; then + $1_BIN_DIR="# no $1 configs found" + AC_MSG_WARN([Cannot find $1 configuration definitions]) + exit 0 + else + no_$1= + $1_BIN_DIR=${ac_cv_c_$1config} + AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh]) + fi + fi +]) + +#------------------------------------------------------------------------ +# TEA_LOAD_CONFIG -- +# +# Load the $1Config.sh file +# +# Arguments: +# +# Requires the following vars to be set: +# $1_BIN_DIR +# +# Results: +# +# Subst the following vars: +# $1_SRC_DIR +# $1_LIB_FILE +# $1_LIB_SPEC +# +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_LOAD_CONFIG], [ + AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh]) + + if test -f "${$1_BIN_DIR}/$1Config.sh" ; then + AC_MSG_RESULT([loading]) + . "${$1_BIN_DIR}/$1Config.sh" + else + AC_MSG_RESULT([file not found]) + fi + + # + # If the $1_BIN_DIR is the build directory (not the install directory), + # then set the common variable name to the value of the build variables. + # For example, the variable $1_LIB_SPEC will be set to the value + # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC + # instead of $1_BUILD_LIB_SPEC since it will work with both an + # installed and uninstalled version of Tcl. + # + + if test -f "${$1_BIN_DIR}/Makefile" ; then + AC_MSG_WARN([Found Makefile - using build library specs for $1]) + $1_LIB_SPEC=${$1_BUILD_LIB_SPEC} + $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC} + $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH} + $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC} + $1_LIBRARY_PATH=${$1_LIBRARY_PATH} + fi + + AC_SUBST($1_VERSION) + AC_SUBST($1_BIN_DIR) + AC_SUBST($1_SRC_DIR) + + AC_SUBST($1_LIB_FILE) + AC_SUBST($1_LIB_SPEC) + + AC_SUBST($1_STUB_LIB_FILE) + AC_SUBST($1_STUB_LIB_SPEC) + AC_SUBST($1_STUB_LIB_PATH) + + # Allow the caller to prevent this auto-check by specifying any 2nd arg + AS_IF([test "x$2" = x], [ + # Check both upper and lower-case variants + # If a dev wanted non-stubs libs, this function could take an option + # to not use _STUB in the paths below + AS_IF([test "x${$1_STUB_LIB_SPEC}" = x], + [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)], + [TEA_LOAD_CONFIG_LIB($1_STUB)]) + ]) +]) + +#------------------------------------------------------------------------ +# TEA_LOAD_CONFIG_LIB -- +# +# Helper function to load correct library from another extension's +# ${PACKAGE}Config.sh. +# +# Results: +# Adds to LIBS the appropriate extension library +# +#------------------------------------------------------------------------ +AC_DEFUN([TEA_LOAD_CONFIG_LIB], [ + AC_MSG_CHECKING([For $1 library for LIBS]) + # This simplifies the use of stub libraries by automatically adding + # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS, + # but this is called before CONFIG_CFLAGS. More importantly, this adds + # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD. + if test "x${$1_LIB_SPEC}" != "x" ; then + if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then + TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"]) + AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}]) + else + TEA_ADD_LIBS([${$1_LIB_SPEC}]) + AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}]) + fi + else + AC_MSG_RESULT([file not found]) + fi +]) + +#------------------------------------------------------------------------ +# TEA_EXPORT_CONFIG -- +# +# Define the data to insert into the ${PACKAGE}Config.sh file +# +# Arguments: +# +# Requires the following vars to be set: +# $1 +# +# Results: +# Subst the following vars: +# +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_EXPORT_CONFIG], [ + #-------------------------------------------------------------------- + # These are for $1Config.sh + #-------------------------------------------------------------------- + + # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib) + eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}" + if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then + eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}${DBGX}" + eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}${DBGX}" + else + eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}" + eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`${DBGX}" + fi + $1_BUILD_LIB_SPEC="-L`pwd` ${$1_LIB_FLAG}" + $1_LIB_SPEC="-L${pkglibdir} ${$1_LIB_FLAG}" + $1_BUILD_STUB_LIB_SPEC="-L`pwd` [$]{$1_STUB_LIB_FLAG}" + $1_STUB_LIB_SPEC="-L${pkglibdir} [$]{$1_STUB_LIB_FLAG}" + $1_BUILD_STUB_LIB_PATH="`pwd`/[$]{PKG_STUB_LIB_FILE}" + $1_STUB_LIB_PATH="${pkglibdir}/[$]{PKG_STUB_LIB_FILE}" + + AC_SUBST($1_BUILD_LIB_SPEC) + AC_SUBST($1_LIB_SPEC) + AC_SUBST($1_BUILD_STUB_LIB_SPEC) + AC_SUBST($1_STUB_LIB_SPEC) + AC_SUBST($1_BUILD_STUB_LIB_PATH) + AC_SUBST($1_STUB_LIB_PATH) + + AC_SUBST(MAJOR_VERSION) + AC_SUBST(MINOR_VERSION) + AC_SUBST(PATCHLEVEL) +]) + + +#------------------------------------------------------------------------ +# TEA_PATH_CELIB -- +# +# Locate Keuchel's celib emulation layer for targeting Win/CE +# +# Arguments: +# none +# +# Results: +# +# Adds the following arguments to configure: +# --with-celib=... +# +# Defines the following vars: +# CELIB_DIR Full path to the directory containing +# the include and platform lib files +#------------------------------------------------------------------------ + +AC_DEFUN([TEA_PATH_CELIB], [ + # First, look for one uninstalled. + # the alternative search directory is invoked by --with-celib + + if test x"${no_celib}" = x ; then + # we reset no_celib in case something fails here + no_celib=true + AC_ARG_WITH(celib,[ --with-celib=DIR use Windows/CE support library from DIR], with_celibconfig=${withval}) + AC_MSG_CHECKING([for Windows/CE celib directory]) + AC_CACHE_VAL(ac_cv_c_celibconfig,[ + # First check to see if --with-celibconfig was specified. + if test x"${with_celibconfig}" != x ; then + if test -d "${with_celibconfig}/inc" ; then + ac_cv_c_celibconfig=`(cd ${with_celibconfig}; pwd)` + else + AC_MSG_ERROR([${with_celibconfig} directory doesn't contain inc directory]) + fi + fi + + # then check for a celib library + if test x"${ac_cv_c_celibconfig}" = x ; then + for i in \ + ../celib-palm-3.0 \ + ../celib \ + ../../celib-palm-3.0 \ + ../../celib \ + `ls -dr ../celib-*3.[[0-9]]* 2>/dev/null` \ + ${srcdir}/../celib-palm-3.0 \ + ${srcdir}/../celib \ + `ls -dr ${srcdir}/../celib-*3.[[0-9]]* 2>/dev/null` \ + ; do + if test -d "$i/inc" ; then + ac_cv_c_celibconfig=`(cd $i; pwd)` + break + fi + done + fi + ]) + if test x"${ac_cv_c_celibconfig}" = x ; then + AC_MSG_ERROR([Cannot find celib support library directory]) + else + no_celib= + CELIB_DIR=${ac_cv_c_celibconfig} + CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` + AC_MSG_RESULT([found $CELIB_DIR]) + fi + fi +]) + + +# Local Variables: +# mode: autoconf +# End: diff --git a/missing b/missing new file mode 100755 index 00000000..6a37006e --- /dev/null +++ b/missing @@ -0,0 +1,336 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing 0.4 - GNU automake" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. + You can get \`$1Help2man' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 00000000..d2d5f21b --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,111 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" 1>&2 + exit 0 + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +case $dirmode in + '') + if mkdir -p -- . 2>/dev/null; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + fi + ;; + *) + if mkdir -m "$dirmode" -p -- . 2>/dev/null; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# End: +# mkinstalldirs ends here diff --git a/ng/Makefile.am b/ng/Makefile.am new file mode 100644 index 00000000..3626eef8 --- /dev/null +++ b/ng/Makefile.am @@ -0,0 +1,50 @@ +include_HEADERS = + +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include -I$(top_srcdir)/libsrc/interface -DOPENGL -D$(TOGL_WINDOWINGSYSTEM) $(TCL_INCLUDES) $(MPI_INCLUDES) $(FFMPEG_INCLUDES) $(JPEGLIB_INCLUDES) + +if NGGUI +bin_PROGRAMS = netgen +endif + +netgen_SOURCES = demoview.cpp ngappinit.cpp onetcl.cpp parallelfunc.cpp ngpkg.cpp demoview.hpp parallelfunc.hpp togl_1_7.h +# nginterface.cpp nginterface_v2.cpp + + +if NGMKL +AM_CPPFLAGS += -DLINKMKL +MKL_LIBS = -L$(MKLROOT)/lib/intel64 -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core -lmkl_def +endif + + +netgen_LDADD = $(top_builddir)/libsrc/visualization/libvisual.la \ + $(top_builddir)/libsrc/csg/libcsgvis.la \ + $(top_builddir)/libsrc/csg/libcsg.la \ + $(top_builddir)/libsrc/interface/libinterface.la \ + $(top_builddir)/libsrc/meshing/libmesh.la \ + -L$(TK_BIN_DIR)/Togl1.7 $(TOGLLIBDIR) -lTogl $(LIBGLU) $(TK_LIB_SPEC) $(TCL_LIB_SPEC) $(MPI_LIBS) $(FFMPEG_LIBS) $(JPEGLIB_LIBS) $(PKG_LIBS) $(MKL_LIBS) + +# +# $(top_builddir)/libsrc/occ/liboccvis.la +# $(top_builddir)/libsrc/occ/libocc.la +# $(top_builddir)/libsrc/stlgeom/libstlvis.la +# $(top_builddir)/libsrc/stlgeom/libstl.la +# $(top_builddir)/libsrc/geom2d/libgeom2d.la +# $(top_builddir)/libsrc/geom2d/libgeom2dvis.la + + +# add for static linkage of ngsolve: +# /opt/netgen/lib/libngsolve.a /opt/netgen/lib/libngcomp.a /opt/netgen/lib/libngcomp.a /opt/netgen/lib/libngfemng.a /opt/netgen/lib/libngmg.a /opt/netgen/lib/libngla.a /opt/netgen/lib/libngbla.a /opt/netgen/lib/libngstd.a -L/opt/intel/mkl/10.2.1.017/lib/em64t /opt/intel/mkl/10.2.1.017/lib/em64t/libmkl_solver_lp64.a -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core +# +# + +dist_bin_SCRIPTS = dialog.tcl menustat.tcl ngicon.tcl ng.tcl \ +ngvisual.tcl sockets.tcl drawing.tcl nghelp.tcl ngshell.tcl \ +ngtesting.tcl parameters.tcl variables.tcl csgeom.tcl stlgeom.tcl \ +occgeom.tcl acisgeom.tcl netgen.ocf + + +netgen_LDFLAGS = -export-dynamic +# netgen_LDFLAGS = -rdynamic +# -static + + diff --git a/ng/Makefile.in b/ng/Makefile.in new file mode 100644 index 00000000..f5fd2e43 --- /dev/null +++ b/ng/Makefile.in @@ -0,0 +1,719 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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@ +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@ +@NGGUI_TRUE@bin_PROGRAMS = netgen$(EXEEXT) +# nginterface.cpp nginterface_v2.cpp +@NGMKL_TRUE@am__append_1 = -DLINKMKL +subdir = ng +DIST_COMMON = $(dist_bin_SCRIPTS) $(include_HEADERS) \ + $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(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)/m4/tcl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(includedir)" +PROGRAMS = $(bin_PROGRAMS) +am_netgen_OBJECTS = demoview.$(OBJEXT) ngappinit.$(OBJEXT) \ + onetcl.$(OBJEXT) parallelfunc.$(OBJEXT) ngpkg.$(OBJEXT) +netgen_OBJECTS = $(am_netgen_OBJECTS) +am__DEPENDENCIES_1 = +netgen_DEPENDENCIES = \ + $(top_builddir)/libsrc/visualization/libvisual.la \ + $(top_builddir)/libsrc/csg/libcsgvis.la \ + $(top_builddir)/libsrc/csg/libcsg.la \ + $(top_builddir)/libsrc/interface/libinterface.la \ + $(top_builddir)/libsrc/meshing/libmesh.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +netgen_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ + $(netgen_LDFLAGS) $(LDFLAGS) -o $@ +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +SCRIPTS = $(dist_bin_SCRIPTS) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(netgen_SOURCES) +DIST_SOURCES = $(netgen_SOURCES) +HEADERS = $(include_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLEANFILES = @CLEANFILES@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH = @CYGPATH@ +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@ +FFMPEG_INCLUDES = @FFMPEG_INCLUDES@ +FFMPEG_LIBS = @FFMPEG_LIBS@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +JPEGLIB_INCLUDES = @JPEGLIB_INCLUDES@ +JPEGLIB_LIBS = @JPEGLIB_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBGLU = @LIBGLU@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MPI_INCLUDES = @MPI_INCLUDES@ +MPI_LIBS = @MPI_LIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OCCFLAGS = @OCCFLAGS@ +OCCLIBS = @OCCLIBS@ +OPENMP_CXXFLAGS = @OPENMP_CXXFLAGS@ +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_CFLAGS = @PKG_CFLAGS@ +PKG_HEADERS = @PKG_HEADERS@ +PKG_INCLUDES = @PKG_INCLUDES@ +PKG_LIBS = @PKG_LIBS@ +PKG_LIB_FILE = @PKG_LIB_FILE@ +PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ +PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ +PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ +PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TCL_BIN_DIR = @TCL_BIN_DIR@ +TCL_DEFS = @TCL_DEFS@ +TCL_EXTRA_CFLAGS = @TCL_EXTRA_CFLAGS@ +TCL_INCLUDES = @TCL_INCLUDES@ +TCL_LD_FLAGS = @TCL_LD_FLAGS@ +TCL_LIBS = @TCL_LIBS@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +TCL_LIB_FLAG = @TCL_LIB_FLAG@ +TCL_LIB_SPEC = @TCL_LIB_SPEC@ +TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@ +TCL_SHLIB_LD_LIBS = @TCL_SHLIB_LD_LIBS@ +TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_STUB_LIB_FLAG = @TCL_STUB_LIB_FLAG@ +TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@ +TCL_VERSION = @TCL_VERSION@ +TK_BIN_DIR = @TK_BIN_DIR@ +TK_INCLUDES = @TK_INCLUDES@ +TK_LIBS = @TK_LIBS@ +TK_LIB_FILE = @TK_LIB_FILE@ +TK_LIB_FLAG = @TK_LIB_FLAG@ +TK_LIB_SPEC = @TK_LIB_SPEC@ +TK_SRC_DIR = @TK_SRC_DIR@ +TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ +TK_STUB_LIB_FLAG = @TK_STUB_LIB_FLAG@ +TK_STUB_LIB_SPEC = @TK_STUB_LIB_SPEC@ +TK_VERSION = @TK_VERSION@ +TK_XINCLUDES = @TK_XINCLUDES@ +TOGLLIBDIR = @TOGLLIBDIR@ +TOGL_WINDOWINGSYSTEM = @TOGL_WINDOWINGSYSTEM@ +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_CXX = @ac_ct_CXX@ +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@ +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@ +include_HEADERS = +AM_CPPFLAGS = -I$(top_srcdir)/libsrc/include \ + -I$(top_srcdir)/libsrc/interface -DOPENGL \ + -D$(TOGL_WINDOWINGSYSTEM) $(TCL_INCLUDES) $(MPI_INCLUDES) \ + $(FFMPEG_INCLUDES) $(JPEGLIB_INCLUDES) $(am__append_1) +netgen_SOURCES = demoview.cpp ngappinit.cpp onetcl.cpp parallelfunc.cpp ngpkg.cpp demoview.hpp parallelfunc.hpp togl_1_7.h +@NGMKL_TRUE@MKL_LIBS = -L$(MKLROOT)/lib/intel64 -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core -lmkl_def +netgen_LDADD = $(top_builddir)/libsrc/visualization/libvisual.la \ + $(top_builddir)/libsrc/csg/libcsgvis.la \ + $(top_builddir)/libsrc/csg/libcsg.la \ + $(top_builddir)/libsrc/interface/libinterface.la \ + $(top_builddir)/libsrc/meshing/libmesh.la \ + -L$(TK_BIN_DIR)/Togl1.7 $(TOGLLIBDIR) -lTogl $(LIBGLU) $(TK_LIB_SPEC) $(TCL_LIB_SPEC) $(MPI_LIBS) $(FFMPEG_LIBS) $(JPEGLIB_LIBS) $(PKG_LIBS) $(MKL_LIBS) + + +# +# $(top_builddir)/libsrc/occ/liboccvis.la +# $(top_builddir)/libsrc/occ/libocc.la +# $(top_builddir)/libsrc/stlgeom/libstlvis.la +# $(top_builddir)/libsrc/stlgeom/libstl.la +# $(top_builddir)/libsrc/geom2d/libgeom2d.la +# $(top_builddir)/libsrc/geom2d/libgeom2dvis.la + +# add for static linkage of ngsolve: +# /opt/netgen/lib/libngsolve.a /opt/netgen/lib/libngcomp.a /opt/netgen/lib/libngcomp.a /opt/netgen/lib/libngfemng.a /opt/netgen/lib/libngmg.a /opt/netgen/lib/libngla.a /opt/netgen/lib/libngbla.a /opt/netgen/lib/libngstd.a -L/opt/intel/mkl/10.2.1.017/lib/em64t /opt/intel/mkl/10.2.1.017/lib/em64t/libmkl_solver_lp64.a -lmkl_intel_lp64 -lmkl_gnu_thread -lmkl_core +# +# +dist_bin_SCRIPTS = dialog.tcl menustat.tcl ngicon.tcl ng.tcl \ +ngvisual.tcl sockets.tcl drawing.tcl nghelp.tcl ngshell.tcl \ +ngtesting.tcl parameters.tcl variables.tcl csgeom.tcl stlgeom.tcl \ +occgeom.tcl acisgeom.tcl netgen.ocf + +netgen_LDFLAGS = -export-dynamic +all: all-am + +.SUFFIXES: +.SUFFIXES: .cpp .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) --foreign ng/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign ng/Makefile +.PRECIOUS: 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): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +netgen$(EXEEXT): $(netgen_OBJECTS) $(netgen_DEPENDENCIES) $(EXTRA_netgen_DEPENDENCIES) + @rm -f netgen$(EXEEXT) + $(netgen_LINK) $(netgen_OBJECTS) $(netgen_LDADD) $(LIBS) +install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-dist_binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/demoview.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngappinit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngpkg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/onetcl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parallelfunc.Po@am__quote@ + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cpp.lo: +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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 +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + 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" + +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 $(PROGRAMS) $(SCRIPTS) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +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: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +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-binPROGRAMS clean-generic clean-libtool 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-includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-dist_binSCRIPTS + +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: uninstall-binPROGRAMS uninstall-dist_binSCRIPTS \ + uninstall-includeHEADERS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-dist_binSCRIPTS install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-includeHEADERS 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 uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-dist_binSCRIPTS \ + uninstall-includeHEADERS + +# netgen_LDFLAGS = -rdynamic +# -static + +# 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/ng/acisgeom.tcl b/ng/acisgeom.tcl new file mode 100644 index 00000000..fab80aa4 --- /dev/null +++ b/ng/acisgeom.tcl @@ -0,0 +1,11 @@ +if { [Ng_ACISCommand isACISavailable] == "yes" } { + .ngmenu.geometry add command -label "ACIS Topology Explorer..." \ + -command { acisdialog; } + + .ngmenu.geometry add command -label "ACIS combine all" \ + -command { Ng_ACISCommand combineall } + .ngmenu.geometry add command -label "ACIS Create CT" \ + -command { Ng_ACISCommand createct } +} + + diff --git a/ng/csgeom.tcl b/ng/csgeom.tcl new file mode 100644 index 00000000..b8cab4d1 --- /dev/null +++ b/ng/csgeom.tcl @@ -0,0 +1,695 @@ +.ngmenu.geometry add command -label "Scan CSG Geometry" -command { Ng_ParseGeometry } +.ngmenu.geometry add command -label "CSG Options..." -command geometryoptionsdialog + +# only intern version ! +# .ngmenu.geometry add separator +# .ngmenu.geometry add command -label "New Primitive" \ +# -command newprimitivedialog -accelerator "

" +# .ngmenu.geometry add command -label "Edit Primitive" \ +# -command editprimitivedialog -accelerator "

" +# .ngmenu.geometry add command -label "Edit Solid" \ +# -command newsoliddialog -accelerator "" +# .ngmenu.geometry add command -label "Choose Top Level " \ +# -command topleveldialog +# .ngmenu.geometry add command -label "Identify" \ +# -command identifydialog +.ngmenu.geometry add command -label "CSG Properties..." \ + -command topleveldialog2 + + + + + + + + + + + +proc geometryoptionsdialog { } { + + + set w .geometry_dlg + + if {[winfo exists .geometry_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + + toplevel $w + + global geooptions + + Ng_GeometryOptions get + + checkbutton $w.drawcsg -text "Draw Geometry" \ + -variable geooptions.drawcsg + pack $w.drawcsg + + frame $w.fac + pack $w.fac -pady 5 + label $w.fac.lab -text "Facets:"; + entry $w.fac.ent -width 8 -relief sunken \ + -textvariable geooptions.facets + pack $w.fac.lab $w.fac.ent -side left + + + frame $w.det + pack $w.det -pady 5 + label $w.det.lab -text "Detail:"; + entry $w.det.ent -width 8 -relief sunken \ + -textvariable geooptions.detail + pack $w.det.lab $w.det.ent -side left + + frame $w.cox + pack $w.cox -pady 5 + label $w.cox.lab -text "min/max x:"; + entry $w.cox.ent1 -width 8 -relief sunken \ + -textvariable geooptions.minx + entry $w.cox.ent2 -width 8 -relief sunken \ + -textvariable geooptions.maxx + pack $w.cox.lab $w.cox.ent1 \ + $w.cox.ent2 -side left + + frame $w.coy + pack $w.coy -pady 5 + label $w.coy.lab -text "min/max y:"; + entry $w.coy.ent1 -width 8 -relief sunken \ + -textvariable geooptions.miny + entry $w.coy.ent2 -width 8 -relief sunken \ + -textvariable geooptions.maxy + pack $w.coy.lab $w.coy.ent1 \ + $w.coy.ent2 -side left + + frame $w.coz + pack $w.coz -pady 5 + label $w.coz.lab -text "min/max z:"; + entry $w.coz.ent1 -width 8 -relief sunken \ + -textvariable geooptions.minz + entry $w.coz.ent2 -width 8 -relief sunken \ + -textvariable geooptions.maxz + pack $w.coz.lab $w.coz.ent1 \ + $w.coz.ent2 -side left + + + +# tixButtonBox $w.bbox -orientation horizontal +# $w.bbox add ok -text Apply -underline 0 -width 5 \ +# -command { Ng_GeometryOptions set } + +# $w.bbox add close -text Done -underline 0 -width 5 \ +# -command { +# Ng_GeometryOptions set +# destroy .geometry_dlg +# } +# pack $w.bbox -side bottom -fill x + + + frame $w.bu + pack $w.bu -fill x -ipady 3 + + + button $w.bu.app -text "Apply" -command { + Ng_GeometryOptions set + } + button $w.bu.ok -text "Done" -command { + Ng_GeometryOptions set + destroy .geometry_dlg + } + pack $w.bu.app $w.bu.ok -side left -expand yes + + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Geometry options" + focus $w + } +} + + + + + + + + + + + + + + + + + +# +# +# Edit primitive +# +# +proc editprimitivedialog2 { name } { + + global w classname + + set w .ep_dlg + toplevel .$w + + Ng_GetPrimitiveData $name classname valuelist + + + label $w.lab1 -text "Primitive Name: $name"; + label $w.lab2 -text "Primitive Class: $classname"; + pack $w.lab1 $w.lab2 -fill x -pady 1m -padx 5m + + frame $w.specific -relief groove + + global spec + set spec(sphere) { cx cy cz rad } + set spec(cylinder) { ax ay az bx by bz rad } + set spec(plane) { px py pz nx ny nz } + set spec(cone) { ax ay az bx by bz ra rb } + set spec(brick) { p1x p1y p1z p2x p2y p2z p3x p3y p3z p4x p4y p4z } + + set cnt 0 + foreach field $spec($classname) { + + frame $w.specific.f$cnt + pack $w.specific.f$cnt -side top -anchor ne + + label $w.specific.f$cnt.lab -text "$field" + entry $w.specific.f$cnt.ent -textvariable dataval($cnt) \ + -width 6 -relief sunken + pack $w.specific.f$cnt.ent $w.specific.f$cnt.lab -side right + $w.specific.f$cnt.ent delete 0 end + $w.specific.f$cnt.ent insert 0 [lindex $valuelist $cnt] + set cnt [expr $cnt + 1] + } + pack $w.specific + + + button $w.cancel -text "cancel" -command { + destroy $w + } + + button $w.ok -text "ok" -command { + + set valuelist "" + set cnt 0 + foreach field $spec($classname) { + lappend valuelist $dataval($cnt) + set cnt [expr $cnt + 1] + } + Ng_SetPrimitiveData $name $valuelist + destroy $w + } + pack $w.cancel $w.ok -side left -expand yes + + bind $w { $w.ok invoke} + bind $w { $w.cancel invoke} + + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + +# grab $w + focus $w.specific.f0.ent +} + + + +# +# +# Select primitve to edit +# +# + +proc editprimitivedialog { } { + global w + + set w .ep_dlg + toplevel $w + + frame $w.frame -borderwidth 5m + pack $w.frame -side top -expand yes -fill y + + listbox $w.frame.list -yscroll "$w.frame.scroll set" -setgrid 1 -height 12 + scrollbar $w.frame.scroll -command "$w.frame.list yview" + pack $w.frame.scroll -side right -fill y + pack $w.frame.list -side left -expand 1 -fill both + + + Ng_GetPrimitiveList primlist + foreach el $primlist { + $w.frame.list insert end $el } + + button $w.cancel -text "cancel" -command { destroy $w } + button $w.ok -text "ok" -command { + set name [.ep_dlg.frame.list get active] + puts "name=($name)" + destroy $w + if { $name != "" } { editprimitivedialog2 $name } + } + + bind $w { $w.cancel invoke } + bind $w { $w.ok invoke } + + + pack $w.cancel $w.ok -side left -expand yes + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + +# grab $w + focus $w.frame.list +} + + + +# +# +# Create new primitive +# +# +proc newprimitivedialog { } { + + global w name + + set w .ap_dlg + + toplevel $w + + set name "" + frame $w.f1 + pack $w.f1 -pady 2m + label $w.f1.lab -text "Primitive Name: "; + entry $w.f1.ent -width 5 -relief sunken \ + -textvariable name + pack $w.f1.lab $w.f1.ent -side left + + frame $w.frame -borderwidth .5c + pack $w.frame -side top -expand yes -fill y + + listbox $w.frame.list -yscroll "$w.frame.scroll set" -setgrid 1 -height 8 + scrollbar $w.frame.scroll -command "$w.frame.list yview" + pack $w.frame.scroll -side right -fill y + pack $w.frame.list -side left -expand 1 -fill both + + $w.frame.list insert 0 sphere cylinder plane cone brick + $w.frame.list activate 0 + + button $w.ok -text "ok" -command { + Ng_CreatePrimitive [$w.frame.list get active] $name + destroy $w + editprimitivedialog2 $name + } + + button $w.cancel -text "cancel" -command { + destroy $w + } + + pack $w.cancel $w.ok -side left -expand yes -pady 2m + + + bind $w { $w.cancel invoke } + bind $w { $w.ok invoke } + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + +# grab $w + focus $w.f1.ent +} + + + + + + +proc newsoliddialog { } { + + global w name val sollist + + set w .ns_dlg + toplevel $w + + set name "" + frame $w.f1 + label $w.f1.lab -text "Solid Name: "; + entry $w.f1.ent -width 5 -relief sunken \ + -textvariable name + $w.f1.ent delete 0 end + button $w.f1.getsel -text "Get Selected" -command { + $w.f1.ent delete 0 end + $w.f1.ent insert 0 [$w.f3.list get active] + $w.bu.get invoke + } + pack $w.f1.getsel -side bottom + pack $w.f1.ent $w.f1.lab -side right + + + frame $w.f3 -borderwidth .5c + listbox $w.f3.list -yscroll "$w.f3.scroll set" -setgrid 1 -height 12 + scrollbar $w.f3.scroll -command "$w.f3.list yview" + pack $w.f3.scroll -side right -fill y + pack $w.f3.list -side left -expand 1 -fill both + + Ng_GetSolidList sollist + foreach el $sollist { + $w.f3.list insert end $el } + + frame $w.f2 + label $w.f2.lab -text "Solid Description: "; + pack $w.f2.lab + + + entry $w.f2.ent -width 100 -relief sunken \ + -textvariable val -xscrollcommand "$w.f2.scr set" + scrollbar $w.f2.scr -relief sunken -orient horiz -command \ + "$w.f2.ent xview" + $w.f2.ent delete 0 end + pack $w.f2.ent $w.f2.scr -fill x + + + + frame $w.bu + button $w.bu.close -text "close" -command { + destroy $w + } + + button $w.bu.get -text "get data" -command { + Ng_GetSolidData $name val + } + + button $w.bu.set -text "set data" -command { + Ng_SetSolidData $name $val + } + + pack $w.bu.get $w.bu.set $w.bu.close -side left + + + pack $w.bu -pady 5 -side bottom ;# buttons + pack $w.f2 -pady 5 -side bottom ;# edit field + pack $w.f1 -pady 5 -side left ;# name + pack $w.f3 -side left -expand yes -fill y ;# listbox + + + + bind $w { $w.bu.close invoke } + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + +# grab $w + focus $w +} + + + + + + + +# +# Edit top level objects +# +# + + +proc toplevelproperties { w solname surfname } { + + global properties + + Ng_TopLevel getprop $solname $surfname properties + + + set w .tlprop_dlg + + if {[winfo exists $w] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + toplevel $w + + label $w.lab1 -text "Red" + scale $w.scale1 -orient horizontal -length 300 -from 0 -to 1 \ + -resolution 0.01 -tickinterval 0.2 \ + -command { Ng_TopLevel setprop $solname $surfname properties; redraw } -variable properties(red) + + label $w.lab2 -text "Green" + scale $w.scale2 -orient horizontal -length 300 -from 0 -to 1 \ + -resolution 0.01 -tickinterval 0.2 \ + -command { Ng_TopLevel setprop $solname $surfname properties; redraw } -variable properties(green) + + label $w.lab3 -text "Blue" + scale $w.scale3 -orient horizontal -length 300 -from 0 -to 1 \ + -resolution 0.01 -tickinterval 0.2 \ + -command { Ng_TopLevel setprop $solname $surfname properties; redraw } -variable properties(blue) + + + pack $w.lab1 $w.scale1 $w.lab2 $w.scale2 $w.lab3 $w.scale3 + + checkbutton $w.cb4 -text "Visible" \ + -command { Ng_TopLevel setprop $solname $surfname properties; redraw } \ + -variable properties(visible) + + checkbutton $w.cb5 -text "Transparent" \ + -command { Ng_TopLevel setprop $solname $surfname properties; redraw } \ + -variable properties(transp) + + + pack $w.cb4 $w.cb5 + + + frame $w.bu + pack $w.bu -fill x + button $w.bu.ok -text "Ok" -command "destroy .tlprop_dlg" + pack $w.bu.ok -expand yes + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + focus $w + } + wm title $w "Properties $solname $surfname" +} + + + + + + +proc topleveldialog { } { + + global w name val sollist + + set w .tl_dlg + toplevel $w + + + + frame $w.sol -borderwidth .5c + listbox $w.sol.list -yscroll "$w.sol.scroll set" -setgrid 1 -height 12 + scrollbar $w.sol.scroll -command "$w.sol.list yview" + pack $w.sol.scroll -side right -fill y + pack $w.sol.list -side left -expand 1 -fill both + + Ng_GetSolidList sollist + foreach el $sollist { + $w.sol.list insert end $el } + Ng_GetPrimitiveList sollist + foreach el $sollist { + $w.sol.list insert end $el } + + + + + frame $w.sul -borderwidth .5c + listbox $w.sul.list -yscroll "$w.sul.scroll set" -setgrid 1 -height 12 + scrollbar $w.sul.scroll -command "$w.sul.list yview" + pack $w.sul.scroll -side right -fill y + pack $w.sul.list -side left -expand 1 -fill both + + Ng_GetSurfaceList sollist + foreach el $sollist { + $w.sul.list insert end $el } + + + + + + frame $w.topl -borderwidth .5c + listbox $w.topl.list -yscroll "$w.topl.scroll set" -setgrid 1 -height 12 \ + -command { puts hi } + scrollbar $w.topl.scroll -command "$w.topl.list yview" + pack $w.topl.scroll -side right -fill y + pack $w.topl.list -side left -expand 1 -fill both + + Ng_TopLevel getlist sollist + puts $sollist + foreach el $sollist { + set hel "[ lindex $el 0 ]" + if { [ llength $el ] == 2 } { + set hel "[ lindex $el 1 ] on [ lindex $el 0 ]" + } + $w.topl.list insert end $hel + } + + + frame $w.bu + + button $w.bu.close -text "close" -command { + destroy $w + } + button $w.bu.addsol -text "Add Solid" -command { + set solname [$w.sol.list get active] + Ng_TopLevel set $solname "" + Ng_ParseGeometry + $w.topl.list insert end $solname + } + + button $w.bu.addsurf -text "Add Surface" -command { + set solname [$w.sol.list get active] + set surfname [$w.sul.list get active] + Ng_TopLevel set $solname $surfname + Ng_ParseGeometry + puts "$solname on $surfname" + $w.topl.list insert end "$surfname on $solname" + } + + button $w.bu.remsol -text "Remove" -command { + set solname [$w.topl.list get active] + set surfname "" + if { [llength $solname] == 3 } { + set surfname [lindex $solname 0] + set solname [lindex $solname 2] + } + Ng_TopLevel remove $solname $surfname + Ng_ParseGeometry + $w.topl.list delete active + } + + button $w.bu.prop -text "Properties" -command { + set solname [$w.topl.list get active] + set surfname "" + if { [llength $solname] == 3 } { + set surfname [lindex $solname 0] + set solname [lindex $solname 2] + } + toplevelproperties tlp $solname $surfname + } + + + + + pack $w.bu.close $w.bu.addsol $w.bu.addsurf $w.bu.remsol $w.bu.prop -side left + + + pack $w.bu -side bottom + pack $w.sol -side left -expand yes -fill y ;# listbox + pack $w.sul -side left -expand yes -fill y ;# listbox + pack $w.topl -side left -expand yes -fill y ;# listbox + + + bind $w { $w.bu.close invoke } + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + +# grab $w + focus $w +} + + + + + + +proc topleveldialog2 { } { + set w .tl2_dlg + + if {[winfo exists .tl2_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + toplevel $w + + global name val sollist + + frame $w.topl -borderwidth .5c + listbox $w.topl.list -yscroll "$w.topl.scroll set" -setgrid 1 -height 12 + scrollbar $w.topl.scroll -command "$w.topl.list yview" + pack $w.topl.scroll -side right -fill y + pack $w.topl.list -side left -expand 1 -fill both + + Ng_TopLevel getlist sollist + puts $sollist + set i 1 + foreach el $sollist { + set hel "$i: [ lindex $el 0 ]" + if { [ llength $el ] == 2 } { + set hel "$i: [ lindex $el 1 ] on [ lindex $el 0 ]" + } + incr i + $w.topl.list insert end $hel } + + + frame $w.bu + + button $w.bu.close -text "close" -command { + destroy .tl2_dlg + } + + + button $w.bu.prop -text "Properties" -command { + set solname [.tl2_dlg.topl.list get active] + set surfname "" + if { [llength $solname] == 2 } { + set solname [lindex $solname 1] + } + if { [llength $solname] == 4 } { + set surfname [lindex $solname 1] + set solname [lindex $solname 3] + } + toplevelproperties tlp $solname $surfname + } + + pack $w.bu.close $w.bu.prop -side left + pack $w.bu -side bottom + pack $w.topl -side left -expand yes -fill y ;# listbox + + bind .tl2_dlg.topl.list { + set solname [.tl2_dlg.topl.list get @%x,%y] + set surfname "" + if { [llength $solname] == 2 } { + set solname [lindex $solname 1] + } + if { [llength $solname] == 4 } { + set surfname [lindex $solname 1] + set solname [lindex $solname 3] + } + toplevelproperties tlp $solname $surfname + } + + bind .tl2_dlg { .tl2_dlg.bu.close invoke } + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Top-Level Options" + focus $w + } +} + + + + + diff --git a/ng/demoview.cpp b/ng/demoview.cpp new file mode 100644 index 00000000..77da7b0e --- /dev/null +++ b/ng/demoview.cpp @@ -0,0 +1,440 @@ +/*********************************************************************/ +/* File: demoview.cpp */ +/* Author: Robert, Joachim */ +/* Date: 6. Mar. 2003 */ +/*********************************************************************/ + + +#include + + +//#include +#include +#include +#include +#include +#include +#include +#include +#include "incvis.hpp" +#include + +namespace netgen { + extern VisualScene *vs; +#include "demoview.hpp" + + + /* + static demokwstruct defkw[] = + { + { TOK_TIME, "t" }, + { TOK_CAMPOS, "camerapos" }, + { TOK_CAMPOINT, "camerapointto" }, + { TOK_CAMUP, "cameraup" } + }; + */ + + + static demoview_kwstruct demoview_defkw[] = + { + { DTOK_TIME, "t" }, + { DTOK_CAMPOS, "camerapos" }, + { DTOK_CAMPOINT, "camerapointto" }, + { DTOK_CAMUP, "cameraup" } + }; + + + DemoScanner :: DemoScanner (ifstream & ascanin) + { + scanin = &ascanin; + token = DTOK_END; + num_value = 0; + linenum = 1; + } + + + + void DemoScanner :: ReadNext () + { + char ch; + + + // whitespaces ueberspringen + do + { + scanin->get(ch); + + if (ch == '\n') + linenum++; + + // end of file reached + if (scanin->eof()) + { + token = DTOK_END; + return; + } + + // skip comment line + if (ch == '#') + { + while (ch != '\n') + { + scanin->get(ch); + if (scanin->eof()) + { + token = DTOK_END; + return; + } + } + linenum++; + } + } + while (isspace(ch)); + + switch (ch) + { + case '(': case ')': + case '[': case ']': + case '-': case ':': + case '=': case ',': + case ';': case '+': + { + token = DEMOVIEW_TOKEN_TYPE (ch); + break; + } + + default: + { + if (isdigit (ch) || ch == '.') + { + scanin->putback (ch); + (*scanin) >> num_value; + token = DTOK_NUM; + return; + } + + if (isalpha (ch)) + { + string_value = string (1, ch); + scanin->get(ch); + while (isalnum(ch)) + { + string_value += ch; + scanin->get(ch); + } + scanin->putback (ch); + } + + int nr = 0; + while (demoview_defkw[nr].kw) + { + if (string_value == demoview_defkw[nr].name) + { + token = demoview_defkw[nr].kw; + return; + } + nr++; + } + + token = DTOK_STRING; + } + } + } + + + + void DemoScanner :: Error (const string & err) + { + stringstream errstr; + errstr << "Parsing error in line " << linenum << ": " << endl << err << endl; + throw string(errstr.str()); + } + + + + void ParseChar (DemoScanner & scan, char ch) + { + char str[2]; + str[0] = ch; + str[1] = 0; + if (scan.GetToken() != DEMOVIEW_TOKEN_TYPE(ch)) + scan.Error (string ("token '") + string(str) + string("' expected")); + scan.ReadNext(); + } + + + + double ParseNumber(DemoScanner & scan) + { + if (scan.GetToken() == '-') + { + scan.ReadNext(); + return -ParseNumber (scan); + } + if (scan.GetToken() != DTOK_NUM) scan.Error ("number expected"); + double val = scan.GetNumValue(); + scan.ReadNext(); + return val; + } + + + Vec<3> ParseVector (DemoScanner & scan) + { + Vec<3> s; + + s(0) = ParseNumber (scan); + ParseChar (scan, ','); + + s(1) = ParseNumber (scan); + ParseChar (scan, ','); + + s(2) = ParseNumber (scan); + + return s; + } + + + void ParseConstLineOrSpline (DemoScanner & scan, double * t, Vec<3> * s) + { + int np = 1; + + scan.ReadNext(); + ParseChar (scan, '('); + + t[0] = ParseNumber (scan)*1000; + ParseChar (scan, ':'); + + s[0] = ParseVector (scan); + + if (scan.GetToken() != DTOK_RP && + scan.GetToken() != DTOK_SEMICOLON) + scan.Error (") or ; expected"); + + if (scan.GetToken() == DTOK_SEMICOLON) + { + np++; + + scan.ReadNext(); + + t[1] = ParseNumber (scan)*1000; + ParseChar (scan, ':'); + + s[1] = ParseVector (scan); + + if (scan.GetToken() != DTOK_RP && + scan.GetToken() != DTOK_SEMICOLON) + scan.Error (") or ; expected"); + + if (scan.GetToken() == DTOK_SEMICOLON) + { + np++; + + scan.ReadNext(); + + t[2] = ParseNumber (scan)*1000; + ParseChar (scan, ':'); + + s[2] = ParseVector (scan); + + ParseChar (scan, ')'); + ParseChar (scan, ';'); + } + else if (scan.GetToken() == DTOK_RP) + { + scan.ReadNext(); + ParseChar (scan, ';'); + } + } + else if (scan.GetToken() == DTOK_RP) + { + scan.ReadNext(); + ParseChar (scan, ';'); + } + + if (np == 1) // constant spline + { + t[1] = t[2] = t[0]; + s[1] = s[2] = s[0]; + } + if (np == 2) // linear spline + { + t[2] = t[1]; t[1] = 0.5*(t[0] + t[2]); + s[2] = s[1]; s[1] = 0.5*(s[0] + s[2]); + } + } + + + + + template + void InterpolationSpline :: AddSpline(double t1, double t2, double t3, S s1, S s2, S s3) + { + int pos, i, j; + // find pos to insert interpotation point + for (pos = 0; pos < ip.Size() && ip[pos][0].GetT() < t1; pos++) ; + + ip.SetSize( ip.Size()+1 ); + for (i = ip.Size()-2; i >= pos; i--) + for (j = 0; j < 3; j++) + ip[i+1][j] = ip[i][j]; + + ip[pos][0].SetTS (t1, s1); + ip[pos][1].SetTS (t2, s2); + ip[pos][2].SetTS (t3, s3); + } + + + + template + S InterpolationSpline :: Evaluate (double t) + { + if (t < ip[0][0].GetT()) + return (ip[0][0].GetS()); + + if (t > ip[ip.Size()-1][2].GetT()) + { + finished = 1; + return (ip[ip.Size()-1][2].GetS()); + } + + int pos; + for (pos = 0; pos < ip.Size() && t >= ip[pos][0].GetT(); pos++) ; + pos--; + + if (t >= ip[pos][0].GetT() && t <= ip[pos][2].GetT()) + { + double t0 = ip[pos][0].GetT(); + double t1 = ip[pos][2].GetT(); + + double t01 = (t-t0)/(t1-t0); + + double b1, b2, b3, w; + + b1 = (1-t01)*(1-t01); + b2 = sqrt(2.0) * t01 * (1-t01); + b3 = t01 * t01; + w = b1 + b2 + b3; + + return ( (1/w) * (b1 * ip[pos][0].GetS() + + b2 * ip[pos][1].GetS() + + b3 * ip[pos][2].GetS()) ); + } + else + return (ip[pos][2].GetS()); + } + + + + DemoView :: DemoView (const char * filename) + : campos( Vec<3>(5,0,0) ), + campoint ( Vec<3>(0,0,0) ), + camup ( Vec<3>(0,0,1) ) + { + double time = 0; + + ifstream istr; + istr.open(filename); + + DemoScanner scan(istr); + + double t[3]; + Vec<3> s[3]; + + scan.ReadNext(); + + try + { + while (1) + { + if (scan.GetToken() == DTOK_END) break; + + if (scan.GetToken() == DTOK_CAMPOS) + { + ParseConstLineOrSpline (scan, &t[0], &s[0]); + campos.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]); + } + + else if (scan.GetToken() == DTOK_CAMUP) + { + ParseConstLineOrSpline (scan, &t[0], &s[0]); + camup.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]); + } + + else if (scan.GetToken() == DTOK_CAMPOINT) + { + ParseConstLineOrSpline (scan, &t[0], &s[0]); + campoint.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]); + } + + else if (scan.GetToken() == DTOK_TIME) + { + scan.ReadNext(); + + if (scan.GetToken() != DTOK_EQU && + scan.GetToken() != DTOK_PLUS) + scan.Error ("= or += expected"); + + if (scan.GetToken() == DTOK_EQU) + { + scan.ReadNext(); + time = ParseNumber (scan)*1000; + ParseChar (scan, ';'); + } + else if (scan.GetToken() == DTOK_PLUS) + { + scan.ReadNext(); + ParseChar (scan, '='); + time += ParseNumber (scan)*1000; + ParseChar (scan, ';'); + } + } + + else + { + cout << "read unidentified token " << scan.GetToken() + << " string = " << scan.GetStringValue() << endl; + scan.ReadNext(); + } + } + } + catch (string errstr) + { + cout << "caught error " << errstr << endl; + } + + + } + + + DemoView :: ~DemoView () + { + ; + } + + int DemoView :: SetTime (double time) + { + /* + cout << "time = " << time << endl; + + cout << "campos : " << campos.Evaluate (time) << endl; + cout << "campoint: " << campoint.Evaluate (time) << endl; + cout << "camup : " << camup.Evaluate (time) << endl; + */ + + + vs -> LookAt ( Point<3>( campos.Evaluate (time)), + Point<3>(campoint.Evaluate (time)), + Point<3>( camup.Evaluate (time)) ); + + if (campos.IsFinished() && + campoint.IsFinished() && + camup.IsFinished()) + { + return -1; + } + + return 0; + } + + +} diff --git a/ng/demoview.hpp b/ng/demoview.hpp new file mode 100644 index 00000000..91ae8fe3 --- /dev/null +++ b/ng/demoview.hpp @@ -0,0 +1,155 @@ +#ifndef FILE_DEMOVIEW +#define FILE_DEMOVIEW + +/*********************************************************************/ +/* File: demoview.hpp */ +/* Author: Robert, Joachim */ +/* Date: 6. Mar. 2003 */ +/*********************************************************************/ + +using namespace netgen; + + +enum DEMOVIEW_TOKEN_TYPE + { + DTOK_MINUS = '-', DTOK_LP = '(', DTOK_RP = ')', DTOK_LSP = '[', DTOK_RSP = ']', + DTOK_EQU = '=', DTOK_COMMA = ',', DTOK_SEMICOLON = ';', DTOK_COLON = ':', DTOK_PLUS = '+', + DTOK_NUM = 100, DTOK_STRING, DTOK_TIME, DTOK_CAMPOS, DTOK_CAMPOINT, DTOK_CAMUP, + DTOK_END + }; + +struct demoview_kwstruct +{ + DEMOVIEW_TOKEN_TYPE kw; + const char * name; +}; + + + + +class DemoScanner +{ + DEMOVIEW_TOKEN_TYPE token; + double num_value; + string string_value; + + int linenum; + ifstream * scanin; + +public: + + DemoScanner (ifstream & ascanin); + + DEMOVIEW_TOKEN_TYPE GetToken() const + { return token; } + + double GetNumValue() const + { return num_value; } + + const string & GetStringValue() const + { return string_value; } + + void ReadNext(); + void Error (const string & err); +}; + + +void ParseChar (DemoScanner & scan, char ch); + +double ParseNumber(DemoScanner & scan); + +Vec<3> ParseVector (DemoScanner & scan); + + + +template +class InterpolationPoint +{ + double t; + S s; + +public: + InterpolationPoint() + {}; + + ~InterpolationPoint() + {}; + + double GetT() const + { return t; }; + + S GetS() const + { return s; }; + + void SetTS(double at, S as) + { t = at; s = as; }; + + InterpolationPoint & operator= (const InterpolationPoint & ip2) + { + SetTS (ip2.t, ip2.s); + return (*this); + }; + +}; + + + +template +class InterpolationSpline +{ +protected: + // Array < InterpolationPoint[3] > ip; + + class intpts + { + public: + InterpolationPoint pts[3]; + InterpolationPoint & operator[](int i) { return pts[i]; } + }; + Array < intpts > ip; + + int finished; + +public: + InterpolationSpline() : finished(0) + {}; + + InterpolationSpline( S s1 ) : finished(0) + { + AddSpline (-1e99, -1e99, -1e99, s1, s1, s1); + // InterpolationSpline(); + } + + ~InterpolationSpline() + {}; + + void AddSpline(double t1, double t2, double t3, S s1, S s2, S s3); + + S Evaluate (double t); + + int IsFinished() const + { + return finished; + } +}; + + + + + +class DemoView +{ + InterpolationSpline< Vec<3> > campos; + InterpolationSpline< Vec<3> > campoint; + InterpolationSpline< Vec<3> > camup; + +public: + DemoView (const char * filename); + ~DemoView (); + + int SetTime (double time); +}; + + + +#endif diff --git a/ng/dialog.tcl b/ng/dialog.tcl new file mode 100644 index 00000000..9ecfdea0 --- /dev/null +++ b/ng/dialog.tcl @@ -0,0 +1,2623 @@ +proc meshingoptionsdialog { } { + + set w .options_dlg + + if {[winfo exists .options_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + + toplevel $w + +# global options.meshsize + + tixNoteBook $w.nb -ipadx 6 -ipady 6 + + $w.nb add general -label "General" -underline 0 + $w.nb add meshsize -label "Mesh Size" -underline 0 + $w.nb add chartopt -label "STL Charts" -underline 0 + $w.nb add optimizer -label "Optimizer" -underline 0 + $w.nb add insider -label "Insider" -underline 0 + $w.nb add debug -label "Debug" -underline 0 + + + pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top + + + # General meshing options + + set f [$w.nb subwidget general] + + set finevals { 1 2 3 4 5 6 } + set finelabs(1) "very coarse" + set finelabs(2) "coarse" + set finelabs(3) "moderate" + set finelabs(4) "fine" + set finelabs(5) "very fine" + set finelabs(6) "user defined" + + tixOptionMenu $f.fine -label "Mesh granularity : " \ + -options { + label.width 19 + label.anchor e + menubutton.width 15 + } + + + foreach finev $finevals { + $f.fine add command $finev -label $finelabs($finev) + } + $f.fine config -variable meshoptions.fineness + $f.fine config -command { setgranularity } + global meshoptions.fineness +# setgranularity ${meshoptions.fineness} + pack $f.fine + + + + + + set mgsteps { ag me ms os mv ov } + set mgsteplabel(ag) "Analyze Geometry" + set mgsteplabel(me) "Mesh Edges" + set mgsteplabel(ms) "Mesh Surface" + set mgsteplabel(os) "Optimize Surface" + set mgsteplabel(mv) "Mesh Volume" + set mgsteplabel(ov) "Optimize Volume" + + + tixOptionMenu $f.first -label "First Step : " \ + -options { + label.width 19 + label.anchor e + menubutton.width 15 + } + + tixOptionMenu $f.last -label "Last Step : " \ + -options { + label.width 19 + label.anchor e + menubutton.width 15 + } + + foreach step $mgsteps { + $f.first add command $step -label $mgsteplabel($step) + $f.last add command $step -label $mgsteplabel($step) + } + + $f.first config -variable meshoptions.firststep + $f.last config -variable meshoptions.laststep + + pack $f.first $f.last + + + + + + set msg(0) "None" + set msg(1) "Least" + set msg(2) "Little" + set msg(3) "Moderate" + set msg(4) "Much" + set msg(5) "Most" + + tixOptionMenu $f.msg -label "Print Messages : " \ + -options { + label.width 19 + label.anchor e + menubutton.width 15 + } + + foreach step {0 1 2 3 4 5 } { + $f.msg add command $step -label $msg($step) + } + + $f.msg config -variable options.printmsg + pack $f.msg + + + + + + + + + checkbutton $f.parthread -text "Parallel meshing thread" \ + -variable options.parthread + checkbutton $f.second -text "Second order elements" \ + -variable options.secondorder + checkbutton $f.quad -text "Quad dominated" \ + -variable options.quad -command { + if { ${options.quad} } { + set meshoptions.laststep os + } + } + checkbutton $f.invtets -text "Invert volume elements" \ + -variable options.inverttets + checkbutton $f.invtrigs -text "Invert surface elements" \ + -variable options.inverttrigs + checkbutton $f.azref -text "Automatic Z-refinement" \ + -variable options.autozrefine + + pack $f.parthread $f.second $f.quad $f.invtets $f.invtrigs $f.azref + + + + tixControl $f.elementorder -label "Element order: " -integer true \ + -variable options.elementorder -min 1 -max 20 \ + -options { + entry.width 2 + label.width 20 + label.anchor e + } + + pack $f.elementorder + + +# tixControl $f.memory -label "Large Memory \[MB\]: " -integer true \ +\# -variable options.memory -min 0 -max 2000 \ +\# -options { +# entry.width 5 +# label.width 20 +# label.anchor e +# } + +# global userlevel +# if { $userlevel >= 3} { pack $f.memory } + + + # Mesh - Size options + set f [$w.nb subwidget meshsize] + + tixControl $f.meshsize -label "max mesh-size: " -integer false \ + -variable options.meshsize -min 1e-9 -max 1e6 \ + -options { + entry.width 6 + label.width 25 + label.anchor e + } + + tixControl $f.minmeshsize -label "min mesh-size: " -integer false \ + -variable options.minmeshsize -min 0 -max 1e6 \ + -options { + entry.width 6 + label.width 25 + label.anchor e + } + + tixControl $f.grading -label "mesh-size grading: " -integer false \ + -variable options.grading -min 0.1 -max 1 -step 0.1 \ + -options { + entry.width 6 + label.width 25 + label.anchor e + } + + pack $f.meshsize $f.minmeshsize $f.grading + + + + frame $f.msf + pack $f.msf + + tixLabelEntry $f.msf.ent -label "mesh-size file: " \ + -labelside top \ + -options { + entry.textVariable options.meshsizefilename + entry.width 35 + label.width 25 + label.anchor w + } + button $f.msf.btn -text "Browse" -command { + global options.meshsizefilename + set types { + {"Meshsize file" {.msz} } } + set options.meshsizefilename [tk_getOpenFile -filetypes $types -initialfile ${options.meshsizefilename}] + } + + pack $f.msf.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4 + pack $f.msf.btn -side left -anchor s -padx 4 -pady 4 + + + label $f.lab -text "Additional mesh size restrictions:" + + #csg-meshsize options + + frame $f.csg -relief groove -borderwidth 3 + pack $f.csg -fill x + + + frame $f.csg.curv + pack $f.csg.curv -anchor w + + scale $f.csg.curv.sc -orient horizontal -length 200 -from 0.2 -to 5 \ + -resolution 0.1 -variable options.curvaturesafety + label $f.csg.curv.la -text "Elements per curvature radius" + pack $f.csg.curv.sc $f.csg.curv.la -side left + + frame $f.csg.elen + pack $f.csg.elen -anchor w + scale $f.csg.elen.sc -orient horizontal -length 200 -from 0.2 -to 5 \ + -resolution 0.1 -variable options.segmentsperedge + label $f.csg.elen.la -text "Elements per edge" + pack $f.csg.elen.sc $f.csg.elen.la -side left + + + #stl-meshsize options + + frame $f.stl -relief groove -borderwidth 3 + pack $f.stl -fill x + + frame $f.stl.r2 + pack $f.stl.r2 -anchor w + scale $f.stl.r2.sc -orient horizontal -length 200 -from 0.2 -to 5 \ + -resolution 0.1 -variable stloptions.resthchartdistfac + checkbutton $f.stl.r2.bu -text "STL - chart distance" \ + -variable stloptions.resthchartdistenable + pack $f.stl.r2.sc $f.stl.r2.bu -side left + + frame $f.stl.r6 + pack $f.stl.r6 -anchor w + scale $f.stl.r6.sc -orient horizontal -length 200 -from 0.2 -to 5 \ + -resolution 0.1 -variable stloptions.resthlinelengthfac + checkbutton $f.stl.r6.bu -text "STL - line length" \ + -variable stloptions.resthlinelengthenable + pack $f.stl.r6.sc $f.stl.r6.bu -side left + + frame $f.stl.r3 + pack $f.stl.r3 -anchor w + scale $f.stl.r3.sc -orient horizontal -length 200 -from 0.2 -to 8 \ + -resolution 0.1 -variable stloptions.resthcloseedgefac + checkbutton $f.stl.r3.bu -text "STL/IGES/STEP - close edges" \ + -variable stloptions.resthcloseedgeenable + + pack $f.stl.r3.sc $f.stl.r3.bu -side left + + frame $f.stl.r1 + pack $f.stl.r1 -anchor w + scale $f.stl.r1.sc -orient horizontal -length 200 -from 0.2 -to 5 \ + -resolution 0.1 -variable stloptions.resthsurfcurvfac + checkbutton $f.stl.r1.bu -text "STL - surface curvature" \ + -variable stloptions.resthsurfcurvenable + pack $f.stl.r1.sc $f.stl.r1.bu -side left + + frame $f.stl.r3b + pack $f.stl.r3b -anchor w + scale $f.stl.r3b.sc -orient horizontal -length 200 -from 0.2 -to 5 \ + -resolution 0.1 -variable stloptions.resthedgeanglefac + checkbutton $f.stl.r3b.bu -text "STL - edge angle" \ + -variable stloptions.resthedgeangleenable + pack $f.stl.r3b.sc $f.stl.r3b.bu -side left + + frame $f.stl.r5 + pack $f.stl.r5 -anchor w + scale $f.stl.r5.sc -orient horizontal -length 200 -from 0.2 -to 5 \ + -resolution 0.1 -variable stloptions.resthsurfmeshcurvfac + checkbutton $f.stl.r5.bu -text "STL - surface mesh curv" \ + -variable stloptions.resthsurfmeshcurvenable + pack $f.stl.r5.sc $f.stl.r5.bu -side left + + + checkbutton $f.stl.recalch -text "STL - Recalc mesh size for surface optimization" \ + -variable stloptions.recalchopt + pack $f.stl.recalch + + button $f.stl.calch -text "Calc New H" -command { redraw; Ng_STLCalcLocalH } + pack $f.stl.calch + + + + + + + set f [$w.nb subwidget chartopt] + + + label $f.lab1 -text "Yellow Edges Angle ()" + scale $f.scale1 -orient horizontal -length 300 \ + -from 0 -to 90 -resolution 1 -tickinterval 10 \ + -variable stloptions.yangle + + pack $f.lab1 $f.scale1 + + label $f.lab2e -text "Edge Corner Angle ()" + scale $f.scale2e -orient horizontal -length 360 -from 0 -to 180 \ + -resolution 1 -tickinterval 20 \ + -variable stloptions.edgecornerangle + pack $f.lab2e $f.scale2e + + label $f.lab2 -text "Chart Angle ()" + scale $f.scale2 -orient horizontal -length 360 -from 0 -to 180 \ + -resolution 1 -tickinterval 20 \ + -variable stloptions.chartangle + pack $f.lab2 $f.scale2 + + label $f.lab2b -text "Outer Chart Angle ()" + scale $f.scale2b -orient horizontal -length 360 -from 0 -to 180 \ + -resolution 1 -tickinterval 20 \ + -variable stloptions.outerchartangle + pack $f.lab2b $f.scale2b + + + + + # Optimization options + + set f [$w.nb subwidget optimizer] + + + + + tixControl $f.os2d -label "Surface opt steps: " -integer true \ + -variable options.optsteps2d -min 0 -max 99 -step 1 \ + -options { + entry.width 3 + label.width 25 + label.anchor e + } + + tixControl $f.os3d -label "Volume opt steps: " -integer true \ + -variable options.optsteps3d -min 0 -max 99 -step 1 \ + -options { + entry.width 3 + label.width 25 + label.anchor e + } + + tixControl $f.elw -label "Element size weight: " -integer false \ + -variable options.elsizeweight -min 0 -max 1 -step 0.1 \ + -options { + entry.width 3 + label.width 25 + label.anchor e + } + + tixControl $f.wem -label "Worst element measure: " -integer false \ + -variable options.opterrpow -min 1 -max 10 -step 1 \ + -options { + entry.width 3 + label.width 25 + label.anchor e + } + + pack $f.os2d $f.os3d $f.elw $f.wem + + frame $f.badellimit + pack $f.badellimit -fill x + label $f.badellimit.lab -text "bad element criterion"; + scale $f.badellimit.scale -orient horizontal -length 150 \ + -from 160 -to 180 -resolution 1 \ + -variable options.badellimit + pack $f.badellimit.scale $f.badellimit.lab -side right -anchor s + + + # insider options + set f [$w.nb subwidget insider] + + + + checkbutton $f.localh -text "Use Local Meshsize" \ + -variable options.localh + checkbutton $f.delauney -text "Use Delaunay" \ + -variable options.delaunay + checkbutton $f.checkoverlap -text "Check Overlapping" \ + -variable options.checkoverlap + checkbutton $f.checkcb -text "Check Chart Boundary" \ + -variable options.checkchartboundary + checkbutton $f.blockfill -text "Do Blockfilling" \ + -variable options.blockfill + + pack $f.localh $f.delauney $f.checkoverlap $f.blockfill $f.checkcb -anchor w + + + + + # debugging options + set f [$w.nb subwidget debug] + + frame $f.cb + pack $f.cb -side top + + + + checkbutton $f.cb.slowchecks -text "Slow checks" \ + -variable debug.slowchecks -command { Ng_SetDebugParameters } + checkbutton $f.cb.debugoutput -text "Debugging outout" \ + -variable debug.debugoutput -command { Ng_SetDebugParameters } + checkbutton $f.cb.haltexline -text "Halt on exising line" \ + -variable debug.haltexistingline -command { Ng_SetDebugParameters } + checkbutton $f.cb.haltoverlap -text "Halt on Overlap" \ + -variable debug.haltoverlap -command { Ng_SetDebugParameters } + checkbutton $f.cb.haltsuc -text "Halt on success" \ + -variable debug.haltsuccess -command { Ng_SetDebugParameters } + checkbutton $f.cb.haltnosuc -text "Halt on no success" \ + -variable debug.haltnosuccess -command { Ng_SetDebugParameters } + checkbutton $f.cb.haltlargequal -text "Halt on large quality class" \ + -variable debug.haltlargequalclass -command { Ng_SetDebugParameters } + checkbutton $f.cb.haltseg -text "Halt on Segment:" \ + -variable debug.haltsegment -command { Ng_SetDebugParameters } + checkbutton $f.cb.haltnode -text "Halt on Node:" \ + -variable debug.haltnode -command { Ng_SetDebugParameters } + + + pack $f.cb.slowchecks $f.cb.debugoutput $f.cb.haltexline $f.cb.haltoverlap $f.cb.haltsuc $f.cb.haltnosuc $f.cb.haltlargequal $f.cb.haltseg $f.cb.haltnode + + frame $f.cb.hf + pack $f.cb.hf -pady 5 + checkbutton $f.cb.hf.cb -text "Halt on Face:" \ + -variable debug.haltface -command { Ng_SetDebugParameters } + entry $f.cb.hf.ent -textvariable debug.haltfacenr -width 5 + pack $f.cb.hf.cb $f.cb.hf.ent -side left + + checkbutton $f.cb.showactivechart -text "Show Active Meshing-Chart" \ + -variable stloptions.showactivechart -command { Ng_SetVisParameters; redraw } + + + + + pack $f.cb.showactivechart + + + frame $f.segs + pack $f.segs -pady 5 + label $f.segs.lab1 -text "P1:"; + entry $f.segs.ent1 -width 8 -relief sunken \ + -textvariable debug.haltsegmentp1 + label $f.segs.lab2 -text "P2:"; + entry $f.segs.ent2 -width 8 -relief sunken \ + -textvariable debug.haltsegmentp2 + pack $f.segs.lab1 $f.segs.ent1 $f.segs.lab2 $f.segs.ent2 -side left + + + + frame $f.cont -relief groove -borderwidth 3 + pack $f.cont + #-fill x + + checkbutton $f.cont.multidrawing -text "Draw Meshing" \ + -variable multithread_drawing + pack $f.cont.multidrawing + + checkbutton $f.cont.multitestmode -text "Meshing Testmode" \ + -variable multithread_testmode + pack $f.cont.multitestmode + + button $f.cont.goon -text "Go On" -command { set multithread_pause 0 } + pack $f.cont.multidrawing $f.cont.multitestmode $f.cont.goon -side left -expand yes + + + + + global userlevel + if { $userlevel < 3} { + $w.nb delete insider + $w.nb delete debug + } + + + +# tixButtonBox $w.bbox -orientation horizontal +# $w.bbox add ok -text Apply -underline 0 -width 5 \ +# -command { +# [.options_dlg.nb subwidget meshsize].meshsize invoke +# [.options_dlg.nb subwidget meshsize].grading invoke +# [.options_dlg.nb subwidget optimizer].os2d invoke +# [.options_dlg.nb subwidget optimizer].os3d invoke +# [.options_dlg.nb subwidget optimizer].elw invoke +# [.options_dlg.nb subwidget optimizer].wem invoke + +# Ng_SetMeshingParameters +# } + +# $w.bbox add close -text Done -underline 0 -width 5 \ +# -command { +# [.options_dlg.nb subwidget meshsize].meshsize invoke +# [.options_dlg.nb subwidget meshsize].grading invoke +# [.options_dlg.nb subwidget optimizer].os2d invoke +# [.options_dlg.nb subwidget optimizer].os3d invoke +# [.options_dlg.nb subwidget optimizer].elw invoke +# [.options_dlg.nb subwidget optimizer].wem invoke + +# Ng_SetMeshingParameters +# destroy .options_dlg +# } + +# pack $w.bbox -side bottom -fill x + + + frame $w.bu + pack $w.bu -fill x -ipady 3 + + button $w.bu.apl -text "Apply" -command { + [.options_dlg.nb subwidget meshsize].meshsize invoke + [.options_dlg.nb subwidget meshsize].grading invoke + [.options_dlg.nb subwidget optimizer].os2d invoke + [.options_dlg.nb subwidget optimizer].os3d invoke + [.options_dlg.nb subwidget optimizer].elw invoke + [.options_dlg.nb subwidget optimizer].wem invoke + + Ng_SetMeshingParameters + Ng_SetDebugParameters + } + + button $w.bu.ok -text "Done" -command { + [.options_dlg.nb subwidget meshsize].meshsize invoke + [.options_dlg.nb subwidget meshsize].grading invoke + [.options_dlg.nb subwidget optimizer].os2d invoke + [.options_dlg.nb subwidget optimizer].os3d invoke + [.options_dlg.nb subwidget optimizer].elw invoke + [.options_dlg.nb subwidget optimizer].wem invoke + + Ng_SetMeshingParameters + Ng_SetDebugParameters + wm withdraw .options_dlg +# destroy .options_dlg + } + + pack $w.bu.apl $w.bu.ok -side left -expand yes + + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Meshing Options" + focus .options_dlg + } +} + + +meshingoptionsdialog +wm withdraw .options_dlg + + + + + + + + + +# +# +# Viewing dialog +# +# +proc viewingoptionsdialog { } { + + global userlevel + + set w .viewopts_dlg + + if {[winfo exists .viewopts_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + toplevel $w + + + + + tixNoteBook $w.nb -ipadx 6 -ipady 6 + + $w.nb add general -label "General" -underline 0 + $w.nb add stl -label "STL" -underline 0 + $w.nb add occ -label "IGES/STEP" -underline 0 + $w.nb add mesh -label "Mesh" -underline 0 + $w.nb add light -label "Light" -underline 0 + $w.nb add edges -label "Edges" -underline 0 + $w.nb add misc -label "Misc." -underline 3 + + + pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top + + + + + + # general + set f [$w.nb subwidget general] + + checkbutton $f.backcol -text "White Background" \ + -variable viewoptions.whitebackground \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.cross -text "Draw Coordinate Cross" \ + -variable viewoptions.drawcoordinatecross \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.color -text "Draw Color-bar" \ + -variable viewoptions.drawcolorbar \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.netgen -text "Draw Netgen-logo" \ + -variable viewoptions.drawnetgenlogo \ + -command { Ng_SetVisParameters; redraw } + + pack $f.backcol $f.cross $f.color $f.netgen + +# checkbutton $f.stereo -text "Stereo View" \ +# -variable viewoptions.stereo \ +# -command { Ng_SetVisParameters; redraw } +# pack $f.stereo + + # stl geometry + set f [$w.nb subwidget stl] + + frame $f.show -relief groove -borderwidth 3 + pack $f.show + checkbutton $f.show.showtrias -text "Show STL-Triangles" \ + -variable stloptions.showtrias -command { Ng_SetVisParameters; redraw } + pack $f.show.showtrias -anchor w + + checkbutton $f.show.showfilledtrias -text "Show Filled Triangles" \ + -variable stloptions.showfilledtrias -command { Ng_SetVisParameters; redraw } + pack $f.show.showfilledtrias -anchor w + + checkbutton $f.show.showactivechart -text "Show Active Meshing-Chart" \ + -variable stloptions.showactivechart -command { Ng_SetVisParameters; redraw } + pack $f.show.showactivechart -anchor w + + checkbutton $f.show.showedges -text "Show Edges" \ + -variable stloptions.showedges -command { Ng_SetVisParameters; redraw } + pack $f.show.showedges -anchor w + + frame $f.special -relief groove -borderwidth 3 + pack $f.special + checkbutton $f.special.showmarktrias -text "Show Chart Triangles" \ + -variable stloptions.showmarktrias \ + -command {set stldoctor.showfaces 0; Ng_STLDoctor; Ng_SetVisParameters; redraw } + pack $f.special.showmarktrias -side left + + checkbutton $f.special.showfaces -text "Show Faces" \ + -variable stldoctor.showfaces \ + -command {set stloptions.showmarktrias 0; Ng_STLDoctor; Ng_SetVisParameters; redraw} + pack $f.special.showfaces -side left + + frame $f.fn -relief groove -borderwidth 3 + pack $f.fn + label $f.fn.lab3 -text "Chart/Face number:" + scale $f.fn.scale3 -orient horizontal -length 200 -from 0 -to 200 \ + -resolution 1 -tickinterval 50 \ + -command { Ng_SetVisParameters; redraw } -variable stloptions.chartnumber + pack $f.fn.lab3 $f.fn.scale3 -side left + + frame $f.fo -relief groove -borderwidth 3 + pack $f.fo + label $f.fo.lab -text "Chart/Face Offset:"; + entry $f.fo.ent -width 5 -relief sunken \ + -textvariable stloptions.chartnumberoffset + pack $f.fo.lab $f.fo.ent -side left + + frame $f.mt + pack $f.mt -fill x + checkbutton $f.mt.bu -text "Show Marked (Dirty) Triangles" \ + -variable stldoctor.showmarkedtrigs \ + -command {Ng_STLDoctor; redraw} + pack $f.mt.bu + + frame $f.ep + pack $f.ep -fill x + checkbutton $f.ep.bu -text "show edge corner points" \ + -variable stldoctor.showedgecornerpoints \ + -command {Ng_STLDoctor; redraw} + pack $f.ep.bu + + frame $f.stt + pack $f.stt -fill x + checkbutton $f.stt.bu -text "show touched triangle chart" \ + -variable stldoctor.showtouchedtrigchart \ + -command {set stldoctor.showfaces 0; set stloptions.showmarktrias 1; \ + Ng_STLDoctor; Ng_SetVisParameters; redraw} + pack $f.stt.bu + + frame $f.sml + pack $f.sml -fill x + checkbutton $f.sml.bu -text "draw meshed edges" \ + -variable stldoctor.drawmeshededges \ + -command {Ng_STLDoctor;} + pack $f.sml.bu + + + frame $f.sm + pack $f.sm -fill x + checkbutton $f.sm.bu -text "select with mouse" \ + -variable stldoctor.selectwithmouse + pack $f.sm.bu + + frame $f.st -relief groove -borderwidth 3 + pack $f.st -fill x + label $f.st.lab -text "Select triangle by number"; + entry $f.st.ent -width 5 -relief sunken \ + -textvariable stldoctor.selecttrig + pack $f.st.ent $f.st.lab -side left -expand yes + + frame $f.vc -relief groove -borderwidth 3 + pack $f.vc -fill x + checkbutton $f.vc.bu -text "show vicinity" \ + -variable stldoctor.showvicinity \ + -command {Ng_STLDoctor vicinity; redraw} + label $f.vc.lab -text "vicinity size"; + scale $f.vc.sc -orient horizontal -length 200 -from 0 -to 200 \ + -resolution 1 -variable stldoctor.vicinity \ + -command { Ng_STLDoctor vicinity; redraw } + pack $f.vc.bu $f.vc.lab $f.vc.sc -expand yes + + + + # IGES/STEP + set f [$w.nb subwidget occ] + + checkbutton $f.occshowsurfaces -text "Show surfaces " \ + -variable occoptions.showsurfaces \ + -command { Ng_SetOCCVisParameters; redraw } + + checkbutton $f.occshowedges -text "Show edges " \ + -variable occoptions.showedges \ + -command { Ng_SetOCCVisParameters; redraw } + + frame $f.deflection -relief groove -borderwidth 3 + pack $f.deflection -fill x + button $f.deflection.lab -text "Rebuild visualization data" \ + -command { + Ng_SetOCCVisParameters + Ng_OCCCommand buildvisualizationmesh + redraw + } + + tixControl $f.deflection.ent -label "Visualization smoothness" -integer false \ + -variable occoptions.deflection -min 0.1 -max 3 -step 0.1 \ + -options { entry.width 3 } \ + -command { Ng_SetOCCVisParameters } + + + + + + pack $f.deflection.ent $f.deflection.lab -side left -expand yes + pack $f.occshowsurfaces $f.occshowedges + + + # ACIS visualization / construction + + tixControl $f.showsolid -label "Show solid (0 for all)" -integer true \ + -variable occoptions.showsolidnr -min 0 -max 999 \ + -options { entry.width 3 } \ + -command { Ng_SetOCCVisParameters; redraw } + + tixControl $f.showsolid2 -label "Show solid 2" -integer true \ + -variable occoptions.showsolidnr2 -min 0 -max 999 \ + -options { entry.width 3 } \ + -command { Ng_SetOCCVisParameters; redraw } + + button $f.subtract -text "Subtract (2 minus 1)" \ + -command { + Ng_ACISCommand subtract ${occoptions.showsolidnr} ${occoptions.showsolidnr2} + redraw + } + + button $f.combine -text "Combine all" \ + -command { + Ng_ACISCommand combineall + redraw + } + + pack $f.showsolid $f.showsolid2 $f.subtract $f.combine + + + + + # mesh options + set f [$w.nb subwidget mesh] + + checkbutton $f.showcolor -text "Colored Meshsize Visualization" \ + -variable viewoptions.colormeshsize \ + -command { Ng_SetVisParameters; redraw } + + + checkbutton $f.showfilledtrigs -text "Show filled triangles" \ + -variable viewoptions.drawfilledtrigs \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.showedges -text "Show edges" \ + -variable viewoptions.drawedges \ + -command { Ng_SetVisParameters; redraw } + + + checkbutton $f.showoutline -text "Show Triangle Outline" \ + -variable viewoptions.drawoutline \ + -command { Ng_SetVisParameters; redraw } + + + tixControl $f.subdiv -label "Subdivision" -integer true \ + -variable visoptions.subdivisions -min 0 -max 8 \ + -options { entry.width 2 } \ + -command { Ng_SetVisParameters; Ng_Vis_Set parameters; Ng_SetNextTimeStamp; redraw } + + + checkbutton $f.showbadels -text "Show bad elements" \ + -variable viewoptions.drawbadels \ + -command { Ng_SetVisParameters; redraw } + + + + checkbutton $f.showprisms -text "Show prisms" \ + -variable viewoptions.drawprisms \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.showpyramids -text "Show pyramids" \ + -variable viewoptions.drawpyramids \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.showhexes -text "Show hexes" \ + -variable viewoptions.drawhexes \ + -command { Ng_SetVisParameters; redraw } + + frame $f.fshrink + label $f.fshrink.lab -text "Shrink elements" + scale $f.fshrink.scale -orient horizontal -length 200 -from 0 -to 1.0001 \ + -resolution 0.01 -tickinterval 0.25 \ + -command { Ng_SetVisParameters; redraw } -variable viewoptions.shrink + + + checkbutton $f.showidentified -text "Show identified points" \ + -variable viewoptions.drawidentified \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.showmetispartition -text "Show METIS Partition" \ + -variable viewoptions.drawmetispartition \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $f.showpointnumbers -text "Show Point-numbers" \ + -variable viewoptions.drawpointnumbers \ + -command { Ng_SetVisParameters; redraw } + checkbutton $f.showedgenumbers -text "Show Edge-numbers" \ + -variable viewoptions.drawedgenumbers \ + -command { Ng_SetVisParameters; redraw } + checkbutton $f.showfacenumbers -text "Show Face-numbers" \ + -variable viewoptions.drawfacenumbers \ + -command { Ng_SetVisParameters; redraw } + checkbutton $f.showelementnumbers -text "Show Element-numbers" \ + -variable viewoptions.drawelementnumbers \ + -command { Ng_SetVisParameters; redraw } + + # label $f.showdomainlab -text "Domain Surface" +# scale $f.showdomain -orient horizontal -length 100 -from 0 -to 50 \ + -resolution 1 -variable viewoptions.drawdomainsurf \ + -command { Ng_SetVisParameters; redraw } \ + -label "Domain Surface" + + tixControl $f.showdomain -label "Show surface of domain" -integer true \ + -variable viewoptions.drawdomainsurf -min 0 -max 50 \ + -options { entry.width 2 } \ + -command { Ng_SetVisParameters; Ng_Vis_Set parameters; redraw } + + + + + frame $f.center -relief groove -borderwidth 3 + pack $f.center -fill x + button $f.center.lab -text "Set Center Point" \ + -command { Ng_SetVisParameters; Ng_Center; redraw } + entry $f.center.ent -width 5 -relief sunken \ + -textvariable viewoptions.centerpoint + pack $f.center.ent $f.center.lab -side left -expand yes + + frame $f.drawel -relief groove -borderwidth 3 + pack $f.drawel -fill x + button $f.drawel.lab -text "Draw Element" \ + -command { Ng_SetVisParameters; Ng_ZoomAll; redraw } + entry $f.drawel.ent -width 5 -relief sunken \ + -textvariable viewoptions.drawelement + pack $f.drawel.ent $f.drawel.lab -side left -expand yes + + pack $f.showfilledtrigs + pack $f.showoutline $f.subdiv $f.showedges $f.showbadels + # pack $f.showdomainlab + pack $f.showdomain + pack $f.showpointnumbers + pack $f.showedgenumbers $f.showfacenumbers $f.showelementnumbers + pack $f.showmetispartition + + + frame $f.frametets + checkbutton $f.frametets.showtets -text "Show Tets in domain " \ + -variable viewoptions.drawtets \ + -command { Ng_SetVisParameters; redraw } + tixControl $f.frametets.showtetsdomain -label "" -integer true \ + -variable viewoptions.drawtetsdomain -min 0 -max 500 \ + -options { entry.width 2 } \ + -command { Ng_SetVisParameters; redraw } + + pack $f.frametets + pack $f.frametets.showtets $f.frametets.showtetsdomain -side left + + + pack $f.showcolor $f.showpyramids $f.showprisms $f.showhexes $f.showidentified + + pack $f.fshrink + pack $f.fshrink.lab $f.fshrink.scale -side left + +# if {$userlevel == 3} { +# frame $f.framecurveproj +# checkbutton $f.framecurveproj.showcurveproj -text "Show curved edge projection " \ + -variable viewoptions.drawcurveproj \ + -command { Ng_SetVisParameters; redraw } + # tixControl $f.framecurveproj.showcurveprojedge -label "" -integer true \ + -variable viewoptions.drawcurveprojedge -min 1 -max 99999 \ + -options { entry.width 5 } \ + -command { Ng_SetVisParameters; redraw } + +# pack $f.framecurveproj +# pack $f.framecurveproj.showcurveproj $f.framecurveproj.showcurveprojedge -side left +# } + + + + + + + # light options + set f [$w.nb subwidget light] + + label $f.lab1 -text "Ambient Light" + scale $f.scale1 -orient horizontal -length 300 -from 0 -to 1 \ + -resolution 0.01 -tickinterval 0.2 \ + -command { Ng_SetVisParameters; redraw } -variable viewoptions.light.amb + label $f.lab2 -text "Diffuse Light" + scale $f.scale2 -orient horizontal -length 300 -from 0 -to 1 \ + -resolution 0.01 -tickinterval 0.2 \ + -command { Ng_SetVisParameters; redraw } -variable viewoptions.light.diff + label $f.lab3 -text "Specular Light" + scale $f.scale3 -orient horizontal -length 300 -from 0 -to 1 \ + -resolution 0.01 -tickinterval 0.2 \ + -command { Ng_SetVisParameters; redraw } -variable viewoptions.light.spec + label $f.lab4 -text "Material Shininess" + scale $f.scale4 -orient horizontal -length 300 -from 0 -to 128 \ + -resolution 1 -tickinterval 32 \ + -command { Ng_SetVisParameters; redraw } -variable viewoptions.mat.shininess + label $f.lab5 -text "Material Transparency" + scale $f.scale5 -orient horizontal -length 300 -from 0 -to 1 \ + -resolution 0.01 -tickinterval 0.2 \ + -command { Ng_SetVisParameters; redraw } -variable viewoptions.mat.transp + + pack $f.lab1 $f.scale1 $f.lab2 $f.scale2 $f.lab3 $f.scale3 $f.lab4 $f.scale4 $f.lab5 $f.scale5 + + + + + + # edges options + set f [$w.nb subwidget edges] + + checkbutton $f.showedges -text "Show Edges" \ + -variable viewoptions.drawededges \ + -command { Ng_SetVisParameters; redraw } + checkbutton $f.showpoints -text "Show Points" \ + -variable viewoptions.drawedpoints \ + -command { Ng_SetVisParameters; redraw } + checkbutton $f.showpointnrs -text "Show Points Nrs" \ + -variable viewoptions.drawedpointnrs \ + -command { Ng_SetVisParameters; redraw } + checkbutton $f.showtang -text "Show CP Tangents" \ + -variable viewoptions.drawedtangents \ + -command { Ng_SetVisParameters; redraw } + checkbutton $f.drawedgenrs -text "Show Edge Nrs" \ + -variable viewoptions.drawededgenrs \ + -command { Ng_SetVisParameters; redraw } + + pack $f.showedges $f.showpoints $f.showpointnrs $f.showtang $f.drawedgenrs + + frame $f.center -relief groove -borderwidth 3 + pack $f.center -fill x + button $f.center.lab -text "Set Center Point" \ + -command { Ng_SetVisParameters; Ng_Center; redraw } + entry $f.center.ent -width 5 -relief sunken \ + -textvariable viewoptions.centerpoint + pack $f.center.ent $f.center.lab -side left -expand yes + + + + frame $f.f1 + pack $f.f1 -pady 5 + label $f.f1.lab -text "SpecPoint Veclen" + entry $f.f1.ent -width 5 -relief sunken -textvariable viewoptions.specpointvlen + pack $f.f1.lab $f.f1.ent + + + + + # misc options + set f [$w.nb subwidget misc] + + frame $f.point -relief groove -borderwidth 3 + + frame $f.point.dp + + checkbutton $f.point.dp.drawpoint -text "Draw Point" \ + -variable viewoptions.drawspecpoint \ + -command { Ng_SetVisParameters; redraw } + + entry $f.point.dp.px -width 8 -relief sunken -textvariable viewoptions.specpointx + entry $f.point.dp.py -width 8 -relief sunken -textvariable viewoptions.specpointy + entry $f.point.dp.pz -width 8 -relief sunken -textvariable viewoptions.specpointz + + pack $f.point.dp.drawpoint $f.point.dp.px $f.point.dp.py $f.point.dp.pz -side left + + pack $f.point.dp + + checkbutton $f.point.center -text "Use as Center" \ + -variable viewoptions.usecentercoords \ + -command { + if { ${viewoptions.usecentercoords} } { + set viewoptions.centerx ${viewoptions.specpointx} + set viewoptions.centery ${viewoptions.specpointy} + set viewoptions.centerz ${viewoptions.specpointz} + Ng_SetVisParameters; Ng_Center + redraw + } { + Ng_SetVisParameters + } + + + } + + pack $f.point.center + + pack $f.point -fill x -ipady 3 + + + + frame $w.bu + pack $w.bu -fill x -ipady 3 + + + button $w.bu.done -text "Done" -command { + Ng_SetVisParameters; + redraw + destroy .viewopts_dlg + } + button $w.bu.apply -text "Apply" -command { + Ng_SetVisParameters; + redraw + } + pack $w.bu.apply $w.bu.done -expand yes -side left + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Viewing options" + focus $w + } +} + + + +proc clipplanecommand { { optionalvar 0 } } { + Ng_SetVisParameters + after idle redraw +} + + +set clippingdialog_pop1 0 +set clippingdialog_pop2 0 +set clippingdialog_pop3 0 +set clippingdialog_pop4 0 + + +# +# +# clipping dialog +# +# +proc clippingdialog { } { + + global clippingdialog_pop1 + global clippingdialog_pop2 + global clippingdialog_pop3 + global clippingdialog_pop4 + set clippingdialog_pop1 1 + set clippingdialog_pop2 1 + set clippingdialog_pop3 1 + set clippingdialog_pop4 1 + + set w .clipping_dlg + + if {[winfo exists .clipping_dlg] == 1} { + + wm withdraw $w + wm deiconify $w + focus $w + + } { + toplevel $w + + label $w.lab1 -text "Normal x" + scale $w.scale1 -orient horizontal -length 300 -from -1 -to 1 \ + -resolution 0.01 -tickinterval 0.5 \ + -variable viewoptions.clipping.nx \ + -command { clipplanecommand } +# -command { popupcheckredraw2 clippingdialog_pop1 ${viewoptions.clipping.enable} } + +# Ng_SetVisParameters; +# if { ${viewoptions.clipping.enable} == 1 } { redraw }; +# Ng_SetVisParameters + + label $w.lab2 -text "Normal y" + scale $w.scale2 -orient horizontal -length 300 -from -1 -to 1 \ + -resolution 0.01 -tickinterval 0.5 \ + -variable viewoptions.clipping.ny \ + -command { clipplanecommand } +# -command { popupcheckredraw2 clippingdialog_pop2 ${viewoptions.clipping.enable} } + + label $w.lab3 -text "Normal z" + scale $w.scale3 -orient horizontal -length 300 -from -1 -to 1 \ + -resolution 0.01 -tickinterval 0.5 \ + -variable viewoptions.clipping.nz \ + -command { clipplanecommand } +# -command { popupcheckredraw2 clippingdialog_pop3 ${viewoptions.clipping.enable} } + label $w.lab4 -text "Distance" + scale $w.scale4 -orient horizontal -length 300 -from -1 -to 1.001 \ + -resolution 0.0001 -tickinterval 0.5 \ + -variable viewoptions.clipping.dist \ + -command { clipplanecommand } +# -command { popupcheckredraw2 clippingdialog_pop4 ${viewoptions.clipping.enable} } + + label $w.lab5 -text "Additional Distance" + scale $w.scale5 -orient horizontal -length 300 -from -1 -to 1.001 \ + -resolution 0.0001 -tickinterval 0.5 \ + -variable viewoptions.clipping.dist2 \ + -command { clipplanecommand } + + + + tixControl $w.clipdomain -label "Clip only domain" -integer true \ + -variable viewoptions.clipping.onlydomain -min 0 -max 50 \ + -options { entry.width 2 } \ + -command { clipplanecommand; } +# -command { Ng_SetVisParameters; redraw } + tixControl $w.donotclipdomain -label "Do not clip domain" -integer true \ + -variable viewoptions.clipping.notdomain -min 0 -max 50 \ + -options { entry.width 2 } \ + -command { clipplanecommand; } +# -command { Ng_SetVisParameters; redraw } + + pack $w.lab1 $w.scale1 $w.lab2 $w.scale2 $w.lab3 $w.scale3 $w.lab4 $w.scale4 $w.lab5 $w.scale5 $w.clipdomain $w.donotclipdomain + + + checkbutton $w.cb1 -text "Enable clipping" \ + -variable viewoptions.clipping.enable \ + -command { Ng_SetVisParameters; redraw } + + pack $w.cb1 + + + + frame $w.bu +# pack $w.bu -fill x + pack $w.bu -fill x -ipady 3 + + button $w.bu.cancle -text "Done" -command "destroy $w" + pack $w.bu.cancle -expand yes + + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Clipping Plane" + # grab $w + focus $w + +# $w.scale1 configure -command { puts "call1b"; Ng_SetVisParameters; redraw } +# puts "after" + + clipplanecommand + } +} + + + + + +# +# refinement dialog +# +# +proc refinementdialog { } { + + set w .refinement_dlg + + if {[winfo exists .refinement_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + + toplevel $w + + + tixControl $w.meshsize -label "max mesh-size: " -integer false \ + -variable options.meshsize -min 1e-6 -max 1e6 \ + -options { + entry.width 6 + label.width 25 + label.anchor e + } + + pack $w.meshsize + + global localh + set localh 1 + tixControl $w.loch -label "local mesh-size: " -integer false \ + -variable localh -min 1e-6 -max 1e6 \ + -options { + entry.width 6 + label.width 25 + label.anchor e + } + + pack $w.loch + + + button $w.restface -text "Restrict H at face" \ + -command { + .refinement_dlg.meshsize invoke + .refinement_dlg.loch invoke + Ng_RestrictH face $localh + } + button $w.restedge -text "Restrict H at edge" \ + -command { + .refinement_dlg.meshsize invoke + .refinement_dlg.loch invoke + Ng_RestrictH edge $localh + } + button $w.restelement -text "Restrict H at element" \ + -command { + .refinement_dlg.meshsize invoke + .refinement_dlg.loch invoke + Ng_RestrictH element $localh + } + button $w.restpoint -text "Restrict H at point" \ + -command { + .refinement_dlg.meshsize invoke + .refinement_dlg.loch invoke + Ng_RestrictH point $localh + } + + + pack $w.restface $w.restedge $w.restelement $w.restpoint + + + + button $w.anisoedge -text "Declare Anisotropic edge" \ + -command { + Ng_Anisotropy edge + } + pack $w.anisoedge + + + frame $w.bu + pack $w.bu -fill x -ipady 3 + + + button $w.bu.cancle -text "Done" -command "destroy .refinement_dlg" + button $w.bu.refine -text "Refine" \ + -command { +# Ng_BisectCopyMesh; + set oldnp 0; set newnp $status_np; + while { $oldnp < $newnp } { + set level [expr $level+1] + Ng_Bisect; + Ng_HighOrder ${options.elementorder} + Ng_ReadStatus; + redraw; + set oldnp $newnp + set newnp $status_np + puts "oldnp $oldnp newnp $newnp" + } + } + button $w.bu.zrefine -text "Z-Refine" \ + -command { Ng_ZRefinement; Ng_ReadStatus; redraw; } + + pack $w.bu.zrefine $w.bu.refine $w.bu.cancle -expand yes -side left + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Select Refinement" + focus $w + } +} + + + + +# +# boundcondessing dialog +# +# +proc bcpropdialog { } { + + set w .bcprop_dlg + + if {[winfo exists .bcprop_dlg] == 1} { + wm withdraw $w + wm deiconify $w + } { + toplevel $w + + frame $w.face -borderwidth 3 + pack $w.face -fill x + label $w.face.lab -text "face index:" + label $w.face.ent -text 1 -padx 4 + button $w.face.next -text "next" -command { + set w .bcprop_dlg; + set facenr [$w.face.ent cget -text] + if {$facenr == [Ng_BCProp getnfd]} { + set facenr 1 + } { + set facenr [expr $facenr + 1] + } + $w.face.ent configure -text $facenr + Ng_BCProp setactive $facenr + set bcnr [Ng_BCProp getbc $facenr] + $w.bc.ent delete 0 end + $w.bc.ent insert 0 $bcnr + + redraw + } + button $w.face.prev -text "prev" -command { + set w .bcprop_dlg; + set facenr [$w.face.ent cget -text] + if {$facenr == 1} { + set facenr [Ng_BCProp getnfd] + } { + set facenr [expr $facenr - 1] + } + $w.face.ent configure -text $facenr + Ng_BCProp setactive $facenr + set bcnr [Ng_BCProp getbc $facenr] + $w.bc.ent delete 0 end + $w.bc.ent insert 0 $bcnr + + redraw + } + + + pack $w.face.lab $w.face.ent $w.face.prev $w.face.next -side left + + frame $w.bc -borderwidth 3 + pack $w.bc -fill x + label $w.bc.lab -text "bc property:" + entry $w.bc.ent -width 5 -relief sunken + button $w.bc.but -text "change" -command { + set w .bcprop_dlg; + Ng_BCProp setbc [$w.face.ent cget -text] [$w.bc.ent get]; + } + button $w.bc.but2 -text "all" -command { + set w .bcprop_dlg; + Ng_BCProp setall [$w.bc.ent get]; + } + pack $w.bc.lab $w.bc.ent $w.bc.but $w.bc.but2 -side left -expand yes + + frame $w.bcname -borderwidth 3 + pack $w.bcname -fill x + label $w.bcname.lab -text "bc name:" + label $w.bcname.ent -text "-" + pack $w.bcname.lab $w.bcname.ent -side left -expand yes + + + frame $w.bu + pack $w.bu -fill x -ipady 3 + + button $w.bu.close -text "Close" -command { destroy .bcprop_dlg } + + pack $w.bu.close -expand yes -side left + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Boundary Conditions" + } + + focus $w + + set facenr [Ng_BCProp getactive] + $w.face.ent configure -text $facenr + + set bcnr [Ng_BCProp getbc $facenr] + $w.bc.ent delete 0 end + $w.bc.ent insert 0 $bcnr + + set bcname [Ng_BCProp getbcname $facenr] + $w.bcname.ent configure -text $bcname + +} + + + + +# +# Philippose - 25/07/2010 +# Display the face colours currently +# available in the mesh +# +proc currmeshcoloursdialog { } { + + set w .currmeshcolours_dlg + + if {[winfo exists .currmeshcolours_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + toplevel $w + + global facecolslist + + frame $w.facecols -borderwidth 3 + + listbox $w.facecols.list -yscroll "$w.facecols.scroll set" -selectmode single -setgrid 1 -width 32 -height 12 + scrollbar $w.facecols.scroll -command "$w.facecols.list yview" + pack $w.facecols.scroll -side right -fill y + pack $w.facecols.list -side left -expand yes -fill both + + Ng_CurrentFaceColours getcolours facecolslist + set i 1 + foreach el $facecolslist { + set hel [format "%d: (%.4f %.4f %.4f)" $i [ lindex $el 0 ] [ lindex $el 1 ] [ lindex $el 2 ]] + incr i + $w.facecols.list insert end $hel } + + frame $w.bu1 -borderwidth 3 + button $w.bu1.showonly -text "show only" -command { + Ng_CurrentFaceColours showonly [.currmeshcolours_dlg.facecols.list curselection] + redraw + } + button $w.bu1.hideonly -text "hide only" -command { + Ng_CurrentFaceColours hideonly [.currmeshcolours_dlg.facecols.list curselection] + redraw + } + button $w.bu1.showalso -text "show" -command { + Ng_CurrentFaceColours showalso [.currmeshcolours_dlg.facecols.list curselection] + redraw + } + button $w.bu1.hidealso -text "hide" -command { + Ng_CurrentFaceColours hidealso [.currmeshcolours_dlg.facecols.list curselection] + redraw + } + pack $w.bu1.showonly $w.bu1.hideonly $w.bu1.showalso $w.bu1.hidealso -expand yes -fill x -padx 2 -pady 2 -side left + + frame $w.bu2 + button $w.bu2.showall -text "show all" -command { + Ng_CurrentFaceColours showall + redraw + } + button $w.bu2.hideall -text "hide all" -command { + Ng_CurrentFaceColours hideall + redraw + } + pack $w.bu2.showall $w.bu2.hideall -expand yes -fill x -padx 2 -pady 2 -side left + + frame $w.bu3 + button $w.bu3.close -text "close" -command { + destroy .currmeshcolours_dlg + } + pack $w.bu3.close -expand yes -fill x -pady 3 -side right + + + pack $w.facecols -side top -expand yes -fill x -fill y + pack $w.bu3 -side bottom + pack $w.bu2 -side bottom + pack $w.bu1 -expand yes -fill x -side left + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Inspect Mesh Colours" + focus $w + } +} + + + + +# +# Philippose - 30/01/2009 +# Local Surface Mesh Size Selection +# (Currently only supports OCC Geometry) +# +# +proc surfacemeshsizedialog { } { + + set w .surfacemeshsize_dlg + + if {[winfo exists .surfacemeshsize_dlg] == 1} { + wm withdraw $w + wm deiconify $w + } { + toplevel $w + + frame $w.face -borderwidth 3 + pack $w.face -fill x -padx 5 + label $w.face.lab -text "face index:" + label $w.face.ent -text 1 -padx 4 + button $w.face.next -text "next" -command { + set w .surfacemeshsize_dlg; + set facenr [$w.face.ent cget -text] + if {$facenr == [Ng_SurfaceMeshSize getnfd]} { + set facenr 1 + } { + set facenr [expr $facenr + 1] + } + $w.face.ent configure -text $facenr + Ng_SurfaceMeshSize setactive $facenr + set surfms [Ng_SurfaceMeshSize getsurfms $facenr] + $w.sms.ent delete 0 end + $w.sms.ent insert 0 $surfms + + redraw + } + button $w.face.prev -text "prev" -command { + set w .surfacemeshsize_dlg; + set facenr [$w.face.ent cget -text] + if {$facenr == 1} { + set facenr [Ng_SurfaceMeshSize getnfd] + } { + set facenr [expr $facenr - 1] + } + $w.face.ent configure -text $facenr + Ng_SurfaceMeshSize setactive $facenr + set surfms [Ng_SurfaceMeshSize getsurfms $facenr] + $w.sms.ent delete 0 end + $w.sms.ent insert 0 $surfms + + redraw + } + + + pack $w.face.lab $w.face.ent $w.face.prev $w.face.next -side left + + frame $w.sms -borderwidth 3 + pack $w.sms -fill x + label $w.sms.lab -text "max mesh size:" + entry $w.sms.ent -width 8 -relief sunken + button $w.sms.but -text "change" -command { + set w .surfacemeshsize_dlg; + Ng_SurfaceMeshSize setsurfms [$w.face.ent cget -text] [$w.sms.ent get]; + } + button $w.sms.but2 -text "all" -command { + set w .surfacemeshsize_dlg; + Ng_SurfaceMeshSize setall [$w.sms.ent get]; + } + pack $w.sms.lab $w.sms.ent $w.sms.but $w.sms.but2 -side left -padx 5 -expand yes + + frame $w.bu + pack $w.bu -fill x -ipady 3 + + button $w.bu.close -text "Close" -command { destroy .surfacemeshsize_dlg } + + pack $w.bu.close -expand yes -side left + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Edit Surface Mesh Size" + } + + focus $w + + set facenr [Ng_SurfaceMeshSize getactive] + $w.face.ent configure -text $facenr + + set surfms [Ng_SurfaceMeshSize getsurfms $facenr] + $w.sms.ent delete 0 end + $w.sms.ent insert 0 $surfms + +} + + + + +# +# METIS dialog +# +# +proc METISdialog { } { + + set w .metis_dlg + set w.parts 64 + + if {[winfo exists .metis_dlg] == 1} { + wm withdraw $w + wm deiconify $w + } { + toplevel $w + + frame $w.a -borderwidth 0 + frame $w.b -borderwidth 0 + pack $w.a $w.b + + label $w.a.lab -text "Number of partitions:" + entry $w.a.ent -textvariable w.parts -width 4 -relief sunken + + button $w.b.start -text "Start METIS" -command { + Ng_Metis ${w.parts} + redraw + } + button $w.b.cancel -text "Cancel" -command { destroy .metis_dlg } + pack $w.a.lab $w.a.ent -side left -expand yes + pack $w.b.start $w.b.cancel -side left + + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "METIS Partitioning" + focus $w + + } +} + + + +# +# STL dialog +# +proc stloptionsdialog { } { + + set w .stlopts_dlg + + if {[winfo exists .stlopts_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + toplevel $w + + tixNoteBook $w.nb -ipadx 6 -ipady 6 + # $w config -bg gray + # $w.nb subwidget nbframe config -backpagecolor gray + + # Create the two tabs on the notebook. The -underline option + # puts a underline on the first character of the labels of the tabs. + # Keyboard accelerators will be defined automatically according + # to the underlined character. + # + +# $w.nb add chartopt -label "Chart Options" -underline 0 +# #$w.nb add meshsize -label "Mesh Size" -underline 0 +# pack $w.nb -expand yes -fill both -padx 5 -pady 5 -side top + + +# set f [$w.nb subwidget chartopt] + + +# label $f.lab1 -text "Yellow Edges Angle ()" +# scale $f.scale1 -orient horizontal -length 300 \ +# -from 0 -to 90 -resolution 1 -tickinterval 10 \ +# -variable stloptions.yangle + +# pack $f.lab1 $f.scale1 + +# label $f.lab2e -text "Edge Corner Angle ()" +# scale $f.scale2e -orient horizontal -length 360 -from 0 -to 180 \ +# -resolution 1 -tickinterval 20 \ +# -variable stloptions.edgecornerangle +# pack $f.lab2e $f.scale2e + +# label $f.lab2 -text "Chart Angle ()" +# scale $f.scale2 -orient horizontal -length 360 -from 0 -to 180 \ +# -resolution 1 -tickinterval 20 \ +# -variable stloptions.chartangle +# pack $f.lab2 $f.scale2 + +# label $f.lab2b -text "Outer Chart Angle ()" +# scale $f.scale2b -orient horizontal -length 360 -from 0 -to 180 \ +# -resolution 1 -tickinterval 20 \ +# -variable stloptions.outerchartangle +# pack $f.lab2b $f.scale2b + +# frame $f.r4 +# pack $f.r4 -anchor w +# scale $f.r4.sc -orient horizontal -length 200 -from 0.1 -to 10 \ +# -resolution 0.1 -variable stloptions.resthatlasfac +# checkbutton $f.r4.bu -text "Restrict h for Calc Atlas (Faster)" \ +# -variable stloptions.resthatlasenable +# pack $f.r4.sc $f.r4.bu -side left + + + #set f [$w.nb subwidget meshsize] + + + +# checkbutton $w.seat -text "Use Searchtrees" \ +# -variable stloptions.usesearchtree +# pack $w.seat + + + + + frame $w.bu +# pack $w.bu + pack $w.bu -fill x -ipady 3 + +# -fill x + + button $w.bu.apply -text "Apply" -command { redraw; Ng_GenerateMesh 1 2} + button $w.bu.cancle -text "Done" -command { destroy .stlopts_dlg } + pack $w.bu.cancle $w.bu.apply -side left -expand yes + + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "STL Options" +# grab $w + focus $w + } +} + +proc stldoctordialog { } { + + set wd .stldoctor_dlg + + if {[winfo exists .stldoctor_dlg] == 1} { + wm withdraw $wd + wm deiconify $wd + focus $wd + } { + + toplevel $wd + + tixNoteBook $wd.nb -ipadx 6 -ipady 6 + + $wd.nb add general -label "General" -underline 0 + $wd.nb add topology -label "Edit Topology" -underline 5 + $wd.nb add edges -label "Edit Edges" -underline 5 + $wd.nb add normals -label "Edit Normals" -underline 5 + $wd.nb add advanced -label "Advanced" -underline 0 + + + pack $wd.nb -expand yes -fill both -padx 5 -pady 5 -side top + + + # GENERAL ***************************** + + set f [$wd.nb subwidget general] + + + frame $f.show + pack $f.show -fill x + checkbutton $f.show.showtrias -text "Show STL-Triangles" \ + -variable stloptions.showtrias -command { Ng_SetVisParameters; redraw } + pack $f.show.showtrias -anchor w + + checkbutton $f.show.showfilledtrias -text "Show Filled Triangles" \ + -variable stloptions.showfilledtrias -command { Ng_SetVisParameters; redraw } + pack $f.show.showfilledtrias -anchor w + + set selmodevals { 0 1 2 3 4 } + set selmodelabs(0) "triangle" + set selmodelabs(1) "edge" + set selmodelabs(2) "point" + set selmodelabs(3) "line" + set selmodelabs(4) "line cluster" + + tixOptionMenu $f.selmode -label "Double Click selects :" \ + -options { + label.width 19 + label.anchor e + menubutton.width 15 + } + + foreach selmodev $selmodevals { + $f.selmode add command $selmodev -label $selmodelabs($selmodev) + } + $f.selmode config -variable stldoctor.selectmode + $f.selmode config -command { Ng_STLDoctor } + global stldoctor.selectmode + pack $f.selmode + + frame $f.sm + pack $f.sm -fill x + checkbutton $f.sm.bu -text "select with mouse" \ + -variable stldoctor.selectwithmouse + pack $f.sm.bu + + frame $f.st -relief groove -borderwidth 3 + pack $f.st -fill x + label $f.st.lab -text "Select triangle by number"; + entry $f.st.ent -width 5 -relief sunken \ + -textvariable stldoctor.selecttrig + pack $f.st.ent $f.st.lab -side left -expand yes + + frame $f.vc -relief groove -borderwidth 3 + pack $f.vc -fill x + checkbutton $f.vc.bu -text "show vicinity" \ + -variable stldoctor.showvicinity \ + -command {Ng_STLDoctor vicinity; redraw} + label $f.vc.lab -text "vicinity size"; + scale $f.vc.sc -orient horizontal -length 200 -from 0 -to 200 \ + -resolution 1 -variable stldoctor.vicinity \ + -command { Ng_STLDoctor vicinity; redraw } + pack $f.vc.bu $f.vc.lab $f.vc.sc -expand yes + + frame $f.ge -relief groove -borderwidth 3 + pack $f.ge -fill x + button $f.ge.neighbourangles -text "calc neighbourangles" -command {Ng_STLDoctor neighbourangles} + button $f.ge.showcoords -text "show coords of touched triangle" -command {Ng_STLDoctor showcoords} + button $f.ge.moveptm -text "move point to middle of trianglepoints" -command {Ng_STLDoctor movepointtomiddle; redraw} + button $f.ge.destroy0trigs -text "destroy 0-volume triangles" -command {Ng_STLDoctor destroy0trigs} + pack $f.ge.neighbourangles $f.ge.showcoords $f.ge.moveptm $f.ge.destroy0trigs -expand yes + + + button $f.ge.cancle -text "Done" -command {destroy .stldoctor_dlg } + pack $f.ge.cancle -expand yes + + # TOPOLOGY ******************** + set f [$wd.nb subwidget topology] + + frame $f.oc -relief groove -borderwidth 3 + pack $f.oc -fill x + button $f.oc.bu -text "invert orientation of selected trig" -command {Ng_STLDoctor invertselectedtrig; redraw } + button $f.oc.bu2 -text "orient after selected trig" -command {Ng_STLDoctor orientafterselectedtrig; redraw } + pack $f.oc.bu $f.oc.bu2 -side left -expand yes + + button $f.toperr -text "mark inconsistent triangles" -command {Ng_STLDoctor marktoperrortrigs; redraw } + + button $f.deltrig -text "delete selected triangle" -command {Ng_STLDoctor deleteselectedtrig; redraw } + button $f.geosmooth -text "geometric smoothing" -command {Ng_STLDoctor smoothgeometry; redraw } + + pack $f.toperr $f.deltrig $f.geosmooth + + + + + + # EDGES *********************** + set f [$wd.nb subwidget edges] + + + frame $f.be -relief groove -borderwidth 3 + pack $f.be -fill x + label $f.be.lab -text "build edges with yellow angle:"; + scale $f.be.sc -orient horizontal -length 200 -from 0 -to 100 \ + -resolution 0.5 + $f.be.sc config -variable stloptions.yangle + $f.be.sc config -command { Ng_SetSTLParameters; Ng_STLDoctor buildedges; redraw } + label $f.be.lab2 -text "continue edges with yellow angle:"; + scale $f.be.sc2 -orient horizontal -length 200 -from 0 -to 100 \ + -resolution 0.5 + $f.be.sc2 config -variable stloptions.contyangle + $f.be.sc2 config -command { Ng_SetSTLParameters; Ng_STLDoctor buildedges; redraw } + + + + button $f.be.buildedges -text "Build Edges" -command {Ng_STLDoctor buildedges; redraw} + pack $f.be.lab $f.be.sc $f.be.lab2 $f.be.sc2 $f.be.buildedges -expand yes + + frame $f.se + pack $f.se -fill x + checkbutton $f.se.bu -text "show excluded" \ + -variable stldoctor.showexcluded \ + -command {Ng_STLDoctor; redraw} + pack $f.se.bu + + # edgeselectmode ****** + + set edgeselmodevals { 0 1 2 3 4 } + set edgeselmodelabs(0) "no change" + set edgeselmodelabs(1) "undefined" + set edgeselmodelabs(2) "confirmed" + set edgeselmodelabs(3) "candidate" + set edgeselmodelabs(4) "excluded" + + tixOptionMenu $f.edgeselmode -label "Double Click sets edge :" \ + -options { + label.width 19 + label.anchor e + menubutton.width 15 + } + + foreach edgeselmodev $edgeselmodevals { + $f.edgeselmode add command $edgeselmodev -label $edgeselmodelabs($edgeselmodev) + } + $f.edgeselmode config -variable stldoctor.edgeselectmode + $f.edgeselmode config -command { Ng_STLDoctor } + global stldoctor.edgeselectmode + pack $f.edgeselmode + + # edge buttons + + frame $f.edg -relief groove -borderwidth 3 + pack $f.edg -fill x + +# checkbutton $f.edg.bu -text "use external edges" \ +# -variable stldoctor.useexternaledges \ +# -command {Ng_STLDoctor; redraw} +# pack $f.edg.bu -expand yes + + + frame $f.edg.f0 + pack $f.edg.f0 + button $f.edg.f0.confirmedge -text "confirm" -command {Ng_STLDoctor confirmedge; redraw} + button $f.edg.f0.candidateedge -text "candidate" -command {Ng_STLDoctor candidateedge; redraw} + button $f.edg.f0.excludeedge -text "exclude" -command {Ng_STLDoctor excludeedge; redraw} + button $f.edg.f0.undefinededge -text "undefined" -command {Ng_STLDoctor undefinededge; redraw} + pack $f.edg.f0.confirmedge $f.edg.f0.candidateedge $f.edg.f0.excludeedge $f.edg.f0.undefinededge -side left + + frame $f.edg.fa + pack $f.edg.fa + button $f.edg.fa.setallundefined -text "all undefined" -command {Ng_STLDoctor setallundefinededges; redraw} + button $f.edg.fa.erasecandidates -text "candidates to undefined" -command {Ng_STLDoctor erasecandidateedges; redraw} + pack $f.edg.fa.setallundefined $f.edg.fa.erasecandidates -side left + + + frame $f.edg.fb + pack $f.edg.fb + button $f.edg.fb.confirmcandidates -text "candidates to confirmed" -command {Ng_STLDoctor confirmcandidateedges; redraw} + button $f.edg.fb.confirmedtocandidates -text "confirmed to candidates" -command {Ng_STLDoctor confirmedtocandidateedges; redraw} + pack $f.edg.fb.confirmcandidates $f.edg.fb.confirmedtocandidates -side left + + frame $f.edg.f1 + frame $f.edg.f2 + frame $f.edg.f3 + frame $f.edg.f4 + pack $f.edg.f1 $f.edg.f2 $f.edg.f3 $f.edg.f4 + + button $f.edg.f1.exportedges -text "export edges" -command {Ng_STLDoctor exportedges} + button $f.edg.f1.importedges -text "import edges" -command {Ng_STLDoctor importedges; redraw} + button $f.edg.f1.saveedgedata -text "save edgedata" \ + -command { + set types { + {"Netgen Edgedata" {.ned} } + } + set file [tk_getSaveFile -filetypes $types -defaultextension ".ned"] + if {$file != ""} { + Ng_STLDoctor saveedgedata $file + } + } + + button $f.edg.f1.loadedgedata -text "load edgedata" \ + -command { + set types { + {"Netgen Edgedata" {.ned} } + } + set file [tk_getOpenFile -filetypes $types -defaultextension ".ned"] + if {$file != ""} { + Ng_STLDoctor loadedgedata $file + puts "loading done" + + redraw + +# wm title . [concat "NETGEN - " $file] + } + } + + button $f.edg.f1.importAVLedges -text "import AVL edges" \ + -command { + set types {{"Edge file" {.edg }}} + + set file [tk_getOpenFile -filetypes $types -defaultextension ".edg"] + if {$file != ""} { + Ng_STLDoctor importexternaledges $file; + } + } + + pack $f.edg.f1.importAVLedges $f.edg.f1.loadedgedata $f.edg.f1.saveedgedata -side left + +# button $f.edg.f1.buildedges -text "build external edges" -command {Ng_STLDoctor buildexternaledges; redraw} + frame $f.edg2 -relief groove -borderwidth 3 + pack $f.edg2 -fill x + + +# button $f.edg2.addlonglines -text "make long lines candidates (% of diam)" -command {Ng_STLDoctor addlonglines; redraw} + label $f.edg2.lab -text "length (%):" + scale $f.edg2.sc -orient horizontal -length 200 -from 0 -to 100 \ + -resolution 0.5 \ + -variable stldoctor.longlinefact + + # button $f.edg2.deletedirtyedges -text "make dirty edges candidates" -command {Ng_STLDoctor deletedirtyedges; redraw} + button $f.edg2.undoedge -text "undo last edge change" -command {Ng_STLDoctor undoedgechange; redraw} + + # pack $f.edg2.addlonglines $f.edg2.deletedirtyedges -expand yes + # pack $f.edg2.lab $f.edg2.sc -side left + pack $f.edg2.undoedge -expand yes + + + + # NORMALS *********************** + set f [$wd.nb subwidget normals] + + frame $f.dt -relief groove -borderwidth 3 + pack $f.dt -fill x + label $f.dt.lab -text "dirty triangle factor"; + entry $f.dt.ent -width 5 -relief sunken \ + -textvariable stldoctor.dirtytrigfact + pack $f.dt.ent $f.dt.lab -side left -expand yes + + frame $f.srt -relief groove -borderwidth 3 + pack $f.srt -fill x + button $f.srt.bu -text "smooth reverted triangles geometric" -command {Ng_STLDoctor smoothrevertedtrigs; redraw } + entry $f.srt.ent -width 5 -relief sunken \ + -textvariable stldoctor.smoothangle + pack $f.srt.ent $f.srt.bu -side left -expand yes + + frame $f.bdt -relief groove -borderwidth 3 + pack $f.bdt -fill x + button $f.bdt.bu -text "mark dirty triangles" -command {Ng_STLDoctor markdirtytrigs; redraw } + button $f.bdt.bu2 -text "smooth dirty triangles normal" -command {Ng_STLDoctor smoothdirtytrigs; redraw } + pack $f.bdt.bu $f.bdt.bu2 -side left -expand yes + + + frame $f.sno -relief groove -borderwidth 3 + pack $f.sno + + label $f.sno.labrough -text "rough" + scale $f.sno.scsmooth -orient horizontal -length 100 -from 0 -to 0.8 \ + -resolution 0.01 -variable stldoctor.smoothnormalsweight \ + -command { Ng_SetSTLParameters } + label $f.sno.labsmooth -text "smooth" + button $f.sno.smoothnormals -text "smooth normals" -command { Ng_STLDoctor smoothnormals; redraw} + + + + pack $f.sno.labrough $f.sno.scsmooth $f.sno.labsmooth $f.sno.smoothnormals -side left -padx 5 + + frame $f.no -relief groove -borderwidth 3 + pack $f.no -fill x + + button $f.no.marknonsmoothnormals -text "mark non-smooth triangles" -command {Ng_STLDoctor marknonsmoothnormals; redraw} + button $f.no.calcnormals -text "calculate normals from geometry" -command {Ng_STLDoctor calcnormals; redraw} + + pack $f.no.marknonsmoothnormals $f.no.calcnormals -expand yes + + + # ADVANCED ************************** + set f [$wd.nb subwidget advanced] + + + frame $f.sc + pack $f.sc -fill x + checkbutton $f.sc.bu -text "spiral check" \ + -variable stldoctor.spiralcheck \ + -command {Ng_STLDoctor;} + checkbutton $f.sc.bu2 -text "cone check" \ + -variable stldoctor.conecheck \ + -command {Ng_STLDoctor;} + pack $f.sc.bu $f.sc.bu2 + + + tixControl $f.gtol -label "load-geometry tolerance factor" -integer false \ + -variable stldoctor.geom_tol_fact \ + -options { + entry.width 8 + label.width 30 + label.anchor e + } + pack $f.gtol + + button $f.adap -text "Apply" -command { + [.stldoctor_dlg.nb subwidget advanced].gtol invoke + Ng_STLDoctor; + } + pack $f.adap -expand yes + +# frame $f.gtol -relief groove -borderwidth 3 +# pack $f.gtol -fill x +# label $f.gtol.lab -text "Geometry-Load-Tolerance-Factor"; +# entry $f.gtol.ent -width 5 -relief sunken \ +# -textvariable stldoctor.geom_tol_fact +# pack $f.gtol.lab $f.gtol.ent -side left -expand yes + + #******************************* + wm withdraw $wd + wm geom $wd +100+100 + wm deiconify $wd + wm title $wd "STL Doctor" + + focus $wd +} +} + + + + + +proc meshdoctordialog { } { + + set w .meshdoc_dlg + global meshdoctor.active + + if {[winfo exists .meshdoc_dlg] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + toplevel $w + + set meshdoctor.active 1 + Ng_MeshDoctor; + + + frame $w.vis -relief groove -borderwidth 3 + pack $w.vis + + checkbutton $w.vis.showfilledtrigs -text "Show filled triangles" \ + -variable viewoptions.drawfilledtrigs \ + -command { Ng_SetVisParameters; redraw } + + checkbutton $w.vis.showedges -text "Show edges" \ + -variable viewoptions.drawedges \ + -command { Ng_SetVisParameters; redraw } + + + checkbutton $w.vis.showoutline -text "Show Triangle Outline" \ + -variable viewoptions.drawoutline \ + -command { Ng_SetVisParameters; redraw } + + pack $w.vis.showfilledtrigs $w.vis.showoutline $w.vis.showedges + + tixControl $w.markedgedist -label "Mark edge dist: " -integer true \ + -min 0 -max 999 \ + -variable meshdoc.markedgedist \ + -options { + entry.width 3 + label.width 20 + label.anchor e + } \ + -command { + Ng_MeshDoctor markedgedist ${meshdoc.markedgedist} + redraw + } + pack $w.markedgedist + + button $w.deledge -text "Delete marked segments" -command { + Ng_MeshDoctor deletemarkedsegments + redraw + } + pack $w.deledge + + button $w.close -text "Close" -command { + set meshdoctor.active 0; + Ng_MeshDoctor; + destroy .meshdoc_dlg + } + pack $w.close -expand yes + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Mesh Doctor" + } +} + + + +# +# Quality viewer +# + +proc qualityviewdialog { show } { + + set w .qualityview_dlg + + if {[winfo exists .qualityview_dlg] == 1} { + + if { $show == 1 } { + wm withdraw .qualityview_dlg + wm deiconify $w + focus $w + } { + wm withdraw $w + } + } { + toplevel $w + + set c $w.c + + canvas $c -relief raised -width 450 -height 300 + pack $w.c -side top -fill x + + set plotFont {Helvetica 12} + set smallFont {Helvetica 12} + + $c create line 100 250 400 250 -width 2 + $c create line 100 250 100 50 -width 2 + + for {set i 0} {$i <= 10} {incr i} { + set x [expr {100 + ($i*30)}] + $c create line $x 250 $x 245 -width 2 + if { [expr {$i % 2}] == 0 } { + $c create text $x 254 -text [format %1.1f [expr 0.1*$i]] -anchor n -font $plotFont + } + } + + global qualbar + global qualbarnull + global qualbaraxis + + for {set i 0} {$i <= 5} {incr i} { + set y [expr {250 - ($i*40)}] + $c create line 100 $y 105 $y -width 2 + +# global qualbaraxis($i) + set qualbaraxis($i) \ + [$c create text 96 $y -text [expr $i*50].0 -anchor e -font $plotFont] + } + + for {set i 0} {$i < 20} {incr i} { + set x1 [expr {100 + ($i*15) + 2}] + set x2 [expr {$x1+10}] + set y [expr {250 - 10 * $i}] +# global qualbar($i) + set qualbar($i) [$c create rectangle $x1 250 $x2 245 -fill blue] + set qualbarnull($i) [$c create text [expr {($x1+$x2)/2}] 245 -text 0 -anchor s -font $smallFont -fill blue] + } + + frame $w.bu + pack $w.bu + # -fill x + + button $w.close -text "Close" \ + -command { + wm withdraw .qualityview_dlg + set viewqualityplot 0 + } + pack $w.close + + + if { $show == 1 } { + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Mesh Quality" + focus $w + } + } +} + + + + + + + + + + +# +# Quality viewer +# +proc memusedialog { show } { + + set w .memuse_dlg + + if {[winfo exists .memuse_dlg] == 1} { + + if { $show == 1 } { + wm withdraw .memuse_dlg + wm deiconify $w + focus $w + } { + wm withdraw $w + } + } { + toplevel $w + + set c $w.c + + canvas $c -relief raised -width 600 -height 300 + pack $w.c -side top -fill x + + set plotFont {Helvetica 18} + set smallFont {Helvetica 12} + + + global memmark + for {set i 0} {$i < 512} { incr i } { + set memmark($i) [$c create line [expr 50+$i] 50 [expr 50+$i] 70 -fill blue] + } + + + set plotFont {Helvetica 18} + set smallFont {Helvetica 12} + + $c create text 50 90 -text "0 GB" -anchor n -font $plotFont + $c create text 178 90 -text "1 GB" -anchor n -font $plotFont + $c create text 306 90 -text "2 GB" -anchor n -font $plotFont + $c create text 434 90 -text "3 GB" -anchor n -font $plotFont + $c create text 562 90 -text "4 GB" -anchor n -font $plotFont + + + frame $w.bu + pack $w.bu + # -fill x + + button $w.close -text "Close" \ + -command { + wm withdraw .memuse_dlg + set memuseplot 0 + } + pack $w.close + + if { $show == 1 } { + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Memory Usage" + focus $w + } + } +} + + + + + + + + + + + + + + + +# +# STL INFO dialog +# +proc STLinfodialog { show } { + + set w .STLinfo_dlg + + if {[winfo exists .STLinfo_dlg] == 1} { + + if { $show == 1 } { + wm withdraw .STLinfo_dlg + wm deiconify $w + focus $w + } { + wm withdraw $w + } + } { + toplevel $w + + set c $w.c + + canvas $c -relief raised -width 450 -height 300 + pack $w.c -side top -fill x + + set plotFont {Helvetica 18} + set smallFont {Helvetica 12} + + $c create line 100 250 400 250 -width 2 + $c create line 100 250 100 50 -width 2 + + frame $w.bu + pack $w.bu + # -fill x + + button $w.close -text "Close" \ + -command { + wm withdraw .STLinfo_dlg + #set STLinfoopen 0 + } + pack $w.close + + + if { $show == 1 } { + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "STL Geometry Info" + focus $w + } + } +} + + + + + + + + +proc logwindow { } { + set w .logwindow + + if {[winfo exists .logwindow] == 1} { + wm withdraw $w + wm deiconify $w + focus $w + } { + toplevel $w + + text $w.edit -yscroll "$w.scrolly set" -setgrid 1 -height 12 + scrollbar $w.scrolly -command "$w.edit yview" + pack $w.edit -side left -fill both -expand 1 + pack $w.scrolly -side left -fill both -expand 0 + + .logwindow.edit insert end "Netgen Log Window\n" + + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Netgen Log" + focus $w + } +} +# logwindow + + + +# Opens a window with a table. tablevar is a list, the first entry is the title, the second the number of rows, the third the number of columns, +# then the entries follow. + +proc printtable { tablevar } { + set w newtcltable + while {[winfo exists .$w] == 1} {set w 1$w} + set w .$w + toplevel $w + for {set i 0} {$i < [lindex $tablevar 2]} { incr i } { + frame $w.col$i + for {set j 0} {$j < [lindex $tablevar 1]} { incr j } { + frame $w.col$i.row$j + message $w.col$i.row$j.txt -aspect 10000000 -text [lindex $tablevar [expr 3+[lindex $tablevar 2]*$j+$i]] + pack $w.col$i.row$j.txt + pack $w.col$i.row$j -side top + } + pack $w.col$i -side left + } + wm withdraw $w + wm geom $w +200+100; wm deiconify $w + wm title $w [lindex $tablevar 0] + focus $w +} + + +set latestwarning 0 + + +proc printwarning { textvar } { + global latestwarning + set latestwarning $textvar + set w warning + while {[winfo exists .$w] == 1} {set w 1$w} + set w .$w + toplevel $w + message $w.mes -aspect 2000 -text "WARNING:\n$textvar" + button $w.done -text "Done" -command "destroy $w" + pack $w.mes + pack $w.done + wm withdraw $w + wm deiconify $w + wm title $w "Warning" + focus $w +} + + +proc printlatestwarning { } { + global latestwarning + if {$latestwarning != 0} {printwarning $latestwarning} +} + + + +proc runtestdialog { } { + source $::ngdir/ngshell.tcl + set w .runtest_dlg + + if {[winfo exists .runtest_dlg] == 1} { + wm withdraw $w + wm deiconify $w + + focus $w + } { + toplevel $w + +# in2d testing # + frame $w.in2dframe + pack $w.in2dframe + + set in2dlogfile "" + tixLabelEntry $w.in2dframe.ent -label "in2d log-file: console if empty" \ + -labelside top \ + -options { + entry.textVariable in2dlogfile + entry.width 35 + label.width 25 + label.anchor w + } + button $w.in2dframe.btn -text "Browse" -command { + set types { { "Log file" {.log} } } + set in2dlogfile [tk_getOpenFile -filetypes $types -initialfile $in2dlogfile] + } + button $w.in2dframe.test -text "Test in2d meshing" -command { ngtest in2d $in2dlogfile } + + + pack $w.in2dframe.test -side left -anchor s -padx 4 -pady 4 + pack $w.in2dframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4 + pack $w.in2dframe.btn -side left -anchor s -padx 4 -pady 4 + + +# geo testing # + frame $w.geoframe + pack $w.geoframe + + set geologfile "" + tixLabelEntry $w.geoframe.ent -label "geo log-file: console if empty" \ + -labelside top \ + -options { + entry.textVariable geologfile + entry.width 35 + label.width 25 + label.anchor w + } + button $w.geoframe.btn -text "Browse" -command { + set types { { "Log file" {.log} } } + set geologfile [tk_getOpenFile -filetypes $types -initialfile $geologfile] + } + button $w.geoframe.test -text "Test geo meshing" -command { ngtest geo $geologfile } + + + pack $w.geoframe.test -side left -anchor s -padx 4 -pady 4 + pack $w.geoframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4 + pack $w.geoframe.btn -side left -anchor s -padx 4 -pady 4 + +# stl testing # + frame $w.stlframe + pack $w.stlframe + + set stllogfile "" + tixLabelEntry $w.stlframe.ent -label "stl log-file: console if empty" \ + -labelside top \ + -options { + entry.textVariable stllogfile + entry.width 35 + label.width 25 + label.anchor w + } + button $w.stlframe.btn -text "Browse" -command { + set types { { "Log file" {.log} } } + set stllogfile [tk_getOpenFile -filetypes $types -initialfile $stllogfile] + } + button $w.stlframe.test -text "Test stl meshing" -command { ngtest stl $stllogfile } + + + pack $w.stlframe.test -side left -anchor s -padx 4 -pady 4 + pack $w.stlframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4 + pack $w.stlframe.btn -side left -anchor s -padx 4 -pady 4 + +# pde testing # + frame $w.pdeframe + pack $w.pdeframe + + set pdelogfile "" + tixLabelEntry $w.pdeframe.ent -label "pde log-file: console if empty" \ + -labelside top \ + -options { + entry.textVariable pdelogfile + entry.width 35 + label.width 25 + label.anchor w + } + button $w.pdeframe.btn -text "Browse" -command { + set types { { "Log file" {.log} } } + set pdelogfile [tk_getOpenFile -filetypes $types -initialfile $pdelogfile] + } + button $w.pdeframe.test -text "Test ngsolve pde's" -command { ngtest pde $pdelogfile } + + + pack $w.pdeframe.test -side left -anchor s -padx 4 -pady 4 + pack $w.pdeframe.ent -side left -expand yes -fill x -anchor s -padx 4 -pady 4 + pack $w.pdeframe.btn -side left -anchor s -padx 4 -pady 4 + + wm title $w "Testing" + focus .runtest_dlg + } +} + diff --git a/ng/drawing.tcl b/ng/drawing.tcl new file mode 100644 index 00000000..0d27944a --- /dev/null +++ b/ng/drawing.tcl @@ -0,0 +1,113 @@ +# +# Creates a drawing frame, and binds mouse events +# +set oldmousex 0 +set oldmousey 0 +# + + +# if { 1 } { + +# use this one for Togl 2.0 +# if {[catch {togl .ndraw -width 400 -height 300 -rgba true -double true -depth true -privatecmap false -stereo false -indirect true -create init -display draw -reshape reshape }] } { + +if {[catch {togl .ndraw -width 400 -height 300 -rgba true -double true -depth true -privatecmap false -stereo false -indirect true }] } { puts "no OpenGL" +} { + # + pack .ndraw -expand true -fill both -padx 10 -pady 10 + # + bind .ndraw { + set oldmousex %x; set oldmousey %y; + } + bind .ndraw { + set oldmousex %x; set oldmousey %y; + } + bind .ndraw { + set oldmousex %x; set oldmousey %y; + } + bind .ndraw { + Ng_MouseMove $oldmousex $oldmousey %x %y $drawmode + .ndraw render + set oldmousex %x; set oldmousey %y; + } + + bind .ndraw { + Ng_MouseDblClick %x %y + .ndraw render + if { [winfo exists .bcprop_dlg] } { bcpropdialog } + if { [winfo exists .surfacemeshsize_dlg] } { surfacemeshsizedialog } + if { [winfo exists .fieldlines_dlg] } { fieldlinesdialog } + } + + bind .ndraw { + Ng_MouseMove $oldmousex $oldmousey %x %y move + .ndraw render + set oldmousex %x; set oldmousey %y; + } + + bind .ndraw { + Ng_MouseMove $oldmousex $oldmousey %x %y zoom + .ndraw render + set oldmousex %x; set oldmousey %y; + } +} + + +proc popupcheckredraw { vari { x 0 } } { + upvar $vari varname + if { $varname == 1 } { + set varname 0 + } { + # puts "popup-redraw $vari" + Ng_Vis_Set parameters + redraw + } +} +proc popupcheckredraw2 { vari boolvar { x 0 } } { + upvar $vari varname + if { $varname == 1 } { + set varname 0 + } { + Ng_SetVisParameters + Ng_Vis_Set parameters + if { $boolvar == 1 } { redraw } + Ng_SetVisParameters + } +} +proc popupcheckredraw3 { vari { x 0 } } { + upvar $vari varname + if { $varname == 1 } { + set varname 0 + } { + Ng_Vis_Set parameters + } +} + + + + +proc redraw { {x 0} } { + if {[winfo exists .ndraw]} { .ndraw render } +} + + + +bind . { Ng_MouseMove 0 0 -10 0 rotate; redraw } +bind . { Ng_MouseMove 0 0 10 0 rotate; redraw } +bind . { Ng_MouseMove 0 0 0 -10 rotate; redraw } +bind . { Ng_MouseMove 0 0 0 10 rotate; redraw } +bind . { Ng_MouseMove 0 0 -10 0 move; redraw } +bind . { Ng_MouseMove 0 0 10 0 move; redraw } +bind . { Ng_MouseMove 0 0 0 -10 move; redraw } +bind . { Ng_MouseMove 0 0 0 10 move; redraw } +bind . { Ng_MouseMove 0 0 0 -10 zoom; redraw } +bind . { Ng_MouseMove 0 0 0 10 zoom; redraw } + +bind . \ + {event generate [focus -displayof %W] -delta 120} + +bind . \ + {event generate [focus -displayof %W] -delta -120} + +bind . { Ng_MouseMove 0 0 0 [expr {%D/-5}] zoom; redraw } + diff --git a/ng/menustat.tcl b/ng/menustat.tcl new file mode 100644 index 00000000..08d058d4 --- /dev/null +++ b/ng/menustat.tcl @@ -0,0 +1,1123 @@ +# netgen menus: + +menu .ngmenu -tearoff 0 -relief raised -bd 2 +. configure -menu .ngmenu + +.ngmenu add cascade -label "File" -menu .ngmenu.file -underline 0 +.ngmenu add cascade -label "Geometry" -menu .ngmenu.geometry -underline 0 +.ngmenu add cascade -label "Mesh" -menu .ngmenu.mesh -underline 0 +.ngmenu add cascade -label "View" -menu .ngmenu.view -underline 0 +.ngmenu add cascade -label "Refinement" -menu .ngmenu.meshsize -underline 5 + +if { $userlevel == 3} { + .ngmenu add cascade -label "Special" -menu .ngmenu.special -underline 3 +} + +.ngmenu add cascade -label "Help" -menu .ngmenu.help -underline 0 + + +##################################################### +# # +# Menu File # +# # +##################################################### + +menu .ngmenu.file + +.ngmenu.file add command -label "Load Geometry..." -accelerator "" \ + -command { + set types { + {"All Geometry types" { .stl .stlb .step .stp .geo .in2d .igs .iges .brep .sat} } + {"IGES Geometry" {.igs .iges} } + {"BREP OpenCascade Geometry" {.brep} } + {"STL Geometry" {.stl} } + {"Binary STL Geometry" {.stlb} } + {"STEP Geometry" {.step .stp} } + {"Geometry file" {.geo} } + {"2D Geometry" {.in2d } } + } + + set ACISavailable [Ng_ACISCommand isACISavailable] + if {$ACISavailable == "yes" } { + lappend types {"ACIS Geometry" {.sat} } + } + + if {[catch { + set file [tk_getOpenFile -filetypes $types -initialdir $dirname -typevariable loadgeomtypevar] + }]} { + set file [tk_getOpenFile -filetypes $types -initialdir $dirname] + } + + if {$file != ""} { + AddRecentFile $file + Ng_LoadGeometry $file + Ng_ParseGeometry +# if { [Ng_STLInfo status]=="ERROR" } { +# tk_messageBox -message "STL ERROR: \n [Ng_STLInfo statustext]" -type ok +# } + set selectvisual geometry + Ng_SetVisParameters + redraw + wm title . [concat "$progname - " $file] + set dirname [file dirname $file] + set basefilename [file tail [file rootname $file]] + + if { $hasocc == "yes" } { + rebuildoccdialog + } + } + } + + + +.ngmenu.file add command -label "Save Geometry..." \ + -command { + set occgeometryloaded [Ng_OCCCommand isoccgeometryloaded] + puts $occgeometryloaded + if {$occgeometryloaded == 1 } { + set types { + {"IGES Geometry file" {.igs} } + {"STEP Geometry file" {.stp} } + {"STL Geometry file" {.stl} } + {"STL BIN Geometry file" {.stlb} } + } + } { + set types { + {"STL Geometry file" {.stl} } + {"STL BIN Geometry file" {.stlb} } + } + } + + set ACISavailable [Ng_ACISCommand isACISavailable] + puts $ACISavailable + if {$ACISavailable == "yes" } { + lappend types {"ACIS Geometry" {.sat} } + } + + set file [tk_getSaveFile -filetypes $types -initialdir $dirname -initialfile $basefilename ] + if {$file != ""} { + Ng_SaveGeometry $file + } + } + + + +.ngmenu.file add cascade -label "Recent Files" -menu .ngmenu.file.recent +menu .ngmenu.file.recent + + +proc AddRecentFile { filename } { + global progname + global dirname + catch { [.ngmenu.file.recent delete $filename] } + .ngmenu.file.recent insert 0 command -label $filename \ + -command "AddRecentFile {$filename}; + Ng_LoadGeometry {$filename}; + Ng_ParseGeometry; + set selectvisual geometry; + Ng_SetVisParameters; + redraw; + wm title . [concat \" $progname - $filename \"]; + set dirname {[file dirname $filename]}; + set basefilename {[file tail [file rootname $filename]]}; + rebuildoccdialog;" + + + if { [.ngmenu.file.recent index last] >= 6 } { + .ngmenu.file.recent delete last } + + saveinifile; + } +loadinifile; + +.ngmenu.file add separator + + +.ngmenu.file add command -label "Load Mesh..." -accelerator "" \ + -command { + set types { + {"Mesh file" {.vol .vol.gz} } } + set file [tk_getOpenFile -filetypes $types -defaultextension ".vol"] + if {$file != ""} { + AddRecentMeshFile $file; + Ng_LoadMesh $file; + set selectvisual mesh + Ng_SetVisParameters + redraw + Ng_ReadStatus; +# Ng_MeshSizeFromSurfaceMesh + wm title . [concat "$progname - " $file] + set dirname [file dirname $file] + set basefilename [file tail [file rootname $file]] + } + } + + + +# astrid +.ngmenu.file add cascade -label "Recent Meshes" -menu .ngmenu.file.recentmesh +menu .ngmenu.file.recentmesh + + +proc AddRecentMeshFile { filename } { + global progname + global dirname + catch { [.ngmenu.file.recentmesh delete $filename] } + .ngmenu.file.recentmesh insert 0 command -label $filename \ + -command "AddRecentMeshFile {$filename}; + Ng_LoadMesh {$filename}; + set selectvisual mesh; + Ng_SetVisParameters; + redraw; + wm title . [concat \" $progname - $filename \"]; + set dirname {[file dirname $filename]}; + set basefilename {[file tail [file rootname $filename]]}; + rebuildoccdialog;" + + if { [.ngmenu.file.recentmesh index last] >= 6 } { + .ngmenu.file.recentmesh delete last } + + savemeshinifile; + } +loadmeshinifile; + +# astrid ende + + +.ngmenu.file add command -label "Save Mesh..." -accelerator "" \ + -command { + set types { + {"Mesh file" {.vol .vol.gz} } } + + set file [tk_getSaveFile -filetypes $types -defaultextension ".vol.gz" -initialfile $basefilename -initialdir $dirname ] + if {$file != ""} { + Ng_SaveMesh $file } + AddRecentMeshFile $file; + + } + +.ngmenu.file add command -label "Merge Mesh..." \ + -command { + set types { + {"Mesh file" {.vol} } } + set file [tk_getOpenFile -filetypes $types -defaultextension ".vol"] + if {$file != ""} { + Ng_MergeMesh $file; + set selectvisual mesh + Ng_SetVisParameters + redraw + Ng_ReadStatus; + } + } + + + + + +.ngmenu.file add command -label "Import Mesh..." \ + -command { + set types { + {"Neutral format" {.mesh .emt} } + {"Surface mesh format" {.surf} } + {"Universal format" {.unv} } + {"Olaf format" {.emt} } + {"TET format" {.tet} } + {"Pro/ENGINEER neutral format" {.fnf} } + } + set file [tk_getOpenFile -filetypes $types ] + if {$file != ""} { + Ng_ImportMesh $file + set selectvisual mesh + Ng_SetVisParameters + redraw + Ng_ReadStatus; + } + } + + +.ngmenu.file add command -label "Export Mesh..." \ + -command { + +# global meshexportformats + foreach exportformat $meshexportformats { + if { [lindex $exportformat 0] == $exportfiletype } { + set extension [lindex $exportformat 1] + } + } + + if { $exportfiletype == "Elmer Format"} { + set file [file nativename [tk_chooseDirectory -title "Elmer Mesh Export - Select Directory"]] + } elseif { $exportfiletype == "OpenFOAM 1.5+ Format"} { + set file [file nativename [tk_chooseDirectory -title "OpenFOAM 1.5+ Mesh Export - Select Case Directory"]] + } elseif { $exportfiletype == "OpenFOAM 1.5+ Compressed"} { + set file [file nativename [tk_chooseDirectory -title "OpenFOAM 1.5+ Mesh Export - Select Case Directory"]] + } else { +# set file [tk_getSaveFile -filetypes "{ \"$exportfiletype\" {$extension} }" ] + set file [tk_getSaveFile -filetypes "{ \"$exportfiletype\" {*}}" ] + } + + if {$file != ""} { + Ng_ExportMesh $file $exportfiletype + } + } + +.ngmenu.file add cascade -label "Export Filetype" -menu .ngmenu.file.filetype + +menu .ngmenu.file.filetype + + +.ngmenu.file add separator + + +.ngmenu.file add command -label "Save Solution..." \ + -command { + set types { + {"Solution File" {.sol} } + {"VTK File" {.vtk} } + } + set file [tk_getSaveFile -filetypes $types ] + if {$file != ""} { + Ng_SaveSolution $file + } + } +#-defaultextension ".sol" ] + +.ngmenu.file add command -label "Import Solution..." \ + -command { + set types { {"Solution File" {.sol} } } + set file [tk_getOpenFile -filetypes $types -defaultextension ".sol" ] + if {$file != ""} { + Ng_ImportSolution $file + set selectvisual solution + Ng_SetVisParameters + redraw + } + } + + + + + + +set demostarttime [clock clicks -millisecond] +set stopdemo 0 +proc demoredraw { } { + global demostarttime + global stopdemo + set curtime [clock clicks -millisecond] + set result [ Ng_DemoSetTime [expr $curtime - $demostarttime] ] + redraw + global videoactive + if { $videoactive == 1 } { + puts "addframe" + .ndraw Ng_VideoClip addframe + } + if { $result == 0 && $stopdemo == 0 } { + after 1 { demoredraw } + } +} +.ngmenu.file add command -label "Show Demo..." \ + -command { + set types { {"Demo File" {.dem} } } + set file [tk_getOpenFile -filetypes $types -defaultextension ".dem" ] + if {$file != ""} { + Ng_ShowDemo $file + set demostarttime [clock clicks -millisecond] + set stopdemo 0 + demoredraw + } + } + + + + +.ngmenu.file add separator + +.ngmenu.file add command -label "Snapshot..." \ + -command { + set types { + {"JPG file" {.jpg} } + {"GIF file" {.gif} } + {"PPM file" {.ppm} } + } + set file [tk_getSaveFile -filetypes $types] +# -defaultextension ".ppm"] + if {$file != ""} { + .ndraw Ng_SnapShot $file } + } + + +.ngmenu.file add cascade -label "Video clip" -menu .ngmenu.file.video +menu .ngmenu.file.video + +set videoactive 0 +.ngmenu.file.video add command -label "start..." \ + -command { + set types { + {"MPG file" {.mpg} } + } + set file [tk_getSaveFile -filetypes $types] + if {$file != ""} { + .ndraw Ng_VideoClip init $file + global videoactive + set videoactive 1 + } + } + +.ngmenu.file.video add command -label "add frame..." \ + -command {.ndraw Ng_VideoClip addframe } + +.ngmenu.file.video add command -label "one cycle" \ + -command { + set visoptions.redrawperiodic 1 + for { set j 0 } { $j < 100 } { incr j } { + puts "j = $j" + Ng_Vis_Set time [expr (1000 * $j / 100)] + redraw + .ndraw Ng_VideoClip addframe + after 200 + } + } + +.ngmenu.file.video add command -label "finalize..." \ + -command { + .ndraw Ng_VideoClip finalize + global videoactive + set videoactive 0 + } + + + +.ngmenu.file add command -label "Save Options" \ + -command { saveoptions } + + + + +.ngmenu.file add separator + + +## herbert tcl load menue +# .ngmenu.file add command -label "Run tests ..." \ +\# -command { runtestdialog } +## +# .ngmenu.file add separator + +.ngmenu.file add command -label "Quit" -accelerator "" \ + -command { + puts "Thank you for using $progname"; + + if { [catch { unload libngsolve[info sharedlibextension] ngsolve } result ] } { +# puts "cannot unload ngsolve" +# puts "error: $result" + } + + Ng_Exit; + destroy . + } +# exit + + +##################################################### +# # +# Menu Mesh # +# # +##################################################### + +menu .ngmenu.mesh +.ngmenu.mesh add command -label "Generate Mesh" -accelerator "" \ + -command { + set selectvisual mesh + Ng_SetVisParameters + Ng_GenerateMesh ${meshoptions.firststep} ${meshoptions.laststep} + Ng_ReadStatus + redraw + } + +.ngmenu.mesh add command -label "Stop Meshing" \ + -command { Ng_StopMeshing } + +.ngmenu.mesh add command -label "Meshing Options..." \ + -command meshingoptionsdialog + + +.ngmenu.mesh add separator + +.ngmenu.mesh add command -label "Delete Mesh" \ + -command { Ng_New mesh; Ng_ReadStatus; redraw } + +.ngmenu.mesh add command -label "Delete Vol Mesh" \ + -command { Ng_DeleteVolMesh; Ng_ReadStatus; redraw } + + +.ngmenu.mesh add command -label "Mesh Info" \ + -command { + set dim [Ng_MeshInfo dim] + set np [Ng_MeshInfo np] + set ne [Ng_MeshInfo ne] + set nse [Ng_MeshInfo nse] + set nseg [Ng_MeshInfo nseg] + set bbox [Ng_MeshInfo bbox] + tk_messageBox -message "Dimension: $dim\nPoints: $np\nElements: $ne\nSurface Els: $nse\nSegments: $nseg\nxmin [lindex $bbox 0] xmax [lindex $bbox 1]\nymin [lindex $bbox 2] ymax [lindex $bbox 3]\nzmin [lindex $bbox 4] zmax [lindex $bbox 5]" + } + + +.ngmenu.mesh add command -label "Mesh Quality" \ + -command { + set inplanemin 0 + set inplanemax 0 + set betplanemin 0 + set betplanemax 0 + Ng_MeshQuality inplanemin inplanemax betplanemin betplanemax + puts "Triangle angles : $inplanemin - $inplanemax" + puts "Tet angles : $betplanemin - $betplanemax" + tk_messageBox -message "Triangle angles : $inplanemin - $inplanemax \n Tet angles : $betplanemin - $betplanemax" + } + +# .ngmenu.mesh add command -label "Quality Plot" \ +# -command { qualityviewdialog 1 } + + + + +.ngmenu.mesh add command -label "Check Surface Mesh" \ + -command { Ng_CheckSurfaceMesh } +.ngmenu.mesh add command -label "Check Volume Mesh" \ + -command { Ng_CheckVolumeMesh } + +.ngmenu.mesh add command -label "Edit Boundary Conditions..." \ + -command { bcpropdialog } + +if { $userlevel == 3 } { + .ngmenu.mesh add command -label "Mesh Doctor..." \ + -command { meshdoctordialog } +} + +.ngmenu.mesh add command -label "METIS Mesh Partitioning..." \ + -command { METISdialog } + +.ngmenu.mesh add separator + +.ngmenu.mesh add command -label "Analyze Geometry" \ + -command { Ng_GenerateMesh ag ag; Ng_ReadStatus; redraw } +.ngmenu.mesh add command -label "Mesh Edges" \ + -command { Ng_GenerateMesh me me; Ng_ReadStatus; redraw } +.ngmenu.mesh add command -label "Mesh Surface" \ + -command { set selectvisual mesh; Ng_SetVisParameters; \ + Ng_GenerateMesh ms ms; Ng_ReadStatus; redraw } + +.ngmenu.mesh add command -label "Optimize Surface" \ + -command { Ng_GenerateMesh os os cmsmSm; redraw } + +.ngmenu.mesh add cascade -label "Surface Optim. Step" -menu .ngmenu.mesh.surfoptstep + +menu .ngmenu.mesh.surfoptstep +.ngmenu.mesh.surfoptstep add command -label "Mesh Smoothing" \ + -command { Ng_GenerateMesh os os m; redraw} +.ngmenu.mesh.surfoptstep add command -label "Edge swapping (topologic)" \ + -command { Ng_GenerateMesh os os s; redraw} +.ngmenu.mesh.surfoptstep add command -label "Edge swapping (metric)" \ + -command { Ng_GenerateMesh os os S; redraw} +.ngmenu.mesh.surfoptstep add command -label "Combine points" \ + -command { Ng_GenerateMesh os os c; redraw} + + +.ngmenu.mesh add separator +.ngmenu.mesh add command -label "Mesh Volume" \ + -command { Ng_GenerateMesh mv mv; Ng_ReadStatus } +.ngmenu.mesh add command -label "Optimize Volume" \ + -command { Ng_GenerateMesh ov ov; Ng_ReadStatus } +.ngmenu.mesh add command -label "Smooth Opt Volume" \ + -command { Ng_GenerateMesh ov ov m; Ng_ReadStatus } +.ngmenu.mesh add command -label "Smooth Opt Volume Jacobian" \ + -command { Ng_GenerateMesh ov ov j; Ng_ReadStatus } + + + +##################################################### +# # +# Menu Geometry # +# # +##################################################### + +menu .ngmenu.geometry + + + + + + + +##################################################### +# # +# Menu View # +# # +##################################################### + +menu .ngmenu.view +.ngmenu.view add command -label "Zoom all" \ + -command { Ng_ZoomAll; redraw } +.ngmenu.view add command -label "Center" \ + -command { Ng_Center; redraw } + +.ngmenu.view add command -label "x-y plane" \ + -command { Ng_StandardRotation xy; redraw } +.ngmenu.view add command -label "y-x plane" \ + -command { Ng_StandardRotation yx; redraw } +.ngmenu.view add command -label "x-z plane" \ + -command { Ng_StandardRotation xz; redraw } +.ngmenu.view add command -label "z-x plane" \ + -command { Ng_StandardRotation zx; redraw } +.ngmenu.view add command -label "y-z plane" \ + -command { Ng_StandardRotation yz; redraw } +.ngmenu.view add command -label "z-y plane" \ + -command { Ng_StandardRotation zy; redraw } + +.ngmenu.view add command -label "Viewing Options..." \ + -command { viewingoptionsdialog; redraw } +.ngmenu.view add command -label "Clipping Plane..." \ + -command { clippingdialog; redraw } +.ngmenu.view add command -label "Solution Data..." \ + -command { visual_dialog; redraw } +.ngmenu.view add checkbutton -variable viewqualityplot \ + -label "Quality Plot" \ + -command { qualityviewdialog $viewqualityplot } +.ngmenu.view add checkbutton -variable memuseplot \ + -label "Memory Usage" \ + -command { memusedialog $memuseplot } + + + + +##################################################### +# # +# Menu Refinement # +# # +##################################################### +# +# Mesh size menu +# +menu .ngmenu.meshsize +.ngmenu.meshsize add command -label "Refine uniform" \ + -command { Ng_Refine; Ng_HighOrder ${options.elementorder}; Ng_ReadStatus; redraw } + +.ngmenu.meshsize add command -label "Second Order" \ + -command { Ng_SecondOrder; Ng_ReadStatus; redraw } + +.ngmenu.meshsize add command -label "Validate Second Order" \ + -command { Ng_ValidateSecondOrder; Ng_ReadStatus; redraw } + +.ngmenu.meshsize add command -label "High Order" \ + -command { Ng_HighOrder ${options.elementorder}; Ng_ReadStatus; redraw } + +.ngmenu.meshsize add separator + +.ngmenu.meshsize add command -label "Refinement Dialog..." \ + -command { refinementdialog } +.ngmenu.meshsize add command -label "Load Meshsize..." \ + -command { + set types { + {"Meshsize file" {.msz} } } + set file [tk_getOpenFile -filetypes $types] + if {$file != ""} { + Ng_LoadMeshSize $file; + } + } +.ngmenu.meshsize add command -label "MS from Surf Mesh" \ + -command { Ng_MeshSizeFromSurfaceMesh } + + +if { $userlevel == 3 } { +.ngmenu.meshsize add command -label "Singular point ms" \ + -command { Ng_SingularPointMS; } + +.ngmenu.meshsize add command -label "Singular edge ms" \ + -command { Ng_SingularEdgeMS; } + +.ngmenu.meshsize add separator + +set bisectfilename ""; + +.ngmenu.meshsize add command -label "Bisection" \ + -command { Ng_ReadStatus; set oldnp 0; set newnp $status_np; +# Ng_BisectCopyMesh; +# Ng_Split2Tets; + Ng_ReadStatus; + + while { $oldnp < $newnp } { +# if { $level == 0 } { +# Ng_ExportMesh feppmesh.vol fepp; +# } { +# Ng_ExportMesh feppmesh$level feppml +# } + set level [expr $level+1] + if { $bisectfilename == ""} { + Ng_Bisect; + } else { + Ng_Bisect $bisectfilename; + } +# Ng_HighOrder ${options.elementorder} "noparallel" +# Ng_Split2Tets; + Ng_ReadStatus; + redraw; + + if { $bisectfilename == ""} { + set oldnp $newnp; + set newnp $status_np; + puts "oldnp $oldnp newnp $newnp"; + } else { + set oldnp $newnp; + } + } + } +# -command { Ng_Bisect; Ng_ReadStatus; redraw } +# -command { exec netgen abc >outfile 2>errfile; Ng_ReadStatus; redraw } + +} + +.ngmenu.meshsize add command -label "Load Refinement Info..." \ + -command { + set types { + {"Refinement info" {.refine} }} + set bisectfilename [tk_getOpenFile -filetypes $types] + } + +.ngmenu.meshsize add command -label "Z-Refinement" \ + -command { Ng_ZRefinement 2; Ng_ReadStatus; redraw } + + +# .ngmenu.meshsize add command -label "hp-Refinement" \ +\# -command { Ng_HPRefinement 4; Ng_ReadStatus; redraw } + +.ngmenu.meshsize add cascade -label "hp-Refinement" -menu .ngmenu.meshsize.hpref +menu .ngmenu.meshsize.hpref +.ngmenu.meshsize.hpref add command -label "1 Level" \ + -command { Ng_HPRefinement 1; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "2 Levels" \ + -command { Ng_HPRefinement 2; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "3 Levels" \ + -command { Ng_HPRefinement 3; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "4 Levels" \ + -command { Ng_HPRefinement 4; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "5 Levels" \ + -command { Ng_HPRefinement 5; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "6 Levels" \ + -command { Ng_HPRefinement 6; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "7 Levels" \ + -command { Ng_HPRefinement 7; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "8 Levels" \ + -command { Ng_HPRefinement 8; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "9 Levels" \ + -command { Ng_HPRefinement 9; Ng_ReadStatus; redraw } +.ngmenu.meshsize.hpref add command -label "10 Levels" \ + -command { Ng_HPRefinement 10; Ng_ReadStatus; redraw } + + +.ngmenu.meshsize add command -label "Split to Tets" \ + -command { Ng_Split2Tets; Ng_ReadStatus; redraw } + + + + + +##################################################### +# # +# Menu Special # +# # +##################################################### + +menu .ngmenu.special +.ngmenu.special add command -label "Prismatic Boundary Layer" \ + -command { Ng_GenerateBoundaryLayer; redraw } +.ngmenu.special add command -label "Insert virtual boundary layer" \ + -command { Ng_InsertVirtualBL; redraw } +.ngmenu.special add command -label "Cut off and combine with other" \ + -command { + set types { {"Mesh file" {.vol} } } + set file [tk_getOpenFile -filetypes $types] + if {$file != ""} { + Ng_CutOffAndCombine $file; } + redraw + } +.ngmenu.special add command -label "Helmholtz Mesh grading" \ + -command { Ng_HelmholtzMesh; } +.ngmenu.special add cascade -label "Colour-based boundary conditions" -menu .ngmenu.special.colbndcond + +menu .ngmenu.special.colbndcond + .ngmenu.special.colbndcond add command -label "Inspect Colours in mesh" \ + -command { currmeshcoloursdialog } + + .ngmenu.special.colbndcond add separator + + .ngmenu.special.colbndcond add command -label "Automatic Assignment" \ + -command { Ng_AutoColourBcProps auto; redraw } + + .ngmenu.special.colbndcond add separator + + set ocffile [file join ${ngdir} netgen.ocf]; + + .ngmenu.special.colbndcond add command -label "Select Colour Profile file" \ + -command { + set types { {"Colour Profile file" {.ocf} } } + set ocffile [tk_getOpenFile -filetypes $types] + if {$ocffile == ""} { + set ocffile [file join ${ngdir} netgen.ocf]; } + } + .ngmenu.special.colbndcond add command -label "Profile based Assignment" \ + -command { Ng_AutoColourBcProps profile ${ocffile}; redraw } + + +# menu .mbar.stl.menu +# .mbar.stl.menu add command -label "STL options" \ +# -command { stloptionsdialog; } +#.mbar.stl.menu add command -label "STL Doctor" \ +# -command { stldoctordialog; } + + +##################################################### +# # +# Menu Help # +# # +##################################################### + + + + +menu .ngmenu.help +# .ngmenu.help add command -label "Ng Help..." \ +\# -command { help_main } +# .ngmenu.view add checkbutton -variable showsensitivehelp \ +# -label "Sensitve Help" \ +# -command { sensitivehelpdialog $showsensitivehelp } +.ngmenu.view add checkbutton -label "Help Line" -variable showhelpline \ + -command { + if { $showhelpline == 1} { + pack .helpline -before .statbar -side bottom -fill x -padx 3p + } { + pack forget .helpline + } +} + +.ngmenu.help add command -label "About..." \ + -command { +tk_messageBox -message "This is NETGEN \nmainly written by \nJoachim Schoeberl \nthanks to \nRobert Gaisbauer, Johannes Gerstmayr, Philippose Rajan" +} + +# tk_menuBar .mbar .mbar.file .mbar.mesh .mbar.test .mbar.help +# focus .mbar + + + + +##################################################### +# # +# Button bar # +# # +##################################################### + +frame .bubar -relief raised -bd 2 +pack .bubar -side top -fill x + +button .bubar.testb -text "Test" -command { Ng_SaveGeometry } +button .bubar.surfm -text "Generate Mesh" -command \ + { + .ngmenu.mesh invoke "Generate Mesh"; +# set selectvisual mesh; +# Ng_SetVisParameters; +# Ng_GenerateMesh ${meshoptions.firststep} ${meshoptions.laststep} +# redraw + } +button .bubar.stopm -text "Stop" -command \ + { + # Ng_StopMeshing; + set multithread_terminate 1; + set stopdemo 1; + } +button .bubar.exitb -text "Quit" \ + -command { + set ans [tk_messageBox -title "Quit Netgen?" -message "Do you really want to quit Netgen?" -type yesno -default "no" -icon question] + if { $ans == "yes" } { + .ngmenu.file invoke "Quit"; + } + } +pack .bubar.exitb .bubar.surfm .bubar.stopm -side left + +#button .bubar.scan -text "Scan" \ +# -command { Ng_ParseGeometry; set selectvisual geometry; Ng_SetVisParameters; redraw } + +button .bubar.zoomall -text "Zoom All" \ + -command { Ng_ZoomAll; redraw } + +button .bubar.center -text "Center" \ + -command { Ng_Center; redraw } + +# tk_optionMenu .bubar.modesel drawmode "rotate" "move " "zoom " +tixOptionMenu .bubar.modesel \ + -options { + label.width 0 + label.anchor e + menubutton.width 6 + } \ + -variable drawmode + +.bubar.modesel add command rotate -label Rotate +.bubar.modesel add command move -label Move +.bubar.modesel add command zoom -label Zoom + + + +set viewvals { geometry specpoints mesh solution} +if { $userlevel == 3} { + set viewvals { geometry mesh specpoints surfmeshing modelview solution} +} + +set viewvallabs(cross) "Cross" +set viewvallabs(geometry) "Geometry" +set viewvallabs(mesh) "Mesh" +set viewvallabs(specpoints) "Edges" +set viewvallabs(surfmeshing) "Mesh Gen" +set viewvallabs(modelview) "Modeller" +set viewvallabs(solution) "Solution" + +tixOptionMenu .bubar.selview \ + -options { + label.width 0 + label.anchor e + menubutton.width 10 + } \ + +foreach viewv $viewvals { + .bubar.selview add command $viewv -label $viewvallabs($viewv) +} + + + +.bubar.selview config -variable selectvisual +.bubar.selview config -command { Ng_SetVisParameters; redraw } + + +pack .bubar.modesel -side right +pack forget .bubar.modesel +pack .bubar.center .bubar.zoomall .bubar.selview -side right + +.ngmenu.view add checkbutton -variable viewrotatebutton \ + -label "Enable LeftButton Selection" \ + -command { + if { $viewrotatebutton } { + pack .bubar.modesel -side right + } { + pack forget .bubar.modesel + } + } + + + + +##################################################### +# # +# Status bar # +# # +##################################################### + +label .helpline -text "None" +pack forget .helpline -side bottom -fill x + +frame .statbar -relief flat -bd 2 +pack .statbar -side bottom -fill x + +label .statbar.ptslabel -text "Points: " +label .statbar.ptsval -textvariable status_np +label .statbar.elslabel -text " Elements: " +label .statbar.elsval -textvariable status_ne +label .statbar.selslabel -text " Surf Elements: " +label .statbar.selsval -textvariable status_nse +# label .statbar.memlabel -text " Mem: " +# label .statbar.memval -textvariable mem_moveable +label .statbar.task -textvariable status_task + +pack .statbar.ptslabel .statbar.ptsval -side left -ipady 3p +pack .statbar.elslabel .statbar.elsval -side left -ipady 3p +pack .statbar.selslabel .statbar.selsval -side left -ipady 3p + +# if { $userlevel == 3 } { +# pack .statbar.memlabel .statbar.memval -side left -ipady 3p +# } + + +tixMeter .statbar.per -value 0 -text 0% +.statbar.per configure -fillcolor blue + +pack .statbar.per -side right +pack .statbar.task -side right -ipady 4 + +set qualbaraxis(0) 0 +set qualbar(0) 0 +set qualbarnull(0) 0 + + + +proc timer2 { } { + global status_np + global status_ne + global status_nse + global multithread_running + global multithread_redraw + global status_working + global status_task + global status_percent + global status_tetqualclasses + + + Ng_ReadStatus + + if { $multithread_redraw == 1 } { + set multithread_redraw 0; + redraw; + + global videoactive + if { $videoactive == 1 } { + puts "addframe" + .ndraw Ng_VideoClip addframe + } + } + + # global mem_moveable + # set mem_moveable [Ng_MemInfo moveable] + + + .statbar.per config -value [expr $status_percent/100] -text [format %2.1f [expr 0.1*int(10*$status_percent)]]% + + + if { $multithread_running } { + pack .statbar.per -side right -before .statbar.task -padx 6 + } { + pack forget .statbar.per + } + + + + # tet quality + if {[winfo exists .qualityview_dlg] == 1} { + + global qualbar + global qualbarnull + global qualbaraxis + + set maxval 0 + for {set i 0} {$i < 20} {incr i} { + if {[lindex $status_tetqualclasses $i] > $maxval} { + set maxval [lindex $status_tetqualclasses $i] + } + } + + set ubound 1 + while { $ubound < $maxval } { + set ubound [expr {10 * $ubound}] + } + if { $ubound/5 > $maxval } { + set ubound [expr $ubound/5] + } + if { $ubound/2 > $maxval } { + set ubound [expr $ubound/2] + } + + + + for {set i 1} {$i <= 5} {incr i} { + # global qualbaraxis($i) + + set value [expr { $i * $ubound / 5 }] + .qualityview_dlg.c dchars $qualbaraxis($i) 0 end + .qualityview_dlg.c insert $qualbaraxis($i) end $value + } + + + for {set i 0} {$i < 20} {incr i} { + set x1 [expr {100 + ($i*15) + 2}] + set x2 [expr {$x1+10}] + + set nbrs [lindex $status_tetqualclasses $i] + set y [expr (249 - (200 * $nbrs / $ubound ) )] + + # global qualbar($i) + .qualityview_dlg.c coords $qualbar($i) $x1 250 $x2 $y + +# global qualbarnull($i) + if { $nbrs == 0 } { + .qualityview_dlg.c itemconfigure $qualbarnull($i) -text 0 + } { + .qualityview_dlg.c itemconfigure $qualbarnull($i) -text "" + } + } + + } + + + if {[winfo exists .memuse_dlg] == 1} { + + global memmark + set usemb [Ng_MemInfo usedmb] + for {set i 0} {$i < [string length $usemb] } {incr i} { + if { [string index $usemb $i] == 0 } { + .memuse_dlg.c coords $memmark($i) [expr 50+$i] 68 [expr 50+$i] 70 + } { + .memuse_dlg.c coords $memmark($i) [expr 50+$i] 50 [expr 50+$i] 70 + } + } + + } + after 30 { timer2 } +} +# after 1000 { timer2 } +timer2 + + + + +proc bgerror { error } { + global errorInfo userlevel + if { $userlevel == 3} { + puts "ERROR: $error" + puts "errinfo: $errorInfo" + } + tk_messageBox -title "Error Message" -message $error -type ok +} + + + + + + +proc smh2 { menuitem } { + if {[catch {$menuitem entrycget active -label} name]} { + set name " " + } + show_menu_help $name + update idletasks +} + +bind .ngmenu <> { smh2 %W } +bind .ngmenu.file <> { smh2 %W } +bind .ngmenu.geometry <> { smh2 %W } +bind .ngmenu.mesh <> { smh2 %W } +bind .ngmenu.view <> { smh2 %W } +bind .ngmenu.meshsize <> { smh2 %W } +bind .ngmenu.special <> { smh2 %W } +bind .ngmenu.help <> { smh2 %W } + + +# command bindings +bind . { .ngmenu.file invoke "Quit" } +bind . { .ngmenu.file invoke "Load Geometry..." } ; +bind . { .ngmenu.file invoke "Load Mesh..." } ; +bind . { .ngmenu.file invoke "Save Mesh..." } ; +bind . { .ngmenu.file activate "Recent Files" } ; +bind .

{ newprimitivedialog } ; # +bind .

{ editprimitivedialog } +bind . { newsoliddialog } +bind . { .ngmenu.mesh invoke "Generate Mesh" } ; + + + + + diff --git a/ng/netgen.ocf b/ng/netgen.ocf new file mode 100644 index 00000000..06d7a5c5 --- /dev/null +++ b/ng/netgen.ocf @@ -0,0 +1,32 @@ +# Netgen Mesher +# Boundary Condition Colour Profile +# +# Name: netgen.ocf +# +# Description: Netgen default colour +# profile file for colour based automatic +# assignment of boundary condition numbers +# +# Format: +# [boundary_colours] (mandatory keyword) +# +# +# +# .... +# .... +# NOTE: +# * Currently, the default Boundary +# Condition number assigned to faces without +# any colour defined is "1" +# * Boundary Condition number "0" is invalid, +# and should not be used + +boundary_colours +7 +2 0.0000 0.0000 0.0000 +3 1.0000 0.0000 0.0000 +4 0.0000 0.0000 1.0000 +5 1.0000 1.0000 0.0000 +6 0.0000 1.0000 1.0000 +7 1.0000 0.0000 1.0000 +8 1.0000 1.0000 1.0000 diff --git a/ng/ng.tcl b/ng/ng.tcl new file mode 100644 index 00000000..bb440808 --- /dev/null +++ b/ng/ng.tcl @@ -0,0 +1,286 @@ +if {[catch {package require Tix } result ]} { + puts "cannot load package Tix" + puts "error : $result" +} + +# if {[catch {package require Togl 2.0 } result ]} { +# puts "cannot load package Togl 2.0" +# puts "error : $result" +# } + + + +# userlevel 1..standard user 2..power-user 3..developer + +set userlevel 3 +if { [Ng_GetCommandLineParameter expert]=="defined" } { + set userlevel 3 +} + +set progname "NETGEN" + +set ngdir "" +if { [lsearch [array names env] NETGENDIR] != -1 } { + set ngdir $env(NETGENDIR) +} +if { [string length $ngdir] == 0 } { + set ngdir "." +} + +set nguserdir "" +if { [lsearch [array names env] NETGEN_USER_DIR] != -1 } { + set nguserdir $env(NETGEN_USER_DIR) +} +if { [string length $nguserdir] == 0 } { + set nguserdir "." +} + + + + +set batchmode [Ng_GetCommandLineParameter batchmode] + +set solvemode 0 +if { [Ng_GetCommandLineParameter solve] != "undefined" || \ + [Ng_GetCommandLineParameter recent] == "defined" } { + set solvemode defined +} + +set shellmode [Ng_GetCommandLineParameter shellmode] + +if { $shellmode == "defined" } { + set batchmode "defined" +} + + +if { $batchmode != "defined" } { + catch { + wm withdraw . + + wm title . $progname + wm geometry . =800x600 + wm minsize . 400 300 + } +} + + +source ${ngdir}/variables.tcl +source ${ngdir}/parameters.tcl + + +if { $batchmode != "defined" } { + catch { + source ${ngdir}/menustat.tcl + } +} + +catch { + source ${ngdir}/dialog.tcl +} + +catch { + source ${ngdir}/drawing.tcl +} + + +if { [catch { load libgeom2dvis[info sharedlibextension] Ng_Geom2d } result ] } { +# puts "cannot load 2d meshing module" +# puts "error: $result" +} + +catch { source ${ngdir}/csgeom.tcl } +catch { source ${ngdir}/stlgeom.tcl } + +set hasocc no +catch { source ${ngdir}/occgeom.tcl } + +source ${ngdir}/acisgeom.tcl + + +catch { source ${ngdir}/nghelp.tcl } +catch { source ${ngdir}/ngvisual.tcl } +catch { source ${ngdir}/sockets.tcl } +catch { source ${ngdir}/acis.tcl } + + + +set zugstange 0 +catch { source ${ngdir}/trafo/menu.tcl } + + + +setgranularity ${meshoptions.fineness} + +Ng_SetMeshingParameters +Ng_SetVisParameters +Ng_SetDebugParameters +Ng_STLDoctor +Ng_GeometryOptions set + +if { $hasocc == "yes" } { + Ng_SetOCCVisParameters +} + + +if { $batchmode != "defined" } { + catch { + wm protocol . WM_DELETE_WINDOW { .ngmenu.file invoke "Quit" } + wm deiconify . + } +} + +set trafoapp 0 +catch { source ${ngdir}/trafoapp/trafoapp.tcl } + +set geofilename [Ng_GetCommandLineParameter geofile] + +if { $geofilename != "undefined" && + [info exists trafo] == 0 && $zugstange == 0} { + + if { [ catch { Ng_LoadGeometry $geofilename } errstring] == 0 } { + if { $batchmode != "defined" } { + AddRecentFile $geofilename + } + Ng_ParseGeometry + if { $batchmode != "defined" } { + set selectvisual geometry + Ng_SetVisParameters + redraw + wm title . [concat "$progname - " $geofilename] + } + set dirname [file dirname $geofilename] + set basefilename [file tail [file rootname $geofilename]] + } { + puts "Problem with input file:" + puts "$errstring" + } +} + + +set cnt 0 +foreach { gran } { verycoarse coarse moderate fine veryfine } { + set cnt [expr $cnt + 1] + if { [Ng_GetCommandLineParameter $gran] == "defined" } { + set meshoptions.fineness $cnt + setgranularity ${meshoptions.fineness} + } +} + + +set meshfilename [Ng_GetCommandLineParameter meshfile] +if { $meshfilename == "undefined" } { + set meshfilename out.mesh +} + +set meshfiletype [Ng_GetCommandLineParameter meshfiletype] +if { $meshfiletype == "undefined" } { + set meshfiletype netgen +} + +set inputmeshfilename [Ng_GetCommandLineParameter inputmeshfile] + +set mergemeshfilename [Ng_GetCommandLineParameter mergefile] + +set meshsizefilename [Ng_GetCommandLineParameter meshsizefile] + +if { $meshsizefilename != "undefined" } { + set options.meshsizefilename $meshsizefilename +} + +set refinementfilename [Ng_GetCommandLineParameter refinementfile] + + +if { $batchmode == "defined" && $solvemode != "defined"} { + set options.parthread 0 + if { $shellmode == "undefined" } { +# old batchmode: only processes commandline arguments + set selectvisual mesh + Ng_SetVisParameters + + set meshsize [Ng_GetCommandLineParameter meshsize] + if {$meshsize != "undefined"} { set options.meshsize $meshsize } + + if { $inputmeshfilename == "undefined" } { + Ng_GenerateMesh ${meshoptions.firststep} ${meshoptions.laststep} + } else { + Ng_LoadMesh $inputmeshfilename + if { $mergemeshfilename != "undefined" } { + Ng_MergeMesh $mergemeshfilename + } + } + + if { $refinementfilename != "undefined" } { + Ng_Bisect $refinementfilename + } + + if { $meshfiletype == "netgen" } { + Ng_SaveMesh $meshfilename + } else { + if { [catch { Ng_ExportMesh $meshfilename $meshfiletype } ] == 1 } { + puts "Unknown file format $meshfiletype" + } + } + Ng_Exit; + + exit + } else { + set code [catch { source ${ngdir}/ngshell.tcl } errcode] + if {$code} { + puts "error: $errcode" + } + set code [ catch {Ng_RunShell} errcode] + if {$code} { + puts "error: $errcode" + } + + Ng_Exit; + exit + } + +} + +set stereo [Ng_GetCommandLineParameter stereo] +if { $stereo == "defined" } { + set viewoptions.stereo 1 + puts "use stereo mode" + Ng_SetVisParameters; + redraw +} + + +catch { source ${ngdir}/ngsolve.tcl } + + +set scriptfilename [Ng_GetCommandLineParameter script] +if { $scriptfilename != "undefined" } { + if { [catch { source $scriptfilename } errstring] == 1 } { + puts "Error in input: $errstring" + } +} + + +if { [Ng_GetCommandLineParameter help]=="defined" } { + if { $zugstange == 1 } { + print_zug_commandline_help + exit; + } { + if { $trafoapp == 1 } { + print_trafo_commandline_help; + } { + print_commandline_help; + Ng_Exit; + exit + } + } +} + + +if { [file exists startup.tcl] } { + source startup.tcl } + + + + +catch { source ${ngdir}/demoapp.tcl } +catch { source ${ngdir}/dropsexp.tcl } + diff --git a/ng/ngappinit.cpp b/ng/ngappinit.cpp new file mode 100644 index 00000000..4448567d --- /dev/null +++ b/ng/ngappinit.cpp @@ -0,0 +1,440 @@ +/* + The main function of netgen. + This file is a modification of tkAppInit.c from the Tcl/Tk package +*/ + +#include +#include "incvis.hpp" +#include + + + +namespace netgen +{ + int id = 0, ntasks = 1; +} + +#ifdef PARALLEL +#include + +extern void ParallelRun(); +namespace netgen +{ + MPI_Comm mesh_comm; +} +#endif + + + +namespace netgen +{ +#include "writeuser.hpp" + extern string ngdir; + Flags parameters; +} + + + +using netgen::parameters; +using netgen::ngdir; +using netgen::verbose; +using netgen::Array; +using netgen::RegisterUserFormats; + + + + +/* + * The following variable is a special hack that is needed in order for + * Sun shared libraries to be used for Tcl. + */ + +// extern "C" int matherr(); +// int *tclDummyMathPtr = (int *) matherr; + +extern "C" int Ng_ServerSocketManagerInit (int port); +extern "C" int Ng_ServerSocketManagerRun (void); + +bool nodisplay = false; +bool shellmode = false; + + +/* + * + * The Netgen main function + * + */ + +int main(int argc, char ** argv) +{ + +#ifdef PARALLEL + int mpi_required = MPI_THREAD_MULTIPLE; +#ifdef VTRACE + mpi_required = MPI_THREAD_SINGLE; +#endif + int mpi_provided; + MPI_Init_thread(&argc, &argv, mpi_required, &mpi_provided); + + MPI_Comm_size(MPI_COMM_WORLD, &netgen::ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &netgen::id); + + + MPI_Comm_dup ( MPI_COMM_WORLD, &netgen::mesh_comm); +#endif + + if ( netgen::id == 0 ) + { + cout << "NETGEN-" << PACKAGE_VERSION << endl; + + cout << "Developed by Joachim Schoeberl at" << endl + << "2010-xxxx Vienna University of Technology" << endl + << "2006-2010 RWTH Aachen University" << endl + << "1996-2006 Johannes Kepler University Linz" << endl; + +#ifdef OCCGEOMETRY + cout << "Including OpenCascade geometry kernel" << endl; +#endif + +#ifdef ACIS + cout << "Including ACIS geometry kernel" << endl; +#endif + +#ifdef LINUX + //feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); + //feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW); + //cout << "Handle Floating Point Exceptions: " << fegetexcept() << endl; +#endif + +#ifdef DEBUG + cout << "You are running the debug version !" << endl; +#endif + + +#ifdef PARALLEL + if (netgen::ntasks == 1) + { + cout << "Run parallel Netgen with 'mpirun -np xy netgen'" << endl; + } + else + { + cout << "Running MPI - parallel using " + << netgen::ntasks << " processor" + << ((netgen::ntasks > 1) ? "s " : " ") << endl; + + cout << "MPI-version = " << MPI_VERSION << '.' << MPI_SUBVERSION << endl; + + if (mpi_provided == MPI_THREAD_MULTIPLE) + cout << "multithreaded MPI is supported" << endl; + } +#endif + } + + + netgen::h_argc = argc; + netgen::h_argv = argv; + + // command line arguments: + for (int i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + parameters.SetCommandLineFlag (argv[i]); + else + parameters.SetFlag ("geofile", argv[i]); + } + + + if (getenv ("NETGENDIR") && strlen (getenv ("NETGENDIR"))) + ngdir = getenv ("NETGENDIR"); + else + ngdir = "."; + + verbose = parameters.GetDefineFlag ("V"); + + if (verbose) + cout << "NETGENDIR = " << ngdir << endl; + + + if ( netgen::id == 0 ) + { + if (parameters.StringFlagDefined ("testout")) + netgen::testout = new ofstream (parameters.GetStringFlag ("testout", "test.out")); + + +#ifdef SOCKETS + Ng_ServerSocketManagerInit(static_cast(parameters.GetNumFlag("serversocket",-1))); + if(parameters.GetNumFlag("serversocket",-1) > 0 && !parameters.GetDefineFlag("display")) + nodisplay = true; +#endif + + if(parameters.GetDefineFlag("batchmode")) + nodisplay = true; + + + if(parameters.GetDefineFlag("shellmode")) + { + nodisplay = true; + shellmode = true; + } + + Tcl_FindExecutable(NULL); + + // initialize application + Tcl_Interp * myinterp = Tcl_CreateInterp (); + if (Tcl_AppInit (myinterp) == TCL_ERROR) + { + cerr << "Exit Netgen due to initialization problem" << endl; + exit (1); + } + + + + // parse tcl-script + int errcode; + + bool internaltcl = false; + if (shellmode) + internaltcl = false; + + if (verbose) + { + cout << "Tcl header version = " << TCL_PATCH_LEVEL << endl; + Tcl_Eval (myinterp, "puts \"Tcl runtime version = [info patchlevel] \";"); + } + + if (parameters.GetDefineFlag ("internaltcl")) + internaltcl=true; + if (parameters.GetDefineFlag ("externaltcl")) + internaltcl=false; + + + + if (internaltcl) + { + if (verbose) + cout << "using internal Tcl-script" << endl; + + // connect to one string + extern const char * ngscript[]; + const char ** hcp = ngscript; + int len = 0; + while (*hcp) + len += strlen (*hcp++); + + char * tr1 = new char[len+1]; + *tr1 = 0; + hcp = ngscript; + + char * tt1 = tr1; + while (*hcp) + { + strcat (tt1, *hcp); + tt1 += strlen (*hcp++); + } + + errcode = Tcl_Eval (myinterp, tr1); + delete [] tr1; + } + + else + + { + string startfile = ngdir + "/ng.tcl"; + + if (verbose) + cout << "Load Tcl-script from " << startfile << endl; + + errcode = Tcl_EvalFile (myinterp, (char*)startfile.c_str()); + } + + if (errcode) + { + cout << "Error in Tcl-Script:" << endl; + // cout << "result = " << myinterp->result << endl; + cout << "result = " << Tcl_GetStringResult (myinterp) << endl; + // cout << "in line " << myinterp->errorLine << endl; + + cout << "\nMake sure to set environment variable NETGENDIR to directory containing ng.tcl" << endl; + exit (1); + } + + + // lookup user file formats and insert into format list: + Array userformats; + Array extensions; + RegisterUserFormats (userformats, extensions); + + ostringstream fstr; + + tcl_const char * exportft = Tcl_GetVar (myinterp, "exportfiletype", 0); + for (int i = 1; i <= userformats.Size(); i++) + { + fstr << ".ngmenu.file.filetype add radio -label \"" + << userformats.Get(i) << "\" -variable exportfiletype\n"; + fstr << "lappend meshexportformats { {" << userformats.Get(i) << "} {" << extensions.Get(i) << "} }\n"; + } + + Tcl_Eval (myinterp, (char*)fstr.str().c_str()); + Tcl_SetVar (myinterp, "exportfiletype", exportft, 0); + + +#ifdef SOCKETS + Ng_ServerSocketManagerRun(); +#endif + + // start event-loop + Tk_MainLoop(); + Tcl_DeleteInterp (myinterp); + Tcl_Exit(0); + } + +#ifdef PARALLEL + else + { + ParallelRun(); + MPI_Finalize(); + } + +#endif + + return 0; +} + + + +/* +extern "C" int Tix_Init (Tcl_Interp * interp); +extern "C" int Itcl_Init (Tcl_Interp * interp); +extern "C" int Itk_Init (Tcl_Interp * interp); +*/ +extern "C" int Ng_Init (Tcl_Interp * interp); +extern "C" int Ng_Vis_Init (Tcl_Interp * interp); + + + +// extern Tcl_PackageInitProc * Tk_SafeInit; + +/* + * + * Initialize packages + * + */ + +// extern "C" int NGSolve_Init (Tcl_Interp * interp); + + +int Tcl_AppInit(Tcl_Interp * interp) +{ + + if (Tcl_Init(interp) == TCL_ERROR) { + cerr << "Problem in Tcl_Init: " << endl; + cout << "result = " << Tcl_GetStringResult (interp) << endl; + // cerr << interp->result << endl; + // return TCL_ERROR; + } + + if (!nodisplay && Tk_Init(interp) == TCL_ERROR) { + cerr << "Problem in Tk_Init: " << endl; + cout << "result = " << Tcl_GetStringResult (interp) << endl; + // cerr << interp->result << endl; + // return TCL_ERROR; + } + + + if (Ng_Init(interp) == TCL_ERROR) { + cerr << "Problem in Ng_Init: " << endl; + cout << "result = " << Tcl_GetStringResult (interp) << endl; + // cerr << interp->result << endl; + // return TCL_ERROR; + } + + if (!nodisplay && Ng_Vis_Init(interp) == TCL_ERROR) { + cerr << "Problem in Ng_Vis_Init: " << endl; + cout << "result = " << Tcl_GetStringResult (interp) << endl; + // cerr << interp->result << endl; + // return TCL_ERROR; + } + + + + + + +#ifdef TRAFO + // extern int Trafo_Init (Tcl_Interp * interp); + // if (Trafo_Init(interp) == TCL_ERROR) + // { + // cerr << "Problem in Trafo_Init: " << endl; + // cerr << interp->result << endl; + // return TCL_ERROR; + // } +#endif + +#ifdef EBGELAST + extern int EBGElast_Init (Tcl_Interp * interp); + if(EBGElast_Init(interp) == TCL_ERROR) + { + cerr << "Problem in EBGElast_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#endif + +#ifdef SMALLTRAFO + extern int SmallModels_Init (Tcl_Interp * interp); + if(SmallModels_Init(interp) == TCL_ERROR) + { + cerr << "Problem in SmallModel_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#endif + +#ifdef SOCKETS + extern int Ng_Socket_Init (Tcl_Interp * interp); + if ( Ng_Socket_Init(interp) == TCL_ERROR) + { + cerr << "Problem in Ng_Socket_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } + +#endif + + +#ifdef ZUGSTANGE + extern int Zugstange_Init (Tcl_Interp * interp); + if (Zugstange_Init(interp) == TCL_ERROR) + { + cerr << "Problem in Zugstange_Init: " << endl; + cerr << interp->result << endl; + return TCL_ERROR; + } +#endif + + + Tcl_StaticPackage(interp, "Tk", Tk_Init, 0); + return TCL_OK; +} + + + + + +// link MKL with netgen +// necessary for MKL 11.x, since MKL complains if started +// from the ngsolve shared library + +#ifdef LINKMKL +extern "C" double ddot_(int *n, double *dx, int *incx, double *dy, + int *incy); + +int mkldummy() +{ + int n = 1, one = 1; + double a = 1, b = 1; + ddot_(&n, &a, &one, &b, &one); +} +#endif diff --git a/ng/nghelp.tcl b/ng/nghelp.tcl new file mode 100644 index 00000000..3d4191f7 --- /dev/null +++ b/ng/nghelp.tcl @@ -0,0 +1,338 @@ +proc print_commandline_help { } { + + puts "Usage: ng { options }" + + puts "-geofile=filename Input geometry file (alternative: ng filename)" + puts "-meshfile=filename Output mesh file" + puts "-verycoarse, -coarse, -moderate, -fine, -veryfine" + puts " Automatic mesh-size selection" + puts "-meshsizefile=filename Load mesh-size file with local mesh sizes" + puts "-meshfiletype={\"Neutral Format\", ...}" + puts " Filetype of output file, default is netgen file" + puts "-batchmode Run Netgen in batchmode" + puts "-inputmeshfile=filename" + puts " Input mesh file (batchmode only)" + puts "-mergefile=filename Merge with mesh file (batchmode only)" + puts "-refinementfile=filename" + puts " Use refinementinfo from file (batchmode only)" + puts "-serversocket=\#num Start a Netgen server with port \#num" + puts "-V Print additional information" + puts "-testout=filename file for test output" + + if { [catch { NGS_GetData } ] == 0 } { + puts "\nNGSolve parameters:" + puts "-pdefile=filename Load pde input file" + puts "-solve Solve pde once" + puts "-solve=n Solve pde by n adaptive refinement steps" + puts "-recent Load and solve most recently loaded pde" + } + +} + + + +proc set_menu_help { entry helpmsg } { + global menuhelps + set menuhelps($entry) $helpmsg +} + +proc show_menu_help { entry } { + global menuhelps + + + if {[catch {set helptext $menuhelps($entry)}]} { + set helptext "no help available " + } + + .helpline configure -text $helptext + + if {[winfo exists .senshelp_dlg]==1} { + .senshelp_dlg.text delete 1.0 end + .senshelp_dlg.text insert end "Menu item: $entry\n\n" + .senshelp_dlg.text insert end $helptext + } +} + + +tixBalloon .balloon -statusbar .helpline + +proc set_control_help { control helpmsg } { + bind $control "show_control_help {$helpmsg}" + bind $control "show_control_help {None}" + .balloon bind $control -balloonmsg $helpmsg -statusmsg $helpmsg +# puts "Add Help to $control" +} + +proc show_control_help { helpmsg } { + .helpline configure -text $helpmsg + if {[winfo exists .senshelp_dlg]==1} { + .senshelp_dlg.text delete 1.0 end + .senshelp_dlg.text insert end $helpmsg + } +} + + +proc sensitivehelpdialog { show } { + + set w .senshelp_dlg + + if {[winfo exists .senshelp_dlg] == 1} { + + if { $show == 1 } { + wm withdraw .senshelp_dlg + wm deiconify $w + focus $w + } { + wm withdraw $w + } + } { + toplevel $w +# wm minsize $w 200 150 + + global senshelptext + + text $w.text -yscrollcommand "$w.scroll set" -setgrid true \ + -width 40 -height 10 -wrap word + scrollbar $w.scroll -command "$w.text yview" + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + + frame $w.bu + pack $w.bu + # -fill x + + button $w.close -text "Close" \ + -command { + wm withdraw .senshelp_dlg + set showsensitivehelp 0 + } + pack $w.close + + + if { $show == 1 } { + wm withdraw $w + wm geom $w +100+100 + wm deiconify $w + wm title $w "Help" + focus $w + } + } +} + + + +set_menu_help "File" "In File menu you can load and store geometries, meshes etc." + +set_menu_help "New Geometry" "Deletes current geometry" +set_menu_help "Load Geometry" "Loads Geometry file in one of the formats STL (ASCII or binary), Constructive Solid Geometry (.geo) or 2D geometry. Please have a look into Netgen User's manuel for more details." +set_menu_help "Save Geometry" "Saves STL Geometry in in either ASCII or binary STL format." +set_menu_help "Load Mesh" "Loads surface and volume mesh in Netgen internal format." +set_menu_help "Save Mesh" "Saves surface and volume mesh in Netgen internal format." +set_menu_help "Write EPS File" "Dumps OpenGL rendering to EPS File." +set_menu_help "Save Options" "Saves current options in file \"ng.opt\". These options will be loaded again when starting ng in the same directory." +set_menu_help "Export Mesh" "Exports mesh in format defined by Export Filetype." +set_menu_help "Export Filetype" "Selects file format for exporting mesh. Please have a look into the Netgen User's manual for more information." +set_menu_help "Import Mesh" "Imports surface or volume mesh in exchange format." +set_menu_help "Quit" "Quits Netgen" + +set_menu_help "Geometry" "Preparing geometries, visualiztion of geometries." +set_menu_help "Scan CSG Geometry" "Generates surface triangulation for rendering" +set_menu_help "CSG Options" "Sets Options for CSG visualization (bounding box, detail size, number of facets)." +set_menu_help "CSG Properties" "Defines appearence of current CSG geometry (color, visibility, transparency)" +set_menu_help "STL Doctor" "Calls STL Doctor for preprocessing STL geometry files." +set_menu_help "STL Info" "Retrieves information about current STL geometry." + +set_menu_help "Mesh" "Menu for mesh generation" +set_menu_help "Generate Mesh" "Generates mesh from geometry, same as Button \"Generate Mesh\"" +set_menu_help "Stop Meshing" "Terminates meshgeneration. It may take a while until meshing terminates, please be patient." +set_menu_help "Meshing Options" "Set options for mesh generation." +set_menu_help "Delete Mesh" "Deletes mesh. Not necessary before generation of new mesh." +set_menu_help "Delete Vol Mesh" "Deletes only volume mesh." +set_menu_help "Mesh Quality" "Computs element shape measures. Triangle angles are inner angles of all triangles (faces of tetrahedra). Tet angles are angles between faces of tetrahedra." +set_menu_help "Check Surface Mesh" "Checks consistency and overlap of surface mesh. Marks overlapping elements as bad elements, please enable visualization of bad elements in View->Mesh." +set_menu_help "Check Volume Mesh" "Checks conformity of volume mesh." +set_menu_help "Edit Boundary Conditions" "Open dialog for setting boundary condition numbers for individual faces." +set_menu_help "Analyze Geometry" "Perform only first step in mesh generation. Action depends on geometry type, e.g. generates charts for STL mesh, find vertices in CSG geometries." +set_menu_help "Mesh Edges" "Meshes edges" +set_menu_help "Mesh Surface" "Generates surface mesh. Includes already surface optimization for some geomtry types." +set_menu_help "Optimize Surface" "Optimizes surface mesh." +set_menu_help "Surface Optim. Step" "Performs a specific surface optimiztion step. Mesh smoothing moves nodes. edge swapping swaps the diagonal of a quadrilateral built by two triangles, criterion either by number of nodes, or anlges. Combine points eliminates triangles by combining points (in the center of gravity)." +set_menu_help "Mesh Volume" "Performs volume meshing. Algorithm is a combination of Delaunay and Rule-based Advancing Front" +set_menu_help "Optimize Volume" "Performs additional volume optimization steps" +set_menu_help "Smooth Opt Volume" "Performs optimization steps by smoothing iterations" +set_menu_help "Smooth Opt Volume Jacobian" "Volume optimization by smoothing iterations. Criterion is optimization of Jacobi determinants. This optimization step is also available for 10-node tetrahedra." + +set_menu_help "View" "Sets viewing options" +set_menu_help "Zoom all" "Zooms scene to show whole object" +set_menu_help "Center" "Defines center of rotation" +set_menu_help "Viewing Options" "Sets viewing options for geometry, mesh, lighting" +set_menu_help "Clipping Plane" "Introduces clipping plane. The clipping plane is defined by the normal vector, and a scaled offset. Clipping of performed by OpenGl rendering" +set_menu_help "Quality Plot" "Shows the element quality distribution histogram. Measure is volume scaled by edge-length to the third. Optimal elements have measure 1." +set_menu_help "Sensitve Help" "Shows this help window" + +set_menu_help "Mesh-size" "Manipulations of existing mesh" +set_menu_help "Refine uniform" "Refines mesh by splitting elements into eight childs (algorithm of J. Bey)" +set_menu_help "Second Order" "Converts 4 node elements to 10 node elements. Edge-midpoitns are projected to the geometry." +set_menu_help "Refinement Dialog" "Controls local mesh refinement" +set_menu_help "Load Meshsize" "Loads mesh-size file for local mesh refinement." +set_menu_help "MS from Surf Mesh" "Defines mesh-size by the surface mesh." + + + + +set f .options_dlg.nb.nbframe.general +# set_control_help $f "General meshing page" +set_control_help $f.fine "Controls relative mesh size.\nThis control affects other mesh-size controls in common" +set_control_help $f.first "First step in mesh generation. Usually, meshing starts from \"analyze geometry\". If the surface mesh is already available \"First step\" should be set to \"mesh volume\"" +set_control_help $f.last "Last step in mesh generation. If only the surface mesh is required, please set \"Last Step\" to \"Optimize Surface\"" + +set_control_help .bubar.surfm "Start mesh generation" +set_control_help .bubar.stopm "Stop mesh generation" + +proc help_item { helptext } {p + puts $helptext +} + + + + + + + +proc show_help { } { + + set w .help + + if {[winfo exists .help] == 1} { + wm withdraw $w + wm deiconif $w + focus $w + } { + + toplevel $w + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.done -text Done -command "destroy $w" + pack $w.buttons.done -side left -expand 1 + + text $w.text -yscrollcommand "$w.scroll set" -setgrid true \ + -width 60 -height 24 -wrap word + scrollbar $w.scroll -command "$w.text yview" + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + + } + $w.text configure -state normal + $w.text delete 1.0 end +} + + + + + + +set bold "-background #43ce80 -relief raised -borderwidth 1" +set normal "-background {} -relief flat" + + +proc help_main { } { + + show_help; + set w .help + global bold + global normal + + + + $w.text insert 0.0 \ + {NETGEN Help} + $w.text insert end \n\n + $w.text insert end \ + {1. General} d1 + $w.text insert end \n\n + $w.text insert end \ + {2. Menu items } d2 + $w.text insert end \n\n + + foreach tag {d1 d2} { + $w.text tag bind $tag "$w.text tag configure $tag $bold" + $w.text tag bind $tag "$w.text tag configure $tag $normal" + } + + $w.text tag bind d1 <1> { puts "general"; help_general } + $w.text tag bind d2 <1> { help_menus } + + $w.text configure -state disabled +} + + + + + + +proc help_general { } { + + show_help; + set w .help + global bold + global normal + + puts "general called" + + $w.text insert 0.0 \ + {NETGEN is an automatic three dimensional tetrahedral mesh generation system. It accepts input from constructive solid geometry (CSG) or boundary representation (BRep) from STEP or STL file format. NETGEN contains modules for mesh optimization and hierarchical mesh refinement.} + + $w.text configure -state disabled +} + + + + + +proc help_menus { } { + + show_help; + set w .help + global bold + global normal + + + $w.text insert 0.0 \ + {The NETGEN Menu items are} + $w.text insert end \n\n + $w.text insert end \ + {1. File} d1 + $w.text insert end \n\n + $w.text insert end \ + {2. Geometry } d2 + $w.text insert end \n\n + $w.text insert end \ + {3. Mesh } d3 + $w.text insert end \n\n + $w.text insert end \ + {4. View } d4 + $w.text insert end \n\n + $w.text insert end \ + {5. Mesh-size } d5 + $w.text insert end \n\n + $w.text insert end \ + {6. STL } d6 + + foreach tag {d1 d2 d3 d4 d5 d6} { + $w.text tag bind $tag "$w.text tag configure $tag $bold" + $w.text tag bind $tag "$w.text tag configure $tag $normal" + } + + $w.text tag bind d1 <1> {puts "File menu"} + $w.text tag bind d2 <1> {puts "Geometry menu"} + $w.text tag bind d3 <1> {puts "Mesh menu"} + $w.text tag bind d4 <1> {puts "View menu"} + $w.text tag bind d5 <1> {puts "Mesh-size menu"} + $w.text tag bind d6 <1> {puts "STL menu"} + + $w.text configure -state disabled +} + + + diff --git a/ng/ngicon.tcl b/ng/ngicon.tcl new file mode 100644 index 00000000..d8b95ac6 --- /dev/null +++ b/ng/ngicon.tcl @@ -0,0 +1,75 @@ +set icon_data { +/* XPM */ +static char *icon2[] = { +/* width height num_colors chars_per_pixel */ +" 60 60 6 1", +/* colors */ +". c #000000", +"# c #008000", +"a c #00b700", +"b c #00c700", +"c c #00ff00", +"d s c None c None", +/* pixels */ +"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", +"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", +"dddddddddddddddd..........dddddddddddddddddddddddddddddddddd", +"ddddddddddddddd.c..cc#####................dddddddddddddddddd", +"ddddddddddddd..cccc..ccccccccccccccccc...#...............ddd", +"dddddddddddd.cccccccc..cccccccccccc...ccc..cccccccccc###..dd", +"ddddddddddd.ccccccccccc..ccccccccc.cccccccc.ccccccccccc...dd", +"dddddddddd.cccccccccccccc.cccccc..cccccccccc.ccccccccc.b..dd", +"ddddddddd.cccccccccccccccc..ccc.ccccccccccccc..cccccc.bb..dd", +"ddddddd........................cccccccccccccccc.cccc.bbb..dd", +"dddddd.ccc.ccccccccccccccccc..#..............ccc.c..bbbb..dd", +"dddd..ccccc..cccccccccccccc.#..##############.....bbbbb.b.dd", +"ddd.ccccccccc..ccccccccccc.##.#.#################.bbbbb.b.dd", +"dd.cccccccccccc..cccccccc.###.##.################.bbbbb.b.dd", +"d..cccccccccccccc..ccccc.####.###.###############.bbbbb.b.dd", +"d.a..............cc..cc.#####.####.##############.bbbb.bb.dd", +"d..aaaaaaaaaaaaaa......######.#####.#############.bbbb.bb.dd", +"d.a.aaaaaaaaaaaaaaaaa...#####.######..###########.bbbb.bb.dd", +"d.aa.aaaaaaaaaaaaaaaa...#####.########.##########.bbbb.bb.dd", +"d.aaa.aaaaaaaaaaaaaaa..#.####.#########.##########..b.bbb.dd", +"d.aaaa.aaaaaaaaaaaaaa..#.####.##########.#########..b.bbb.dd", +"d.aaaaa..aaaaaaaaaaaa..##.###.###########.########..b.bbb.dd", +"d.aaaaaaa.aaaaaaaaaaa..###.###.###########.#######..b.bbb.dd", +"d.aaaaaaaa.aaaaaaaaaa..###.###.############.######..b.bbb#.d", +"d.aaaaaaaaa.aaaaaaaaa..####.##.#############.#####...bbbb#.d", +"d.aaaaaaaaaa.aaaaaaaa..#####.#.##############.####...bbbb#.d", +"d.aaaaaaaaaaa.aaaaaaa..#####.#.###############.###...bbbb#.d", +"d.aaaaaaaaaaaa.aaaaaa..######..################.##...bbbb#.d", +"d.aaaaaaaaaaaaa.aaaaaaa.#####..#################.#..bbbbb#.d", +"d.aaaaaaaaaaaaaa.aaaaaa.#####.............#######...bbbbb#.d", +"d.aaaaaaaaaaaaaaa.aaaaa.####.###.#########..........bbbbbb.d", +"dd.aaaaaaaaaaaaaaa.aaaa.###.#####..##############...bbbbbb.d", +"dd.aaaaaaaaaaaaaaaa.aaa.##.########.############.b...bbbbb.d", +"dd.aaaaaaaaaaaaaaaaa.aa.#.##########...########.b.bbb.bbbb.d", +"dd.aaaaaaaaaaaaaaaaaa....##############.######.bb.bbb.bbbb.d", +"dd.aaaaaaaaaaaaaaaaaaaa...##############..###.bbb.bbbb.bbb.d", +"dd.aaaaaaaaaaaaaaaaaa..a.a..............##.#.bbbb.bbbb.bbb.d", +"dd.aaaaaaaaaaaaaaaaa.aaaa.aaaaaaaaaaaaaa....bbbb.bbbbbb.bb.d", +"dd.aaaaaaaaaaaaaaaa.aaaaa.aaaaaaaaaaaaaaaaa.bbbb.bbbbbbb.b.d", +"dd.aaaaaaaaaaaaaaa.aaaaaaa.aaaaaaaaaaaaaaaa.bbbb.bbbbbbb.b.d", +"dd.aaaaaaaaaaaaaa.aaaaaaaaa.aaaaaaaaaaaaaaa.bbbb.bbbbbbbb..d", +"dd.aaaaaaaaaaaaa.aaaaaaaaaaa.aaaaaaaaaaaaaa.bbb.bbbbbbbbb..d", +"dd.aaaaaaaaaaaa.aaaaaaaaaaaaa.aaaaaaaaaaaaa.bbb.bbbbbbbbbb.d", +"dd.aaaaaaaaaaa.aaaaaaaaaaaaaaa.aaaaaaaaaaaa.bbb.bbbbbbbbbb.d", +"dd.aaaaaaaaaa.aaaaaaaaaaaaaaaaa.aaaaaaaaaaaa.bb.bbbbbbbbb.dd", +"dd.aaaaaaaaa.aaaaaaaaaaaaaaaaaaa.aaaaaaaaaaa.bb.bbbbbbbb.ddd", +"dd.aaaaaaaa.aaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaa.b.bbbbbbbb.dddd", +"dd.aaaaaaa.aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaa.b.bbbbbbb.ddddd", +"dd.aaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa.b.bbbbbb.dddddd", +"dd.aaaa..aaaaaaaaaaaaaaaaaaaaaaaaaaa..aaaaaa.b.bbbbb.ddddddd", +"ddd.aa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaa..bbbb..dddddddd", +"ddd.a.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaa..bbb.dddddddddd", +"ddd..aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaa..bb.ddddddddddd", +"ddd........aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aa..b.dddddddddddd", +"ddddddddddd.............aaaaaaaaaaaaaaaaaa.a...ddddddddddddd", +"dddddddddddddddddddddddd............aaaaaaa...dddddddddddddd", +"dddddddddddddddddddddddddddddddddddd.........ddddddddddddddd", +"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", +"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", +"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" +}; +} diff --git a/ng/ngpkg.cpp b/ng/ngpkg.cpp new file mode 100644 index 00000000..afc47389 --- /dev/null +++ b/ng/ngpkg.cpp @@ -0,0 +1,3513 @@ +/* + +The interface between the GUI and the netgen library + +*/ + +#include +#include +#include + +#include + + +#include +#include + + +#include + + +#ifdef SOCKETS +#include "../libsrc/sockets/sockets.hpp" +#include "../libsrc/sockets/socketmanager.hpp" +#endif + + +// to be sure to include the 'right' togl-version +#include "togl_1_7.h" +// #include "togl_2_0.h" + +extern bool nodisplay; + +#include + + + +namespace netgen +{ +#include "../libsrc/interface/writeuser.hpp" +#include "demoview.hpp" +} + + +#ifdef ACIS +#include "ng_acis.hpp" +#endif + + +#ifdef JPEGLIB +#include +#endif + +#ifdef FFMPEG +extern "C" { + /* +#include +#include +#include + */ +#include +#include +#include +} +#endif + +#ifdef NGSOLVE +extern "C" void NGSolve_Exit(); +#endif + +// extern void * ngsolve_handle; + + +namespace netgen +{ + extern Flags parameters; + + /* + NetgenOutStream operator<< ( ostream & ost, Imp imp ) + { + return ( NetgenOutStream ( &ost, imp ) ); + } + + NetgenOutStream operator<< ( ostream & ost, Proc proc ) + { + return ( NetgenOutStream ( &ost, proc ) ); + } + + + NetgenOutStream operator<< ( ostream & ost, Procs & procs ) + { + return ( NetgenOutStream ( &ost, procs ) ); + } + */ + + extern AutoPtr ng_geometry; + extern AutoPtr mesh; + Tcl_Interp * tcl_interp; + + +#ifdef SOCKETS + AutoPtr clientsocket; + ServerSocketManager serversocketmanager; + //Array< AutoPtr < ServerInfo > > servers; + Array< ServerInfo* > servers; + AutoPtr serversocketusernetgen; +#endif + + + + // visualization scenes, pointer vs selects which one is drawn: + + static VisualScene vscross; + extern VisualSceneSurfaceMeshing vssurfacemeshing; + extern VisualSceneMesh vsmesh; + extern VisualSceneMeshDoctor vsmeshdoc; + + static VisualSceneSpecPoints vsspecpoints; + + VisualSceneSolution vssolution; + + + + VisualScene *vs = &vscross; + + + + char * err_needsmesh = (char*) "This operation needs a mesh"; + char * err_jobrunning = (char*) "Meshing Job already running"; + + + + + +#ifndef SMALLLIB + // Destination for messages, errors, ... + DLL_HEADER void Ng_PrintDest(const char * s) + { + /* +#ifdef PARALLEL + int id, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); +#else + int id = 0; int ntasks = 1; +#endif + */ + + if (id == 0) + (*mycout) << s << flush; + + /* + if ( ntasks == 1 ) + (*mycout) << s << flush; + else + (*mycout) << "p" << id << ": " << s << flush ; + */ + } + + DLL_HEADER void MyError(const char * ch) + { + cout << ch; + (*testout) << "Error !!! " << ch << endl << flush; + } +#endif + + static clock_t starttimea; + void ResetTime () + { + starttimea = clock(); + } + +#ifndef SMALLLIB + DLL_HEADER double GetTime () + { + return double(clock() - starttimea) / CLOCKS_PER_SEC; + } +#endif + + + + + + // file handling .. + int Ng_New (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (strcmp (argv[1], "mesh") == 0) + mesh.Reset(); + + if (strcmp (argv[1], "geom") == 0) + { + /* + delete ng_geometry; + ng_geometry = new NetgenGeometry; + */ + ng_geometry.Reset (new NetgenGeometry); + } + + return TCL_OK; + } + + + + + int Ng_ImportMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); + + int Ng_LoadMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + string filename (argv[1]); + + if (filename.find(".vol") == string::npos) + { + return Ng_ImportMesh(clientData,interp,argc,argv); + } + + PrintMessage (1, "load mesh from file ", filename); + + mesh.Reset (new Mesh()); + try + { + istream * infile; + // if (filename.substr (filename.length()-3, 3) == ".gz") + if (filename.find(".vol.gz") != string::npos) + infile = new igzstream (filename.c_str()); + else + infile = new ifstream (filename.c_str()); + + // ifstream infile(filename.c_str()); + mesh -> Load(*infile); + +#ifdef PARALLEL + MyMPI_SendCmd ("mesh"); + mesh -> Distribute(); +#endif + + for (int i = 0; i < geometryregister.Size(); i++) + { + NetgenGeometry * hgeom = geometryregister[i]->LoadFromMeshFile (*infile); + if (hgeom) + { + ng_geometry.Reset (hgeom); + break; + } + } + delete infile; + + /* + string auxstring; + if(infile.good()) + { + infile >> auxstring; + if(auxstring == "csgsurfaces") + { + CSGeometry * geometry = new CSGeometry (""); + geometry -> LoadSurfaces(infile); + + delete ng_geometry; + ng_geometry = geometry; + } + } + */ + } + catch (NgException e) + { + PrintMessage (3, e.What()); + return TCL_ERROR; + } + + PrintMessage (2, mesh->GetNP(), " Points, ", + mesh->GetNE(), " Elements."); + + return TCL_OK; + } + + + + + + int Ng_SaveMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + string filename (argv[1]); + PrintMessage (1, "Save mesh to file ", filename, ".... Please Wait!"); + + ostream * outfile; + if (filename.substr (filename.length()-3, 3) == ".gz") + outfile = new ogzstream (filename.c_str()); + else + outfile = new ofstream (filename.c_str()); + + mesh -> Save (*outfile); + *outfile << endl << endl << "endmesh" << endl << endl; + + if (ng_geometry) + ng_geometry -> SaveToMeshFile (*outfile); + + delete outfile; + PrintMessage (1, "Save mesh to file .... DONE!"); + return TCL_OK; + } + + + + + + int Ng_MergeMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + string filename (argv[1]); + + PrintMessage (1, "merge with mesh from file ", filename); + + try + { + CSGeometry * geometry = dynamic_cast (ng_geometry.Ptr()); + + //mesh -> Merge (filename); + ifstream infile(filename.c_str()); + const int offset = (geometry) ? geometry->GetNSurf() : 0; + mesh -> Merge(infile,offset); + + string auxstring; + if(infile.good()) + { + infile >> auxstring; + if(auxstring == "csgsurfaces") + geometry -> LoadSurfaces(infile); + } + } + catch (NgException e) + { + PrintMessage (3, e.What()); + return TCL_ERROR; + } + + PrintMessage (2, mesh->GetNP(), " Points, ", + mesh->GetNSE(), " Surface Elements."); + + return TCL_OK; + } + + + + + + int Ng_ExportMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + string filename (argv[1]); + string filetype (argv[2]); + PrintMessage (1, "Export mesh to file ", filename, ".... Please Wait!"); + + // CSGeometry * geometry = dynamic_cast (ng_geometry); + if (WriteUserFormat (filetype, *mesh, *ng_geometry, filename)) + { + ostringstream ost; + ost << "Sorry, nothing known about file format " << filetype << endl; + Tcl_SetResult (interp, (char*)ost.str().c_str(), TCL_VOLATILE); + return TCL_ERROR; + } + + PrintMessage (1, "Export mesh to file .... DONE!"); + return TCL_OK; + } + + + + int Ng_ImportMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + const string filename (argv[1]); + PrintMessage (1, "import mesh from ", filename); + + mesh.Reset (new Mesh()); + + ReadFile (*mesh, filename); + PrintMessage (2, mesh->GetNP(), " Points, ", + mesh->GetNE(), " Elements."); + + mesh->SetGlobalH (mparam.maxh); + mesh->CalcLocalH(mparam.grading); + + return TCL_OK; + } + + + + int Ng_ImportSolution (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + const char * filename = argv[1]; + PrintMessage (1, "Import solution from file ", filename); + + ImportSolution (filename); + return TCL_OK; + } + + + + static DemoView * demoview = 0; + int Ng_ShowDemo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + const char * filename = argv[1]; + PrintMessage (1, "Show demo ", filename); + demoview = new DemoView (filename); + + return TCL_OK; + } + + + + int Ng_DemoSetTime (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + cout << "demosettime, time = " << argv[1] << endl; + int result = -1; + + static char strminusone[] = "-1"; + static char str0[] = "0"; + + if (demoview) + result = demoview->SetTime (atof (argv[1])); + + if (result == -1) + Tcl_SetResult (interp, strminusone, TCL_STATIC); + else + Tcl_SetResult (interp, str0, TCL_STATIC); + + return TCL_OK; + } + + + + + + + + int Ng_SaveSolution (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + const char * filename = argv[1]; + PrintMessage (1, "Save solution to file ", filename); + + vssolution.SaveSolutionData (filename); + return TCL_OK; + } + + + + + int Ng_SetNextTimeStamp (ClientData clientData, + Tcl_Interp * interp, + int argqc, tcl_const char *argv[]) + { + if (mesh.Ptr()) + mesh -> SetNextTimeStamp(); + return TCL_OK; + } + + + + + int Ng_LoadGeometry (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + tcl_const char * lgfilename = argv[1]; + +#ifdef LOG_STREAM + (*logout) << "Load geometry file: " << lgfilename << endl; +#endif + +#ifdef STAT_STREAM + (*statout) << lgfilename << " & " << endl; +#endif + + + try + { + for (int i = 0; i < geometryregister.Size(); i++) + { + NetgenGeometry * hgeom = geometryregister[i]->Load (lgfilename); + if (hgeom) + { + // delete ng_geometry; + // ng_geometry = hgeom; + ng_geometry.Reset (hgeom); + + mesh.Reset(); + return TCL_OK; + } + } + + + ifstream infile(lgfilename); + + if (strlen(lgfilename) < 4) + { + cout << "ERROR: cannot recognise file format!" << endl; + } + else + { + if ((strcmp (&lgfilename[strlen(lgfilename)-4], "iges") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "igs") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "IGS") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "IGES") == 0)) + { + Tcl_SetResult (interp, (char*)"IGES import requires the OpenCascade geometry kernel. " + "Please install OpenCascade as described in the Netgen-website", + TCL_STATIC); + return TCL_ERROR; + } + + else if (strcmp (&lgfilename[strlen(lgfilename)-3], "sat") == 0) + { +#ifdef ACIS + PrintMessage (1, "Load ACIS geometry file ", lgfilename); + acisgeometry = netgen::LoadACIS_SAT (lgfilename); +#endif + } + else if ((strcmp (&lgfilename[strlen(lgfilename)-4], "step") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "stp") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-3], "STP") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "STEP") == 0)) + { +#ifdef ACISxxx + PrintMessage (1, "Load STEP geometry file ", lgfilename); + acisgeometry = netgen::LoadACIS_STEP (lgfilename); +#else + Tcl_SetResult (interp, (char*)"IGES import requires the OpenCascade geometry kernel. " + "Please install OpenCascade as described in the Netgen-website", + TCL_STATIC); + return TCL_ERROR; +#endif + } + else if ((strcmp (&lgfilename[strlen(lgfilename)-4], "brep") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "Brep") == 0) || + (strcmp (&lgfilename[strlen(lgfilename)-4], "BREP") == 0)) + { + Tcl_SetResult (interp, (char*)"BREP import requires the OpenCascade geometry kernel. " + "Please install OpenCascade as described in the Netgen-website", + TCL_STATIC); + return TCL_ERROR; + } + } + } + + catch (NgException e) + { + Tcl_SetResult (interp, const_cast (e.What().c_str()), TCL_VOLATILE); + return TCL_ERROR; + } + + mesh.Reset(); + return TCL_OK; + } + + + + + + + + + + + int Ng_SaveGeometry (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc == 2) + { + const char * cfilename = argv[1]; + + try + { + ng_geometry -> Save (string (cfilename)); + } + catch (NgException e) + { + Tcl_SetResult (interp, const_cast (e.What().c_str()), TCL_VOLATILE); + return TCL_ERROR; + } + + PrintMessage (1, "Save geometry to file ", cfilename); + + if (strlen(cfilename) < 4) {cout << "ERROR: can not recognise file format!!!" << endl;} + else + { +#ifdef ACIS + if (acisgeometry) + { + char * filename = const_cast (argv[1]); + if (strcmp (&filename[strlen(filename)-3], "sat") == 0) + { + acisgeometry -> SaveSATFile (filename); + } + } +#endif + /* + if (strcmp (&cfilename[strlen(cfilename)-3], "ngg") == 0) + { + CSGeometry * geometry = dynamic_cast (ng_geometry); + if (geometry) + { + ofstream of(cfilename); + geometry->Save (of); + } + } + */ + } + } + + return TCL_OK; + } + + + + + + + + + + int Ng_ReadStatus (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + char buf[20], lstring[200]; + if (mesh.Ptr()) + { + sprintf (buf, "%d", mesh->GetNP()); + Tcl_SetVar (interp, "::status_np", buf, 0); + sprintf (buf, "%d", mesh->GetNE()); + Tcl_SetVar (interp, "::status_ne", buf, 0); + sprintf (buf, "%d", mesh->GetNSE()); + Tcl_SetVar (interp, "::status_nse", buf, 0); + } + else + { + Tcl_SetVar (interp, "::status_np", "0", 0); + Tcl_SetVar (interp, "::status_ne", "0", 0); + Tcl_SetVar (interp, "::status_nse", "0", 0); + } + + if (multithread.running) + Tcl_SetVar (interp, "::status_working", "working", 0); + else + Tcl_SetVar (interp, "::status_working", " ", 0); + + Tcl_SetVar (interp, "::status_task", const_cast(multithread.task), 0); + sprintf (buf, "%lf", multithread.percent); + Tcl_SetVar (interp, "::status_percent", buf, 0); + + lstring[0] = 0; + for (int i = 1; i <= tets_in_qualclass.Size(); i++) + { + sprintf (buf, " %d", tets_in_qualclass.Get(i)); + strcat (lstring, buf); + } + for (int i = tets_in_qualclass.Size()+1; i <= 20; i++) + strcat (lstring, " 0"); + Tcl_SetVar (interp, "::status_tetqualclasses", lstring, 0); + + return TCL_OK; + } + + + int Ng_MemInfo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc < 2) return TCL_ERROR; + + if (strcmp (argv[1], "usedmb") == 0) + { // returns string of 512 '0' or '1' + + static char usedmb[513]; + for (int i = 0; i < 512; i++) + usedmb[i] = (i % 7 == 0) ? '1' : '0'; + + usedmb[512] = 0; + BaseDynamicMem::GetUsed (512, usedmb); + Tcl_SetResult (interp, usedmb, TCL_STATIC); + return TCL_OK; + } + + return TCL_ERROR; + } + + + + int Ng_BCProp (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + static char buf[100]; + + if (argc < 2) + { + Tcl_SetResult (interp, (char*)"Ng_BCProp needs arguments", TCL_STATIC); + return TCL_ERROR; + } + + if (strcmp (argv[1], "setbc") == 0) + { + int facenr = atoi (argv[2]); + int bcnr = atoi (argv[3]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + mesh->GetFaceDescriptor (facenr).SetBCProperty (bcnr); + } + + if (strcmp (argv[1], "setall") == 0) + { + int bcnr = atoi (argv[2]); + if (mesh.Ptr()) + { + int nfd = mesh->GetNFD(); + for (int i = 1; i <= nfd; i++) + mesh->GetFaceDescriptor (i).SetBCProperty (bcnr); + } + } + + if (strcmp (argv[1], "getbc") == 0) + { + int facenr = atoi (argv[2]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + { + sprintf (buf, "%d", mesh->GetFaceDescriptor(facenr).BCProperty()); + } + else + { + strcpy (buf, "0"); + } + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + if (strcmp (argv[1], "getbcname") == 0) + { + int facenr = atoi (argv[2]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + { + sprintf (buf, "%s", mesh->GetFaceDescriptor(facenr).GetBCName().c_str()); + } + else + { + strcpy (buf, "-"); + } + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + + if (strcmp (argv[1], "getactive") == 0) + { + sprintf (buf, "%d", vsmesh.SelectedFace()); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + if (strcmp (argv[1], "setactive") == 0) + { + int facenr = atoi (argv[2]); + if (mesh.Ptr() && facenr >= 1 && facenr <= mesh->GetNFD()) + { + vsmesh.SetSelectedFace (facenr); + } + } + + if (strcmp (argv[1], "getnfd") == 0) + { + if (mesh.Ptr()) + sprintf (buf, "%d", mesh->GetNFD()); + else + sprintf (buf, "0"); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + + return TCL_OK; + } + + + + + + int Ng_Refine (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + +#ifdef ACIS + if (acisgeometry) + { + ACISRefinementSurfaces ref (*acisgeometry); + ACISMeshOptimize2dSurfaces opt(*acisgeometry); + ref.Set2dOptimizer(&opt); + ref.Refine (*mesh); + } + else +#endif + { + ng_geometry -> GetRefinement().Refine(*mesh); + } + +//redo second order refinement if desired + if (mparam.secondorder) + const_cast (ng_geometry->GetRefinement()).MakeSecondOrder(*mesh); + + return TCL_OK; + } + + int Ng_SecondOrder (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + const_cast (ng_geometry -> GetRefinement()).MakeSecondOrder (*mesh); + + return TCL_OK; + } + + + void * HighOrderDummy (void *) + { + // mparam.elementorder = atoi (Tcl_GetVar (interp, "options.elementorder", 0)); + const char * savetask = multithread.task; + + Refinement & ref = const_cast (ng_geometry -> GetRefinement()); + mesh -> GetCurvedElements().BuildCurvedElements (&ref, mparam.elementorder); + + multithread.task = savetask; + multithread.running = 0; + multithread.terminate = 1; + + mesh -> SetNextMajorTimeStamp(); + return 0; + } + + int Ng_HighOrder (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + multithread.running = 1; + multithread.terminate = 0; + + mparam.elementorder = atoi(argv[1]); + + + HighOrderDummy(NULL); + + return TCL_OK; + } + + + + void * ValidateDummy (void *) + { + Refinement & ref = const_cast (ng_geometry -> GetRefinement()); + ref.ValidateSecondOrder (*mesh); + + multithread.running = 0; + return NULL; + } + + + + int Ng_ValidateSecondOrder (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + multithread.running = 1; + RunParallel (ValidateDummy, NULL); + + return TCL_OK; + } + + + int Ng_ZRefinement (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + ZRefinementOptions opt; + opt.minref = 5; + + if (argc >= 2) opt.minref = atoi (argv[1]); + + ZRefinement (*mesh, ng_geometry.Ptr(), opt); + + return TCL_OK; + } + + int Ng_HPRefinement (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + int levels = atoi (argv[1]); + + + Refinement & ref = const_cast (ng_geometry -> GetRefinement()); + HPRefinement (*mesh, &ref, levels); + return TCL_OK; + } + + + int Ng_LoadMeshSize (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->LoadLocalMeshSize(argv[1]); + return TCL_OK; + } + + + int Ng_MeshSizeFromSurfaceMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->SetGlobalH (mparam.maxh); + mesh->CalcLocalH(mparam.grading); + + return TCL_OK; + } + + + + + + // Philippose Rajan - 13 June 2009 + // Added a new TCL function call for the generation + // of prismatic boundary layers + int Ng_GenerateBoundaryLayer (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + if(multithread.running) + { + Tcl_SetResult(interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + GenerateBoundaryLayer (*mesh, mparam); + return TCL_OK; + } + + + int Ng_InsertVirtualBL (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + InsertVirtualBoundaryLayer (*mesh); + return TCL_OK; + } + + int Ng_CutOffAndCombine (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + Mesh othermesh; + othermesh.Load (argv[1]); + othermesh.SetGlobalH (mparam.maxh); + othermesh.CalcLocalH(mparam.grading); + + CutOffAndCombine (*mesh, othermesh); + return TCL_OK; + } + + + int Ng_HelmholtzMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + HelmholtzMesh (*mesh); + return TCL_OK; + } + + + + + int Ng_SetMeshingParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + mparam.maxh = atof (Tcl_GetVar (interp, "::options.meshsize", 0)); + mparam.minh = atof (Tcl_GetVar (interp, "::options.minmeshsize", 0)); + mparam.meshsizefilename = Tcl_GetVar (interp, "::options.meshsizefilename", 0); + if (!strlen (mparam.meshsizefilename)) + mparam.meshsizefilename = NULL; + + mparam.curvaturesafety = atof (Tcl_GetVar (interp, "::options.curvaturesafety", 0)); + mparam.segmentsperedge = atof (Tcl_GetVar (interp, "::options.segmentsperedge", 0)); + mparam.badellimit = atof (Tcl_GetVar (interp, "::options.badellimit", 0)); + mparam.secondorder = atoi (Tcl_GetVar (interp, "::options.secondorder", 0)); + mparam.elementorder = atoi (Tcl_GetVar (interp, "::options.elementorder", 0)); + mparam.quad = atoi (Tcl_GetVar (interp, "::options.quad", 0)); + + mparam.inverttets = atoi (Tcl_GetVar (interp, "::options.inverttets", 0)); + mparam.inverttrigs = atoi (Tcl_GetVar (interp, "::options.inverttrigs", 0)); + mparam.uselocalh = atoi (Tcl_GetVar (interp, "::options.localh", 0)); + mparam.grading = atof (Tcl_GetVar (interp, "::options.grading", 0)); + mparam.delaunay = atoi (Tcl_GetVar (interp, "::options.delaunay", 0)); + mparam.checkoverlap = atoi (Tcl_GetVar (interp, "::options.checkoverlap", 0)); + mparam.checkoverlappingboundary = atoi (Tcl_GetVar (interp, "::options.checkoverlappingboundary", 0)); + mparam.checkchartboundary = atoi (Tcl_GetVar (interp, "::options.checkchartboundary", 0)); + mparam.optsteps3d = atoi (Tcl_GetVar (interp, "::options.optsteps3d", 0)); + mparam.optsteps2d = atoi (Tcl_GetVar (interp, "::options.optsteps2d", 0)); + mparam.opterrpow = atof (Tcl_GetVar (interp, "::options.opterrpow", 0)); + + mparam.parthread = atoi (Tcl_GetVar (interp, "::options.parthread", 0)); + mparam.elsizeweight = atof (Tcl_GetVar (interp, "::options.elsizeweight", 0)); + + mparam.autozrefine = atoi (Tcl_GetVar (interp, "::options.autozrefine", 0)); + + extern int printmessage_importance; + extern int printdots; + printmessage_importance = atoi (Tcl_GetVar (interp, "::options.printmsg", 0)); + printdots = (printmessage_importance >= 4); + + //BaseMoveableMem::totalsize = 0; + // 1048576 * atoi (Tcl_GetVar (interp, "::options.memory", 0)); + if (mesh.Ptr()) + { + mesh->SetGlobalH (mparam.maxh); + mesh->SetMinimalH (mparam.minh); + } + +#ifdef PARALLEL + MyMPI_SendCmd ("bcastparthread"); + MyMPI_Bcast (mparam.parthread); +#endif + + return TCL_OK; + } + + + + int Ng_SetDebugParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + debugparam.slowchecks = atoi (Tcl_GetVar (interp, "::debug.slowchecks", 0)); + debugparam.debugoutput = atoi (Tcl_GetVar (interp, "::debug.debugoutput", 0)); + debugparam.haltexistingline = atoi (Tcl_GetVar (interp, "::debug.haltexistingline", 0)); + debugparam.haltoverlap = atoi (Tcl_GetVar (interp, "::debug.haltoverlap", 0)); + debugparam.haltsuccess = atoi (Tcl_GetVar (interp, "::debug.haltsuccess", 0)); + debugparam.haltnosuccess = atoi (Tcl_GetVar (interp, "::debug.haltnosuccess", 0)); + debugparam.haltlargequalclass = atoi (Tcl_GetVar (interp, "::debug.haltlargequalclass", 0)); + debugparam.haltsegment = atoi (Tcl_GetVar (interp, "::debug.haltsegment", 0)); + debugparam.haltnode = atoi (Tcl_GetVar (interp, "::debug.haltnode", 0)); + debugparam.haltface = atoi (Tcl_GetVar (interp, "::debug.haltface", 0)); + debugparam.haltsegmentp1 = atoi (Tcl_GetVar (interp, "::debug.haltsegmentp1", 0)); + debugparam.haltsegmentp2 = atoi (Tcl_GetVar (interp, "::debug.haltsegmentp2", 0)); + debugparam.haltfacenr = atoi (Tcl_GetVar (interp, "::debug.haltfacenr", 0)); + return TCL_OK; + } + + + + + + int Ng_GetCommandLineParameter (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc != 2) + { + Tcl_SetResult (interp, (char*)"Ng_GetCommandLineParameter needs 1 parameter", + TCL_STATIC); + return TCL_ERROR; + } + + static char buf[10]; + + if (parameters.StringFlagDefined (argv[1])) + Tcl_SetResult (interp, + (char*)parameters.GetStringFlag (argv[1], NULL), TCL_STATIC); + else if (parameters.NumFlagDefined (argv[1])) + { + sprintf (buf, "%lf", parameters.GetNumFlag (argv[1], 0)); + Tcl_SetResult (interp, buf, TCL_STATIC); + } + else if (parameters.GetDefineFlag (argv[1])) + Tcl_SetResult (interp, (char*)"defined", TCL_STATIC); + else + Tcl_SetResult (interp, (char*)"undefined", TCL_STATIC); + + return TCL_OK; + } + + + static int perfstepsstart; + static int perfstepsend; + + static char* optstring = NULL; + static char* optstringcsg = NULL; + + void * MeshingDummy (void *) + { + + const char * savetask = multithread.task; + multithread.task = "Generate Mesh"; + + ResetTime(); + + + try + { + +#ifdef LOG_STREAM + (*logout) << "Start meshing" << endl; + (*logout) << "Meshing parameters:" << endl; + mparam.Print (*logout); +#endif + +#ifdef ACIS + if (acisgeometry) + { + ACISGenerateMesh(*acisgeometry, mesh.Ptr(), perfstepsstart, perfstepsend, optstring); + } + else +#endif + /* + if (geometry2d) + { + extern void MeshFromSpline2D (SplineGeometry2d & geometry2d, + Mesh *& mesh, MeshingParameters & mp); + MeshFromSpline2D (*geometry2d, mesh.Ptr(), mparam); + } + else + */ + { + int res = ng_geometry -> GenerateMesh (mesh.Ptr(), mparam, perfstepsstart, perfstepsend); + if (res != MESHING3_OK) + { + multithread.task = savetask; + multithread.running = 0; + return 0; + } + } + + if (mparam.autozrefine) + { + ZRefinementOptions opt; + opt.minref = 5; + ZRefinement (*mesh, ng_geometry.Ptr(), opt); + mesh -> SetNextMajorTimeStamp(); + } + + if (mparam.secondorder) + { + const_cast (ng_geometry -> GetRefinement()).MakeSecondOrder (*mesh); + mesh -> SetNextMajorTimeStamp(); + } + + if (mparam.elementorder > 1) + { + mesh -> GetCurvedElements().BuildCurvedElements (&const_cast (ng_geometry -> GetRefinement()), + mparam.elementorder); + + mesh -> SetNextMajorTimeStamp(); + } + + + PrintMessage (1, "Meshing done, time = ", GetTime(), " sec"); + } + + catch (NgException e) + { + cout << e.What() << endl; + } + + multithread.task = savetask; + multithread.running = 0; + +#ifdef OCCGEOMETRYorig + // currently not active + OCCGeometry * occgeometry = dynamic_cast (ng_geometry); + if (occgeometry && occgeometry->ErrorInSurfaceMeshing()) + { + char script[] = "rebuildoccdialog"; + Tcl_GlobalEval (tcl_interp, script); + } +#endif + return NULL; + } + + + int MeshingVal(tcl_const char* str) + { + if (strcmp(str, "ag") == 0) {return MESHCONST_ANALYSE;} + if (strcmp(str, "me") == 0) {return MESHCONST_MESHEDGES;} + if (strcmp(str, "ms") == 0) {return MESHCONST_MESHSURFACE;} + if (strcmp(str, "os") == 0) {return MESHCONST_OPTSURFACE;} + if (strcmp(str, "mv") == 0) {return MESHCONST_MESHVOLUME;} + if (strcmp(str, "ov") == 0) {return MESHCONST_OPTVOLUME;} + + cout << "TCL TK ERROR, wrong meshing value, return='" << str << "'" << endl; + return 0; + } + + + + int Ng_GenerateMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + multithread.running = 1; + multithread.terminate = 0; + + for (int i = 0; i < geometryregister.Size(); i++) + geometryregister[i] -> SetParameters (interp); + + + Ng_SetMeshingParameters (clientData, interp, 0, argv); + + perfstepsstart = 1; + perfstepsend = 6; + + if (optstringcsg) delete optstringcsg; + optstringcsg = NULL; + if (optstring) delete optstring; + optstring = NULL; + + if (argc == 2) + { + perfstepsstart = 1; + perfstepsend = MeshingVal(argv[1]); + } + else if (argc == 3) + { + perfstepsstart = MeshingVal(argv[1]); + perfstepsend = MeshingVal(argv[2]); + } + else if (argc == 4) + { + perfstepsstart = MeshingVal(argv[1]); + perfstepsend = MeshingVal(argv[2]); + optstring = new char[strlen(argv[3])+1]; + strcpy(optstring, argv[3]); + optstringcsg = new char[strlen(argv[3])+1]; + strcpy(optstringcsg, argv[3]); + } + + RunParallel (MeshingDummy, NULL); + + return TCL_OK; + } + + + int Ng_StopMeshing (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + multithread.terminate = 1; + return TCL_OK; + } + + int Ng_MeshInfo (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + ostringstream str; + + if (argc >= 2 && strcmp (argv[1], "dim") == 0) + str << mesh->GetDimension(); + else if (argc >= 2 && strcmp (argv[1], "np") == 0) + str << mesh->GetNP(); + else if (argc >= 2 && strcmp (argv[1], "ne") == 0) + str << mesh->GetNE(); + else if (argc >= 2 && strcmp (argv[1], "nse") == 0) + str << mesh->GetNSE(); + else if (argc >= 2 && strcmp (argv[1], "nseg") == 0) + str << mesh->GetNSeg(); + else if (argc >= 2 && strcmp (argv[1], "bbox") == 0) + { + Point3d pmin, pmax; + mesh->GetBox (pmin, pmax); + str << pmin.X() << " " << pmax.X() << " " + << pmin.Y() << " " << pmax.Y() << " " + << pmin.Z() << " " << pmax.Z() << endl; + } + else + { + cout << "argv[1] = " << argv[1] << endl; + Tcl_SetResult (interp, (char*)"Ng_MeshInfo requires an argument out of \n dim np ne", TCL_STATIC); + return TCL_ERROR; + } + + Tcl_SetResult (interp, (char*)str.str().c_str(), TCL_VOLATILE); + return TCL_OK; + } + + int Ng_MeshQuality (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + double angles[4]; + char buf[10]; + + if (mesh.Ptr()) + mesh->CalcMinMaxAngle(mparam.badellimit, angles); + else + { + angles[0] = angles[1] = angles[2] = angles[3] = 0; + } + sprintf (buf, "%5.1lf", angles[0]); + Tcl_SetVar (interp, argv[1], buf, 0); + sprintf (buf, "%5.1lf", angles[1]); + Tcl_SetVar (interp, argv[2], buf, 0); + sprintf (buf, "%5.1lf", angles[2]); + Tcl_SetVar (interp, argv[3], buf, 0); + sprintf (buf, "%5.1lf", angles[3]); + Tcl_SetVar (interp, argv[4], buf, 0); + + return TCL_OK; + } + + int Ng_CheckSurfaceMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->FindOpenElements(); + if (mesh->CheckConsistentBoundary()) + { + PrintMessage (1, "surface mesh not consistent, trying orientation"); + mesh->SurfaceMeshOrientation(); + } + else + { + PrintMessage (1, "surface mesh consistent"); + } + + mesh->CheckOverlappingBoundary(); + return TCL_OK; + } + + int Ng_CheckVolumeMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->CheckVolumeMesh(); + return TCL_OK; + } + + + int Ng_DeleteVolMesh (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (mesh.Ptr()) + mesh->ClearVolumeElements(); + + return TCL_OK; + } + + + int Ng_SplitSeparatedFaces (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (mesh.Ptr()) + mesh->SplitSeparatedFaces (); + return TCL_OK; + } + + + + int Ng_RestrictH (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + if (argc != 3) + return TCL_OK; + if (!mesh.Ptr()) + return TCL_OK; + + + double loch = atof (argv[2]); + if (strcmp (argv[1], "face") == 0) + { + cout << "Restrict h at face to " << loch << endl; + mesh -> RestrictLocalH (RESTRICTH_FACE, vsmesh.SelectedFace(), loch); + } + if (strcmp (argv[1], "edge") == 0) + { + cout << "Restrict h at edge to " << loch << endl; + mesh -> RestrictLocalH (RESTRICTH_EDGE, vsmesh.SelectedEdge(), loch); + } + if (strcmp (argv[1], "point") == 0) + { + cout << "Restrict h at point to " << loch << endl; + mesh -> RestrictLocalH (RESTRICTH_POINT, vsmesh.SelectedPoint(), loch); + } + + return TCL_OK; + } + + + + + + int Ng_Anisotropy (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + if (argc != 2) + return TCL_OK; + if (!mesh.Ptr()) + return TCL_OK; + + if (strcmp (argv[1], "edge") == 0) + { + int edgenr = vsmesh.SelectedEdge(); + for (int i = 1; i <= mesh->GetNSeg(); i++) + { + Segment & seg = mesh->LineSegment(i); + if (seg.edgenr == edgenr) + { + seg.singedge_left = 1 - seg.singedge_left; + seg.singedge_right = 1 - seg.singedge_right; + } + } + } + + return TCL_OK; + } + + + + + BisectionOptions biopt; + + void * BisectDummy (void *) + { + const Refinement & ref = ng_geometry->GetRefinement(); + MeshOptimize2d * opt = NULL; + + /* +#ifdef ACIS + if (acisgeometry) + { + // ref = new ACISRefinementSurfaces(*acisgeometry); + opt = new ACISMeshOptimize2dSurfaces(*acisgeometry); + ref->Set2dOptimizer(opt); + } +#endif + else + { + ref = new RefinementSurfaces(*geometry); + opt = new MeshOptimize2dSurfaces(*geometry); + ref->Set2dOptimizer(opt); + } + */ + + if(!mesh->LocalHFunctionGenerated()) + mesh->CalcLocalH(mparam.grading); + + mesh->LocalHFunction().SetGrading (mparam.grading); + ref . Bisect (*mesh, biopt); + mesh -> UpdateTopology(); + mesh -> GetCurvedElements().BuildCurvedElements (&ref, mparam.elementorder); + + multithread.running = 0; + + delete opt; + return NULL; + } + + + int Ng_Bisect (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + + if (multithread.running) + { + cout << "Thread alrad running" << endl; + return TCL_OK; + } + multithread.running = 1; + + biopt.outfilename = NULL; // "ngfepp.vol"; + biopt.femcode = "fepp"; + biopt.refinementfilename = NULL; + + if (argc >= 2) + biopt.refinementfilename = argv[1]; + + + // pthread_create (&meshingthread, NULL, &BisectDummy, NULL); + BisectDummy (0); + + /* + extern void BisectTets (Mesh &, const CSGeometry *); + BisectTets (*mesh, geometry); + */ + return TCL_OK; + } + + + + // int Ng_BisectCopyMesh (ClientData clientData, + // Tcl_Interp * interp, + // int argc, tcl_const char *argv[]) + // { + // if (!mesh.Ptr()) + // { + // Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + // return TCL_ERROR; + // } + // if (multithread.running) + // { + // Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + // return TCL_ERROR; + // } + + // BisectTetsCopyMesh (*mesh, geometry.Ptr(), biopt); + // return TCL_OK; + // } + + + + + + + int Ng_Split2Tets (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!mesh.Ptr()) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + if (multithread.running) + { + Tcl_SetResult (interp, err_jobrunning, TCL_STATIC); + return TCL_ERROR; + } + + mesh->Split2Tets (); + + return TCL_OK; + } + + + + + + + + + extern int Ng_MeshDoctor (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]); + + + + + + + + SYMBOLTABLE & GetVisualizationScenes () + { + static SYMBOLTABLE vss; + return vss; + } + + void AddVisualizationScene (const string & name, + VisualScene * avs) + { + GetVisualizationScenes().Set (name.c_str(), avs); + } + + + void SetVisualScene (Tcl_Interp * interp) + { + const char * vismode = vispar.selectvisual; + // Tcl_GetVar (interp, "selectvisual", 0); + vs = &vscross; + if (GetVisualizationScenes().Used(vismode)) + { + vs = GetVisualizationScenes().Get(vismode); + } + else if (vismode) + { + if (strcmp (vismode, "geometry") == 0) + { + for (int i = 0; i < geometryregister.Size(); i++) + { + VisualScene * hvs = geometryregister[i]->GetVisualScene (ng_geometry.Ptr()); + if (hvs) + { + vs = hvs; + return; + } + } + +#ifdef ACIS + else if (acisgeometry) + vs = &vsacisgeom; +#endif // ACIS + } + + if (strcmp (vismode, "mesh") == 0) + { + if (!meshdoctor.active) + vs = &vsmesh; + else + vs = &vsmeshdoc; + } + + // if (strcmp (vismode, "surfmeshing") == 0) vs = &vssurfacemeshing; + if (strcmp (vismode, "specpoints") == 0) vs = &vsspecpoints; + // if (strcmp (vismode, "solution") == 0) vs = &vssolution; + } + } + + + + + + +#if TOGL_MAJOR_VERSION==1 + + + // Togl + + static int fontbase = 0; + + void MyOpenGLText (const char * text) + { + if (nodisplay) + return; + + glListBase (fontbase); + glCallLists (GLsizei(strlen(text)), GL_UNSIGNED_BYTE, text); + } + + + + static void init( struct Togl *togl ) + { + if (nodisplay) + return; + + fontbase = Togl_LoadBitmapFont( togl, TOGL_BITMAP_8_BY_13 ); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + SetVisualScene (Togl_Interp(togl)); + vs->DrawScene(); + } + + static void zap( struct Togl *togl ) + { + ; + } + + static void draw( struct Togl *togl ) + { + if (nodisplay) + return; + + + int w = Togl_Width (togl); + int h = Togl_Height (togl); + + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // OpenGL near and far clipping planes + double pnear = 0.1; + double pfar = 10; + + gluPerspective(20.0f, double(w) / h, pnear, pfar); + glMatrixMode(GL_MODELVIEW); + + + + Tcl_Interp * interp = Togl_Interp(togl); + + SetVisualScene (interp); + +#ifdef STEREO + if (1) // vispar.stereo) + { + glMatrixMode (GL_MODELVIEW); + glPushMatrix(); + + glLoadIdentity (); + + // glTranslatef (0.1, 0, 0); + gluLookAt (0.3, 0, 6, 0, 0, 0, 0, 1, 0); + Togl_StereoDrawBuffer(GL_BACK_RIGHT); + vs->DrawScene(); + + glLoadIdentity (); + // glTranslatef (-0.1, 0, 0); + gluLookAt (-0.3, 0, 6, 0, 0, 0, 0, 1, 0); + Togl_StereoDrawBuffer(GL_BACK_LEFT); + vs->DrawScene(); + glPopMatrix(); + + Togl_SwapBuffers(togl); + } + else +#endif + { + glPushMatrix(); + glLoadIdentity(); + // gluLookAt (0, 0, 6, 0, 0, 0, 0, 1, 0); + vs->DrawScene(); + glPopMatrix(); + Togl_SwapBuffers(togl); + } + } + + static void reshape( struct Togl *togl) + { + /* + if (nodisplay) + return; + + int w = Togl_Width (togl); + int h = Togl_Height (togl); + + glViewport(0, 0, w, h); + netgen::VisualScene::viewport[0]=0; + netgen::VisualScene::viewport[1]=0; + netgen::VisualScene::viewport[2]=w; + netgen::VisualScene::viewport[3]=h; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // OpenGL near and far clipping planes + double pnear = 0.1; + double pfar = 10; + + gluPerspective(20.0f, double(w) / h, pnear, pfar); + glMatrixMode(GL_MODELVIEW); + + draw (togl); + */ + } + + + +#else + + + // Sorry, Togl 2.0 not supported + + Tcl_Obj * togl_font; + Togl * togl = NULL; + + void MyOpenGLText (const char * text) + { + // cout << "togl - text: " << text << endl; + Togl_WriteChars (togl, togl_font, text, strlen(text)); + } + + static int + init(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) + { + cout << "call init" << endl; + + + if (Togl_GetToglFromObj(interp, objv[1], &togl) != TCL_OK) + return TCL_ERROR; + + cout << "call Togl - load font (crashes on my OpenSuse Linux64)" << endl; + // togl_font = Togl_LoadBitmapFont( togl, "Helvetica"); + // togl_font = Togl_LoadBitmapFont( togl, "Times"); + // togl_font = Togl_LoadBitmapFont( togl, TOGL_BITMAP_8_BY_13 ); + togl_font = Togl_LoadBitmapFont( togl, NULL ); + cout << "success" << endl; + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + + SetVisualScene (Togl_Interp(togl)); + vs->DrawScene(); + return TCL_OK; + } + + static int + zap(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) + { + return TCL_OK; + } + + + static int + draw(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) + { + SetVisualScene (interp); + + glPushMatrix(); + + glLoadIdentity(); + vs->DrawScene(); + Togl_SwapBuffers(togl); + + glPopMatrix(); + + return TCL_OK; + } + + static int + reshape(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) + { + int w = Togl_Width (togl); + int h = Togl_Height (togl); + + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + // OpenGL near and far clipping planes + double pnear = 0.1; + double pfar = 10; + + gluPerspective(20.0f, double(w) / h, pnear, pfar); + glMatrixMode(GL_MODELVIEW); + + return TCL_OK; + } + + + + + +#endif + + + + + +#if TOGL_MAJOR_VERSION==1 + +#ifndef JPEGLIB + static int Ng_SnapShot (struct Togl * togl, + int argc, tcl_const char *argv[]) + { + const char * filename = argv[2]; + + char str[250]; + char filename2[250]; + int len = strlen(filename); + strcpy (filename2, filename); + + filename2[len-3] = 'p'; + filename2[len-2] = 'p'; + filename2[len-1] = 'm'; + filename2[len] = 0; + + cout << "Snapshot to file '" << filename << endl; + + int w = Togl_Width (togl); + w = int((w + 1) / 4) * 4 + 4; + int h = Togl_Height (togl); + + // unsigned char * buffer = new unsigned char[w*h*4]; + unsigned char * buffer = new unsigned char[w*h*3]; + glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buffer); + + ofstream outfile(filename2); + outfile << "P6" << endl + << "# CREATOR: Netgen" << endl + << w << " " << h << endl + << "255" << endl; + for (int i = 0; i < h; i++) + for (int j = 0; j < w; j++) + for (int k = 0; k < 3; k++) + outfile.put (buffer[k+3*j+3*w*(h-i-1)]); + outfile << flush; + + delete[] buffer; + + // convert image file (Unix/Linux only): + sprintf(str,"convert -quality 100 %s %s", filename2, filename); + + int err = system(str); + if (err != 0) + { + Tcl_SetResult (Togl_Interp(togl), (char*)"Cannot convert image file", TCL_VOLATILE); + return TCL_ERROR; + } + sprintf(str,"rm %s", filename2); + system(str); + + return TCL_OK; + } + + + +#else + + + static int Ng_SnapShot (struct Togl * togl, + int argc, tcl_const char *argv[]) + { + const char * filename = argv[2]; + int len = strlen(filename); + + if (strcmp ("jpg", filename+len-3) == 0) + { + cout << "Snapshot to file '" << filename << "'" << endl; + + int w = Togl_Width (togl); + w = int((w + 1) / 4) * 4 + 4; + int h = Togl_Height (togl); + + // unsigned char * buffer = new unsigned char[w*h*4]; + unsigned char * buffer = new unsigned char[w*h*3]; + glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, buffer); + + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + FILE *outfile = fopen(filename,"wb"); + JSAMPROW row_pointer[1]; + int row_stride, quality = 85; // 1...100 + + cinfo.err = jpeg_std_error( &jerr ); + jpeg_create_compress( &cinfo ); + jpeg_stdio_dest( &cinfo, outfile ); + + + cinfo.image_width = w; + cinfo.image_height = h; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_RGB; + + jpeg_set_defaults( &cinfo ); + jpeg_set_quality( &cinfo, quality, TRUE ); + jpeg_start_compress( &cinfo, TRUE ); + + row_stride = 3*w; + while( cinfo.next_scanline < cinfo.image_height ) { + row_pointer[0] = &buffer[ (h-1-cinfo.next_scanline) * row_stride ]; + (void)jpeg_write_scanlines( &cinfo, row_pointer, 1 ); + } + + jpeg_finish_compress( &cinfo ); + fclose( outfile ); + + jpeg_destroy_compress( &cinfo ); + fprintf( stdout, "done [ok]\n" ); + fflush( stdout ); + + free( buffer ); + return TCL_OK; + } + else + { + cout << "Snapshot to " << filename << " not supported" << endl; + return TCL_ERROR; + } + } + + +#endif + + + + + +#ifdef FFMPEG + + // thanks to Mikko Lyly @ CSC, Helsinki + +#define STATE_READY 0 +#define STATE_STARTED 1 + + +#define INBUF_SIZE 4096 +#define DEFAULT_B_FRAMES 3 + // #define DEFAULT_B_FRAMES 0 +#define DEFAULT_GOP_SIZE 200 + // #define DEFAULT_GOP_SIZE 10 + // #define DEFAULT_BITRATE 500000 +#define DEFAULT_BITRATE 5000000 + // #define DEFAULT_MPG_BUFSIZE 500000 +#define DEFAULT_MPG_BUFSIZE 500000 + + typedef struct buffer_s { + uint8_t *MPG; + uint8_t *YUV; + uint8_t *RGB; + uint8_t *ROW; + } buffer_t; + + void free_buffers( buffer_t *buff ) { + free( buff->MPG ); + free( buff->YUV ); + free( buff->RGB ); + free( buff->ROW ); + } + + static double psnr( double d ) { + if( d==0 ) + return INFINITY; + return -10.0*log( d )/log( 10.0 ); + } + + void print_info( int count_frames, AVCodecContext *context, int bytes ) { + double tmp = context->width * context->height * 255.0 * 255.0; + double Ypsnr = psnr( context->coded_frame->error[0] / tmp ); + double quality = context->coded_frame->quality/(double)FF_QP2LAMBDA; + char pict_type = av_get_picture_type_char(context->coded_frame->pict_type); + cout << "video: frame=" << count_frames << " type=" << pict_type; + cout << " size=" << bytes << " PSNR(Y)=" << Ypsnr << " dB q=" << (float)quality << endl; + } + + + + static int Ng_VideoClip (struct Togl * togl, + int argc, tcl_const char *argv[]) + { + static AVCodec *codec = NULL; + static AVCodecContext *context = NULL; + static AVFrame *YUVpicture = NULL; + static AVFrame *RGBpicture = NULL; + static int bytes, PIXsize, stride; + static int y, nx, ny; + // static int ox, oy, viewp[4]; + static int i_state = STATE_READY; + static int initialized = 0; + static int count_frames = 0; + static int bitrate = DEFAULT_BITRATE; + static int gopsize = DEFAULT_GOP_SIZE; + static int bframes = DEFAULT_B_FRAMES; + static int MPGbufsize = DEFAULT_MPG_BUFSIZE; + static CodecID codec_id = CODEC_ID_MPEG1VIDEO; + static FILE *MPGfile; + static buffer_t buff; + static struct SwsContext *img_convert_ctx; + + + if (strcmp (argv[2], "init") == 0) + { + // Can't initialize when running: + //------------------------------- + if( i_state != STATE_READY ) { + cout << "cannot initialize: already running" << endl; + return TCL_ERROR; + } + + + + // Open output file: + //------------------- + const char * filename = argv[3]; + cout << "Saving videoclip to file '" << filename << "'" << endl; + MPGfile = fopen(filename, "wb"); + + // Determine picture size: + //------------------------ + nx = Togl_Width (togl); + nx = int((nx + 1) / 4) * 4 + 4; + ny = Togl_Height (togl); + ny = 2 * (ny/2); + cout << "Width=" << nx << ", height=" << ny << endl; + + // Allocate buffers: + //------------------ + PIXsize = nx*ny; + stride = 3*nx; + buff.RGB = (uint8_t*)malloc(stride*ny); + buff.ROW = (uint8_t*)malloc(stride); + buff.YUV = (uint8_t*)malloc(3*(PIXsize/2)); + buff.MPG = (uint8_t*)malloc(MPGbufsize); + + + // Initialize libavcodec: + //----------------------- + if( !initialized ) { + av_register_all(); + initialized = 1; + } + + // Choose codec: + //-------------- + codec = avcodec_find_encoder( codec_id ); + if( !codec ) { + free_buffers( &buff ); + fclose( MPGfile ); + cout << "can't find codec" << endl; + return TCL_ERROR; + } + + // Init codec context etc.: + //-------------------------- + // context = avcodec_alloc_context(); + context = avcodec_alloc_context3(codec); + + context->bit_rate = bitrate; + context->width = nx; + context->height = ny; + context->time_base = (AVRational){ 1, 25 }; + context->gop_size = gopsize; + context->max_b_frames = bframes; + context->pix_fmt = PIX_FMT_YUV420P; + context->flags |= CODEC_FLAG_PSNR; + + // if( avcodec_open( context, codec ) < 0 ) { + if( avcodec_open2( context, codec, NULL) < 0 ) { + cout << "can't open codec" << endl; + avcodec_close( context ); + av_free( context ); + free_buffers( &buff ); + fclose( MPGfile ); + return TCL_ERROR; + } + + YUVpicture = avcodec_alloc_frame(); + + YUVpicture->data[0] = buff.YUV; + YUVpicture->data[1] = buff.YUV + PIXsize; + YUVpicture->data[2] = buff.YUV + PIXsize + PIXsize / 4; + YUVpicture->linesize[0] = nx; + YUVpicture->linesize[1] = nx / 2; + YUVpicture->linesize[2] = nx / 2; + + RGBpicture = avcodec_alloc_frame(); + + RGBpicture->data[0] = buff.RGB; + RGBpicture->data[1] = buff.RGB; + RGBpicture->data[2] = buff.RGB; + RGBpicture->linesize[0] = stride; + RGBpicture->linesize[1] = stride; + RGBpicture->linesize[2] = stride; + + // Set state "started": + //---------------------- + i_state = STATE_STARTED; + cout << "savempg: state: started" << endl; + + return TCL_OK; + } + + + + else if (strcmp (argv[2], "addframe") == 0) + { + // Can't compress if status != started: + //------------------------------------- + if( i_state != STATE_STARTED ) { + cout << "cannot add frame: codec not initialized" << endl; + return TCL_ERROR; + } + + // Read RGB data: + //--------------- + glReadPixels (0, 0, nx, ny, GL_RGB, GL_UNSIGNED_BYTE, buff.RGB ); + + // The picture is upside down - flip it: + //--------------------------------------- + for( y=0; ydata, RGBpicture->linesize, + 0, ny, YUVpicture->data, YUVpicture->linesize ); + + + // Encode frame: + //-------------- + bytes = avcodec_encode_video( context, buff.MPG, + MPGbufsize, YUVpicture ); + count_frames++; + print_info( count_frames, context, bytes ); + fwrite( buff.MPG, 1, bytes, MPGfile ); + + return TCL_OK; + } + + + + else if (strcmp (argv[2], "finalize") == 0) + { + // Can't stop if status != started: + //--------------------------------- + if( i_state != STATE_STARTED ) { + cout << "cannot finalize: codec not initialized" << endl; + return TCL_ERROR; + } + + // Get the delayed frames, if any: + //-------------------------------- + for( ; bytes; ) { + bytes = avcodec_encode_video( context, buff.MPG, MPGbufsize, NULL ); + count_frames++; + print_info( count_frames, context, bytes ); + fwrite( buff.MPG, 1, bytes, MPGfile ); + } + + // Add sequence end code: + //----------------------- + if( codec_id == CODEC_ID_MPEG1VIDEO ) { + buff.MPG[0] = 0x00; + buff.MPG[1] = 0x00; + buff.MPG[2] = 0x01; + buff.MPG[3] = 0xb7; + fwrite( buff.MPG, 1, 4, MPGfile ); + } + + // Finalize: + //----------- + avcodec_close( context ); + av_free( context ); + av_free( YUVpicture ); + av_free( RGBpicture ); + free_buffers( &buff ); + fclose( MPGfile ); + + i_state = STATE_READY; + cout << "finalized" << endl; + + return TCL_OK; + } + return TCL_OK; + } + + + +#else + static int Ng_VideoClip (struct Togl * togl, + int argc, tcl_const char *argv[]) + { + Tcl_SetResult (Togl_Interp(togl), (char*)"Video not available, Netgen was not compiled with FFMPEG library", TCL_STATIC); + return TCL_ERROR; + } +#endif + +#endif + + + + + + + + + + + + + int Ng_MouseMove (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int oldx, oldy; + int newx, newy; + + oldx = atoi (argv[1]); + oldy = atoi (argv[2]); + newx = atoi (argv[3]); + newy = atoi (argv[4]); + + SetVisualScene(interp); + vs->MouseMove (oldx, oldy, newx, newy, argv[5][0]); + + return TCL_OK; + } + + + int Ng_MouseDblClick (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + int px, py; + + px = atoi (argv[1]); + py = atoi (argv[2]); + + SetVisualScene(interp); + vs->MouseDblClick (px, py); + + return TCL_OK; + } + + + int Ng_ZoomAll (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + vs->BuildScene (1); + + return TCL_OK; + } + + + int Ng_Center (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + vs->BuildScene (2); + + return TCL_OK; + } + + + int Ng_StandardRotation (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + vs->StandardRotation (argv[1]); + + return TCL_OK; + } + + int Ng_ArbitraryRotation (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + SetVisualScene(interp); + Array alpha; + Array vec; + + for(int i=1; iArbitraryRotation (alpha,vec); + + return TCL_OK; + } + + + + int Ng_Metis (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { +#ifdef METISold + + if (!mesh) + { + Tcl_SetResult (interp, err_needsmesh, TCL_STATIC); + return TCL_ERROR; + } + + // METIS Partitioning + + if (mesh->GetDimension() == 3) + { + using namespace metis; + + int ne = mesh->GetNE(); + if (ne < 3) + { + Tcl_SetResult (interp, "This operation needs a volume mesh", TCL_STATIC); + return TCL_ERROR; + } + + int nn = mesh->GetNP(); + + ELEMENT_TYPE elementtype = mesh->VolumeElement(1).GetType(); + int npe = mesh->VolumeElement(1).GetNP(); + + for (int i = 2; i<=ne; i++) + if (mesh->VolumeElement(i).GetType() != elementtype) + { + Tcl_SetResult (interp, "Works in 3D only uniformal tet or hex meshes", TCL_STATIC); + return TCL_ERROR; + } + + idxtype *elmnts; + elmnts = new idxtype[ne*npe]; + + int etype; + if (elementtype == TET) + etype = 2; + else if (elementtype == HEX) + etype = 3; + else + { + Tcl_SetResult (interp, "Works in 3D only uniformal tet or hex meshes", TCL_STATIC); + return TCL_ERROR; + } + + for (int i=1; i<=ne; i++) + for (int j=1; j<=npe; j++) + elmnts[(i-1)*npe+(j-1)] = mesh->VolumeElement(i).PNum(j)-1; + + + int numflag = 0; + int nparts = atoi (argv[1]); + int edgecut; + idxtype *epart, *npart; + epart = new idxtype[ne]; + npart = new idxtype[nn]; + + cout << "Starting Metis (" << ne << " Elements, " << nn << " Nodes, " << nparts << " Partitions) ... " << flush; + + METIS_PartMeshNodal (&ne, &nn, elmnts, &etype, &numflag, &nparts, + &edgecut, epart, npart); + + cout << "done" << endl; + + cout << "edge-cut: " << edgecut << ", balance: " << ComputeElementBalance(ne, nparts, epart) << endl; + + for (int i=1; i<=ne; i++) + mesh->VolumeElement(i).SetPartition(epart[i-1]); + + mesh->SetNextTimeStamp(); + } + + +#endif + return TCL_OK; + } + + + + + + void SelectFaceInOCCDialogTree (int facenr) + { + char script[50]; + sprintf (script, "selectentity {Face %i}", facenr); + Tcl_GlobalEval (tcl_interp, script); + } + + + + + +#ifndef ACIS + int Ng_ACISCommand (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (argc >= 2) + { + if (strcmp (argv[1], "isACISavailable") == 0) + { + Tcl_SetResult (interp, (char*)"no", TCL_STATIC); + return TCL_OK; + } + } + Tcl_SetResult (interp, (char*)"undefined ACiS command", TCL_STATIC); + return TCL_ERROR; + } +#endif + + + // from ng_interface + void Ng_SetVisualizationParameter (const char * name, const char * value) + { + // #ifdef OPENGL + // #ifndef NOTCL + char buf[100]; + sprintf (buf, "visoptions.%s", name); + if (printmessage_importance>0) + { + cout << "name = " << name << ", value = " << value << endl; + cout << "set tcl-variable " << buf << " to " << value << endl; + } + Tcl_SetVar (tcl_interp, buf, const_cast (value), 0); + Tcl_Eval (tcl_interp, "Ng_Vis_Set parameters;"); + // #endif + // #endif + } +} + + +using namespace netgen; +void Ng_InitSolutionData (Ng_SolutionData * soldata) +{ + + soldata -> name = NULL; + soldata -> data = NULL; + soldata -> components = 1; + soldata -> dist = 1; + soldata -> order = 1; + soldata -> iscomplex = 0; + soldata -> draw_surface = 1; + soldata -> draw_volume = 1; + soldata -> soltype = NG_SOLUTION_NODAL; + soldata -> solclass = 0; +} + +void Ng_SetSolutionData (Ng_SolutionData * soldata) +{ +#ifdef OPENGL + if (nodisplay) + return; + // vssolution.ClearSolutionData (); + VisualSceneSolution::SolData * vss = new VisualSceneSolution::SolData; + + vss->name = new char[strlen (soldata->name)+1]; + strcpy (vss->name, soldata->name); + + vss->data = soldata->data; + vss->components = soldata->components; + vss->dist = soldata->dist; + vss->order = soldata->order; + vss->iscomplex = bool(soldata->iscomplex); + vss->draw_surface = soldata->draw_surface; + vss->draw_volume = soldata->draw_volume; + vss->soltype = VisualSceneSolution::SolType (soldata->soltype); + vss->solclass = soldata->solclass; + vssolution.AddSolutionData (vss); +#endif +} + +void Ng_SetMouseEventHandler (netgen::MouseEventHandler * handler) +{ + vsmesh.SetMouseEventHandler (handler); +} + + +void Ng_ClearSolutionData () +{ +#ifdef OPENGL + if (nodisplay) + return; + vssolution.ClearSolutionData(); +#endif +} + + + +namespace netgen +{ + extern void Render (); +} + +void Ng_Redraw () +{ +#ifdef OPENGL + extern bool nodisplay; // he: global in ngappinit.cpp + if (!nodisplay) + { + netgen::vssolution.UpdateSolutionTimeStamp(); + Render(); + } +#endif +} + + + + + +namespace netgen +{ + + +int firsttime = 1; +int animcnt = 0; +void PlayAnimFile(const char* name, int speed, int maxcnt) +{ + //extern Mesh * mesh; + + /* + if (mesh.Ptr()) mesh->DeleteMesh(); + if (!mesh.Ptr()) mesh = new Mesh(); + */ + mesh.Reset (new Mesh()); + + int ne, np, i; + + char str[80]; + char str2[80]; + + //int tend = 5000; + // for (ti = 1; ti <= tend; ti++) + //{ + int rti = (animcnt%(maxcnt-1)) + 1; + animcnt+=speed; + + sprintf(str2,"%05i.sol",rti); + strcpy(str,"mbssol/"); + strcat(str,name); + strcat(str,str2); + + if (printmessage_importance>0) + cout << "read file '" << str << "'" << endl; + + ifstream infile(str); + infile >> ne; + for (i = 1; i <= ne; i++) + { + int j; + Element2d tri(TRIG); + tri.SetIndex(1); //faceind + + for (j = 1; j <= 3; j++) + infile >> tri.PNum(j); + + infile >> np; + for (i = 1; i <= np; i++) + { + Point3d p; + infile >> p.X() >> p.Y() >> p.Z(); + if (firsttime) + mesh->AddPoint (p); + else + mesh->Point(i) = Point<3> (p); + } + + //firsttime = 0; + Ng_Redraw(); + } +} + + + + + int Ng_SetVisParameters (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + if (!Tcl_GetVar (interp, "::viewoptions.light.amb", TCL_GLOBAL_ONLY)) + return TCL_ERROR; + + vispar.lightamb = atof (Tcl_GetVar (interp, "::viewoptions.light.amb", TCL_GLOBAL_ONLY)); + vispar.lightdiff = atof (Tcl_GetVar (interp, "::viewoptions.light.diff", TCL_GLOBAL_ONLY)); + vispar.lightspec = atof (Tcl_GetVar (interp, "::viewoptions.light.spec", TCL_GLOBAL_ONLY)); + vispar.shininess = atof (Tcl_GetVar (interp, "::viewoptions.mat.shininess", TCL_GLOBAL_ONLY)); + vispar.locviewer = atoi (Tcl_GetVar (interp, "::viewoptions.light.locviewer", TCL_GLOBAL_ONLY)); + vispar.transp = atof (Tcl_GetVar (interp, "::viewoptions.mat.transp", TCL_GLOBAL_ONLY)); + + VisualizationParameters::Clipping hclip; + hclip.normal.X() = atof (Tcl_GetVar (interp, "::viewoptions.clipping.nx", TCL_GLOBAL_ONLY)); + hclip.normal.Y() = atof (Tcl_GetVar (interp, "::viewoptions.clipping.ny", TCL_GLOBAL_ONLY)); + hclip.normal.Z() = atof (Tcl_GetVar (interp, "::viewoptions.clipping.nz", TCL_GLOBAL_ONLY)); + hclip.dist = atof (Tcl_GetVar (interp, "::viewoptions.clipping.dist", TCL_GLOBAL_ONLY)); + hclip.dist2 = atof (Tcl_GetVar (interp, "::viewoptions.clipping.dist2", TCL_GLOBAL_ONLY)); + hclip.enable = atoi (Tcl_GetVar (interp, "::viewoptions.clipping.enable", TCL_GLOBAL_ONLY)); + vispar.clipdomain = + atoi (Tcl_GetVar (interp, "::viewoptions.clipping.onlydomain", TCL_GLOBAL_ONLY)); + vispar.donotclipdomain = + atoi (Tcl_GetVar (interp, "::viewoptions.clipping.notdomain", TCL_GLOBAL_ONLY)); + + if ( ! (hclip == vispar.clipping) ) + hclip.timestamp = NextTimeStamp(); + vispar.clipping = hclip; + + + vispar.whitebackground = atoi (Tcl_GetVar (interp, "::viewoptions.whitebackground", TCL_GLOBAL_ONLY)); + vispar.drawcoordinatecross = atoi (Tcl_GetVar (interp, "::viewoptions.drawcoordinatecross", TCL_GLOBAL_ONLY)); + vispar.drawcolorbar = atoi (Tcl_GetVar (interp, "::viewoptions.drawcolorbar", TCL_GLOBAL_ONLY)); + vispar.drawnetgenlogo = atoi (Tcl_GetVar (interp, "::viewoptions.drawnetgenlogo", TCL_GLOBAL_ONLY)); + vispar.stereo = atoi (Tcl_GetVar (interp, "::viewoptions.stereo", TCL_GLOBAL_ONLY)); + vispar.colormeshsize = atoi (Tcl_GetVar (interp, "::viewoptions.colormeshsize", TCL_GLOBAL_ONLY)); + VisualScene :: SetBackGroundColor (vispar.whitebackground ? 1 : 0); + + strcpy (vispar.selectvisual, Tcl_GetVar (interp, "::selectvisual", TCL_GLOBAL_ONLY)); + + // vispar.showstltrias = atoi (Tcl_GetVar (interp, "::viewoptions.stl.showtrias", TCL_GLOBAL_ONLY)); + + vispar.stlshowtrias = + atoi (Tcl_GetVar (interp, "::stloptions.showtrias", TCL_GLOBAL_ONLY)); + vispar.stlshowfilledtrias = + atoi (Tcl_GetVar (interp, "::stloptions.showfilledtrias", TCL_GLOBAL_ONLY)); + vispar.stlshowedges = + atoi (Tcl_GetVar (interp, "::stloptions.showedges", TCL_GLOBAL_ONLY)); + vispar.stlshowmarktrias = + atoi (Tcl_GetVar (interp, "::stloptions.showmarktrias", TCL_GLOBAL_ONLY)); + vispar.stlshowactivechart = + atoi (Tcl_GetVar (interp, "::stloptions.showactivechart", TCL_GLOBAL_ONLY)); + vispar.stlchartnumber = + atoi (Tcl_GetVar (interp, "::stloptions.chartnumber", TCL_GLOBAL_ONLY)); + vispar.stlchartnumberoffset = + atoi (Tcl_GetVar (interp, "::stloptions.chartnumberoffset", TCL_GLOBAL_ONLY)); + + vispar.occshowsurfaces = + atoi (Tcl_GetVar (interp, "::occoptions.showsurfaces", TCL_GLOBAL_ONLY)); + vispar.occshowedges = + atoi (Tcl_GetVar (interp, "::occoptions.showedges", TCL_GLOBAL_ONLY)); + + vispar.drawoutline = + atoi (Tcl_GetVar (interp, "::viewoptions.drawoutline", TCL_GLOBAL_ONLY)); + vispar.drawfilledtrigs = + atoi (Tcl_GetVar (interp, "::viewoptions.drawfilledtrigs", TCL_GLOBAL_ONLY)); + vispar.subdivisions = + atoi (Tcl_GetVar (interp, "::visoptions.subdivisions", TCL_GLOBAL_ONLY)); + vispar.drawbadels = + atoi (Tcl_GetVar (interp, "::viewoptions.drawbadels", TCL_GLOBAL_ONLY)); + vispar.drawedges = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedges", TCL_GLOBAL_ONLY)); + + vispar.drawtetsdomain = + atoi (Tcl_GetVar (interp, "::viewoptions.drawtetsdomain", TCL_GLOBAL_ONLY)); + vispar.drawtets = + atoi (Tcl_GetVar (interp, "::viewoptions.drawtets", TCL_GLOBAL_ONLY)); + vispar.drawprisms = + atoi (Tcl_GetVar (interp, "::viewoptions.drawprisms", TCL_GLOBAL_ONLY)); + vispar.drawpyramids = + atoi (Tcl_GetVar (interp, "::viewoptions.drawpyramids", TCL_GLOBAL_ONLY)); + vispar.drawhexes = + atoi (Tcl_GetVar (interp, "::viewoptions.drawhexes", TCL_GLOBAL_ONLY)); + vispar.shrink = + atof (Tcl_GetVar (interp, "::viewoptions.shrink", TCL_GLOBAL_ONLY)); + vispar.drawidentified = + atoi (Tcl_GetVar (interp, "::viewoptions.drawidentified", TCL_GLOBAL_ONLY)); + vispar.drawpointnumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawpointnumbers", TCL_GLOBAL_ONLY)); + vispar.drawedgenumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedgenumbers", TCL_GLOBAL_ONLY)); + vispar.drawfacenumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawfacenumbers", TCL_GLOBAL_ONLY)); + vispar.drawelementnumbers = + atoi (Tcl_GetVar (interp, "::viewoptions.drawelementnumbers", TCL_GLOBAL_ONLY)); + vispar.drawdomainsurf = + atoi (Tcl_GetVar (interp, "::viewoptions.drawdomainsurf", TCL_GLOBAL_ONLY)); + + vispar.drawededges = + atoi (Tcl_GetVar (interp, "::viewoptions.drawededges", TCL_GLOBAL_ONLY)); + vispar.drawedpoints = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedpoints", TCL_GLOBAL_ONLY)); + vispar.drawedpointnrs = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedpointnrs", TCL_GLOBAL_ONLY)); + vispar.drawedtangents = + atoi (Tcl_GetVar (interp, "::viewoptions.drawedtangents", TCL_GLOBAL_ONLY)); + vispar.drawededgenrs = + atoi (Tcl_GetVar (interp, "::viewoptions.drawededgenrs", TCL_GLOBAL_ONLY)); + + vispar.drawcurveproj = + atoi (Tcl_GetVar (interp, "::viewoptions.drawcurveproj", TCL_GLOBAL_ONLY)); + vispar.drawcurveprojedge = + atoi (Tcl_GetVar (interp, "::viewoptions.drawcurveprojedge", TCL_GLOBAL_ONLY)); + + vispar.centerpoint = + atoi (Tcl_GetVar (interp, "::viewoptions.centerpoint", TCL_GLOBAL_ONLY)); + vispar.use_center_coords = + atoi (Tcl_GetVar (interp, "::viewoptions.usecentercoords", TCL_GLOBAL_ONLY)) > 0; + vispar.centerx = + atof (Tcl_GetVar (interp, "::viewoptions.centerx", TCL_GLOBAL_ONLY)); + vispar.centery = + atof (Tcl_GetVar (interp, "::viewoptions.centery", TCL_GLOBAL_ONLY)); + vispar.centerz = + atof (Tcl_GetVar (interp, "::viewoptions.centerz", TCL_GLOBAL_ONLY)); + vispar.drawelement = + atoi (Tcl_GetVar (interp, "::viewoptions.drawelement", TCL_GLOBAL_ONLY)); + vispar.drawmetispartition = + atoi (Tcl_GetVar (interp, "::viewoptions.drawmetispartition", TCL_GLOBAL_ONLY)); + + vispar.drawspecpoint = + atoi (Tcl_GetVar (interp, "::viewoptions.drawspecpoint", TCL_GLOBAL_ONLY)); + vispar.specpointx = + atof (Tcl_GetVar (interp, "::viewoptions.specpointx", TCL_GLOBAL_ONLY)); + vispar.specpointy = + atof (Tcl_GetVar (interp, "::viewoptions.specpointy", TCL_GLOBAL_ONLY)); + vispar.specpointz = + atof (Tcl_GetVar (interp, "::viewoptions.specpointz", TCL_GLOBAL_ONLY)); + + + vsspecpoints.len = + atof (Tcl_GetVar (interp, "::viewoptions.specpointvlen", TCL_GLOBAL_ONLY)); + + vispar.occdeflection = pow(10.0,-1-atof (Tcl_GetVar (interp, "::occoptions.deflection", TCL_GLOBAL_ONLY))); + + + +#ifdef PARALLELGL + vsmesh.Broadcast (); +#endif + + return TCL_OK; + } + + + + int Ng_BuildFieldLines (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + vssolution.BuildFieldLinesPlot(); + return TCL_OK; + } + + + + int Ng_Exit (ClientData clientData, + Tcl_Interp * interp, + int argc, tcl_const char *argv[]) + { + /* +#ifdef PARALLEL + int id, rc, ntasks; + MPI_Comm_size(MPI_COMM_WORLD, &ntasks); + MPI_Comm_rank(MPI_COMM_WORLD, &id); + if ( id != 0 ) + return TCL_OK; +#endif + */ + + /* + if (ngsolve_handle) + { + void (*ngs_exit)(); + ngs_exit = ( void (*)() ) dlsym (ngsolve_handle, "NGSolve_Exit"); + if (ngs_exit) (*ngs_exit)(); + } + */ + +#ifdef NGSOLVE + NGSolve_Exit (); +#endif + + + +#ifdef ACIS + outcome res; + res = api_terminate_faceter(); + if(!res.ok()) + cerr << "problem with terminating acis faceter" << endl; + res = api_terminate_constructors(); + if(!res.ok()) + cerr << "problem with terminating acis constructors" << endl; + res = api_terminate_kernel(); + if(!res.ok()) + cerr << "problem with terminating acis kernel" << endl; + res = api_stop_modeller(); + if(!res.ok()) + cerr << "problem with terminating acis modeller" << endl; + + //cout << "stopped acis, outcome = " << res.ok() << endl; +#endif + +#ifdef PARALLEL + if (id == 0) MyMPI_SendCmd ("end"); + MPI_Finalize(); +#endif + + mesh.Reset (NULL); + ng_geometry.Reset (NULL); + + if (testout != &cout) + delete testout; + + return TCL_OK; + } + + +#ifdef SOCKETS + void * ServerSocketManagerRunDummy ( void * nix ) + { + serversocketmanager.Run(); + return NULL; + } + + extern "C" int Ng_ServerSocketManagerRun( void ); + int Ng_ServerSocketManagerRun( void ) + { + if(mparam.parthread) + RunParallel(ServerSocketManagerRunDummy,NULL); + else + serversocketmanager.Run(); + + return TCL_OK; + } + + extern "C" int Ng_ServerSocketManagerInit(int port); + int Ng_ServerSocketManagerInit(int port) + { + serversocketmanager.Init(port); + return TCL_OK; + } +#endif //SOCKETS + + + extern "C" int Ng_Init (Tcl_Interp * interp); + extern "C" int Ng_CSG_Init (Tcl_Interp * interp); + +#ifdef _MSC_VER + extern "C" int Ng_stl_Init (Tcl_Interp * interp); + extern "C" int Ng_geom2d_Init (Tcl_Interp * interp); + #ifdef OCCGEOMETRY + extern "C" int Ng_occ_Init (Tcl_Interp * interp); + #endif +#endif + + + // extern "C" int Ng_Geom2d_Init (Tcl_Interp * interp); + + // int main_Eero (ClientData clientData, + // Tcl_Interp * interp, + // int argc, tcl_const char *argv[]); + + + int Ng_Init (Tcl_Interp * interp) + { +#ifdef SOCKETS + if(serversocketmanager.Good()) + serversocketusernetgen.Reset(new ServerSocketUserNetgen (serversocketmanager, mesh, geometry)); +#endif + + Ng_CSG_Init(interp); +#ifdef _MSC_VER + Ng_stl_Init(interp); + Ng_geom2d_Init (interp); +#ifdef OCCGEOMETRY + Ng_occ_Init (interp); +#endif +#endif + + + // Ng_Geom2d_Init(interp); + + tcl_interp = interp; + + // Tcl_CreateCommand (interp, "Ng_Eero", main_Eero, + // (ClientData)NULL, + // (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_New", Ng_New, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + // Tcl_CreateCommand (interp, "Ng_Lock", Ng_Lock, + // (ClientData)NULL, + // (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_LoadGeometry", Ng_LoadGeometry, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SaveGeometry", Ng_SaveGeometry, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_LoadMesh", Ng_LoadMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SaveMesh", Ng_SaveMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MergeMesh", Ng_MergeMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ExportMesh", Ng_ExportMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ImportMesh", Ng_ImportMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ImportSolution", Ng_ImportSolution, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ShowDemo", Ng_ShowDemo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_DemoSetTime", Ng_DemoSetTime, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SaveSolution", Ng_SaveSolution, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + + + + + // meshing + Tcl_CreateCommand (interp, "Ng_GenerateMesh", Ng_GenerateMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_StopMeshing", Ng_StopMeshing, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MeshInfo", Ng_MeshInfo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MeshQuality", Ng_MeshQuality, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_CheckSurfaceMesh", Ng_CheckSurfaceMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_CheckVolumeMesh", Ng_CheckVolumeMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_DeleteVolMesh", Ng_DeleteVolMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SplitSeparatedFaces", Ng_SplitSeparatedFaces, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetNextTimeStamp", Ng_SetNextTimeStamp, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Refine", Ng_Refine, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SecondOrder", Ng_SecondOrder, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_HighOrder", Ng_HighOrder, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ValidateSecondOrder", Ng_ValidateSecondOrder, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_RestrictH", Ng_RestrictH, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Anisotropy", Ng_Anisotropy, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Bisect", Ng_Bisect, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + // Tcl_CreateCommand (interp, "Ng_BisectCopyMesh", Ng_BisectCopyMesh, + // (ClientData)NULL, + // (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Split2Tets", Ng_Split2Tets, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ZRefinement", Ng_ZRefinement, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_HPRefinement", Ng_HPRefinement, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_LoadMeshSize", Ng_LoadMeshSize, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MeshSizeFromSurfaceMesh", Ng_MeshSizeFromSurfaceMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_GenerateBoundaryLayer", Ng_GenerateBoundaryLayer, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_InsertVirtualBL", Ng_InsertVirtualBL, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_CutOffAndCombine", Ng_CutOffAndCombine, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_HelmholtzMesh", Ng_HelmholtzMesh, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ReadStatus", Ng_ReadStatus, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MemInfo", Ng_MemInfo, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_MeshDoctor", Ng_MeshDoctor, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_BCProp", Ng_BCProp, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + + + Tcl_CreateCommand (interp, "Ng_ACISCommand", + Ng_ACISCommand, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_MouseMove", Ng_MouseMove, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_MouseDblClick", Ng_MouseDblClick, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_ZoomAll", Ng_ZoomAll, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Center", Ng_Center, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_StandardRotation", Ng_StandardRotation, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_ArbitraryRotation", Ng_ArbitraryRotation, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_SetVisParameters", Ng_SetVisParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetMeshingParameters", Ng_SetMeshingParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_SetDebugParameters", Ng_SetDebugParameters, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_GetCommandLineParameter", + Ng_GetCommandLineParameter, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Exit", + Ng_Exit, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + Tcl_CreateCommand (interp, "Ng_Metis", + Ng_Metis, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + + Tcl_CreateCommand (interp, "Ng_BuildFieldLines", + Ng_BuildFieldLines, + (ClientData)NULL, + (Tcl_CmdDeleteProc*) NULL); + + /* + * Specify the C callback functions for widget creation, display, + * and reshape. + */ +#if TOGL_MAJOR_VERSION==1 + if (!nodisplay) + { + if (Togl_Init(interp) == TCL_ERROR) + return TCL_ERROR; + + Togl_CreateFunc( init ); + Togl_DestroyFunc( zap ); + Togl_DisplayFunc( draw ); + Togl_ReshapeFunc( reshape ); + // Togl_TimerFunc( idle ); + Togl_CreateCommand( (char*)"Ng_SnapShot", Ng_SnapShot); + Togl_CreateCommand( (char*)"Ng_VideoClip", Ng_VideoClip); + // Togl_CreateCommand("position",position); + } +#else + if (!nodisplay) + { + if (Togl_Init(interp) == TCL_ERROR) + return TCL_ERROR; + + + Tcl_CreateObjCommand(interp, "init", init, NULL, NULL); + Tcl_CreateObjCommand(interp, "zap", zap, NULL, NULL); + Tcl_CreateObjCommand(interp, "draw", draw, NULL, NULL); + Tcl_CreateObjCommand(interp, "reshape", reshape, NULL, NULL); + + // Togl_TimerFunc( idle ); + // Togl_CreateCommand( (char*)"Ng_SnapShot", Ng_SnapShot); + // Togl_CreateCommand( (char*)"Ng_VideoClip", Ng_VideoClip); + // Togl_CreateCommand("position",position); + } + +#endif + + + multithread.pause = 0; + multithread.testmode = 0; + multithread.redraw = 0; + multithread.drawing = 1; + multithread.terminate = 0; + multithread.running = 0; + + multithread.task = ""; + multithread.percent = 20; + + + Tcl_LinkVar (interp, "multithread_pause", + (char*)&multithread.pause, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_testmode", + (char*)&multithread.testmode, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_redraw", + (char*)&multithread.redraw, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_drawing", + (char*)&multithread.drawing, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_terminate", + (char*)&multithread.terminate, TCL_LINK_INT); + Tcl_LinkVar (interp, "multithread_running", + (char*)&multithread.running, TCL_LINK_INT); + + + //testout->setstate(ios_base::badbit); + + myerr = &cerr; + extern ostream * mycout; + mycout = &cout; + + testmode = 0; + + + +#ifdef ACIS + outcome res; + res = api_start_modeller (0); + if(!res.ok()) + cerr << "problem with starting acis modeller" << endl; + +#ifdef ACIS_R17 + unlock_spatial_products_661(); +#endif + res = api_initialize_kernel(); + if(!res.ok()) + cerr << "problem with starting acis kernel" << endl; + res = api_initialize_constructors(); + if(!res.ok()) + cerr << "problem with starting acis constructors" << endl; + res = api_initialize_faceter(); + if(!res.ok()) + cerr << "problem with starting acis faceter" << endl; +#endif + + + return TCL_OK; + } + + +} + + diff --git a/ng/ngshell.tcl b/ng/ngshell.tcl new file mode 100644 index 00000000..06d2625e --- /dev/null +++ b/ng/ngshell.tcl @@ -0,0 +1,258 @@ +## the shell loop + +proc dotest {} { + source ngtest.tcl +} + +proc Ng_RunShell {} { + puts "Wellcome to NG Shell mode" + set line 1 + while { 1 } { + puts -nonewline "$line: " + flush stdout + set cmdline [gets stdin] + if { [catch $cmdline errcode] } { +# puts "error in command: '$cmdline'" + puts "$errcode" + } + incr line 1 + } +} + +## global list for help index +# ---> global var in variables.tcl +# set cmdindex {} +# set hlpindex {} +# set secindex {} + + + +# print comd list +proc Ng_PrintCmdIndex { } { + global cmdindex + foreach { lst } $cmdindex { + puts $lst + } +} + +# print formatted help index +proc Ng_PrintHlpIndex { } { + global hlpindex + global secindex + foreach {sec} $secindex { + puts "\n * $sec:" + foreach {lst} $hlpindex { + if {$sec == [lindex $lst 1]} { + puts " * [lindex $lst 2]: [lindex $lst 3]" + } + } + } +} + +# register a cmd to the help index +proc Ng_RegisterCmd { cmd section syntax {help ""} } { + global hlpindex + global cmdindex + global secindex + + puts "register command $cmd" + + if { [lsearch $cmdindex cmd] != -1 } { + puts "command '$cmd' already defined" + } else { + lappend cmdindex $cmd + + lappend hlpindex [list $cmd $section $syntax $help] + if {[lsearch $secindex $section]==-1} { + lappend secindex $section + } +# puts "registered command $cmd" + } +} + + +# general purpose commands +Ng_RegisterCmd "exit" "general" "exit" "exit Netgen shell mode" +#Ng_RegisterCmd "Ng_LoadGeometry" "netgen" "Ng_LoadGeometry " "load geometry file" +#Ng_RegisterCmd "Ng_ParseGeometry" "netgen" "Ng_ParseGeometry" "parse geometry" +#Ng_RegisterCmd "Ng_GenerateMesh" "netgen" "Ng_GenerateMesh" "generate mesh" +#Ng_RegisterCmd "Ng_SaveMesh" "netgen" "Ng_SaveMesh " "save mesh to file" + + +## public domain shell functions + +# print hel information +proc nghelp { {sec ""} } { + global secindex + global hlpindex + global cmdindex + if { $sec == "" } { + Ng_PrintHlpIndex + puts "\n type help 'section'\n" + return + } + + + if { [lsearch $secindex $sec] != -1} { + foreach {lst} $hlpindex { + if {[lindex $lst 1] == $sec } { + puts " * [lindex $lst 2]: [lindex $lst 3]" + } + } + return + } + + set ind [lsearch $cmdindex $sec] + if {$ind != -1} { + set lst [lindex $hlpindex $ind] + puts " * [lindex $lst 2]: [lindex $lst 3]" + return + } + + puts " unknown section or command $sec" +} + +set ngtimer 0 + +proc nggettimer {} { + return [clock clicks -milliseconds] +} + +proc ngtic {} { + set ::ngtimer [nggettimer] +} + + +proc ngtoc { {logfile stdout} } { + set end [nggettimer] + set tim [expr ($end - $::ngtimer)/1000.0] + puts $logfile "$tim s" +} + + +# load geometry file +proc ngloadgeometry { fname } { + if { ![file exists $fname] } { + puts "error: file $fname does not exist" + } else { + set err [catch {Ng_LoadGeometry $fname}] + if {$err != 0} { + puts "error: loading geometry failed" + } + } +} +Ng_RegisterCmd "ngloadgeometry" "netgen" "ngloadgeometry " "load geometry file" + +# parse geometry +proc ngparsegeometry {} { + set err [catch {Ng_ParseGeometry}] + if {$err} { + puts "error: parsing geometry failed" + } +} +Ng_RegisterCmd "ngparsegeometry" "netgen" "ngparsegeometry" "parse geometry" + +# generate mesh +proc nggeneratemesh {} { + set err [catch {Ng_GenerateMesh}] + if {$err} { + puts "error: mesh generation failed" + } +} +Ng_RegisterCmd "nggeneratemesh" "netgen" "nggeneratemesh" "generate mesh" + +# save mesh +proc ngsavemesh { fname } { + if { [file exists $fname]} { + puts "warning: existing file $fname overwritten" + } else { + set err [catch {Ng_SaveMesh $fname}] + if {$err != 0} { + puts "error: saving mesh failed" + } + } +} +Ng_RegisterCmd "ngsavemesh" "netgen" "ngsavemesh " "save mesh to file" + +#set option +proc ngset { opt {val 0} } { + if {$opt == "meshsize"} { + set ::options.meshsize $val + Ng_SetMeshingParameters + } elseif {$opt == "printmsg"} { + set ::options.printmsg $val + Ng_SetMeshingParameters + } else { + puts "error: unknown option $opt"; + } +} +Ng_RegisterCmd "ngset" "netgen" "ngset