diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Allwmake b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Allwmake new file mode 100755 index 0000000000..98dec66c76 --- /dev/null +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Allwmake @@ -0,0 +1,10 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory +set -x + +if [ -d "${FASTDUALOCTREE_SRC_PATH}" ] +then + wmake +fi + +# ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/files b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/files index 3d9e676a3e..fbe4cfeda6 100644 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/files +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/files @@ -4,6 +4,7 @@ MarchingCubes/MarchingCubes.cpp MarchingCubes/ply.c */ +/* MarchingCubes = fastdualoctree_sgp $(MarchingCubes)/data_access.cpp @@ -14,6 +15,7 @@ $(MarchingCubes)/mc_draw.cpp $(MarchingCubes)/morton.cpp $(MarchingCubes)/opt_octree.cpp $(MarchingCubes)/hash_octree.cpp +*/ cvMeshSurfaceSimplify.C diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/options b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/options index 5118e3d004..3b9b222ba8 100644 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/options +++ b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/Make/options @@ -6,7 +6,7 @@ EXE_INC = \ -DUNIX \ -Wno-old-style-cast \ /* -IMarchingCubes */ \ - -I$(MarchingCubes) \ + -I$(FASTDUALOCTREE_SRC_PATH) \ -I../conformalVoronoiMesh/lnInclude \ -I$(LIB_SRC)/edgeMesh/lnInclude \ -I$(LIB_SRC)/triSurface/lnInclude \ @@ -14,6 +14,7 @@ EXE_INC = \ EXE_LIBS = \ $(CGAL_LIBS) \ + -L$(FASTDUALOCTREE_SRC_PATH) -lperf_main \ -lGL \ -lconformalVoronoiMesh \ -ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lscotchDecomp \ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/.DS_Store b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/.DS_Store deleted file mode 100644 index 34e72fcf2d..0000000000 Binary files a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/.DS_Store and /dev/null differ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/CMakeLists.txt b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/CMakeLists.txt deleted file mode 100644 index 9140ecaa19..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/CMakeLists.txt +++ /dev/null @@ -1,96 +0,0 @@ -PROJECT(fastDualOctree) - -cmake_minimum_required(VERSION 2.8) - -#--------------------------------------------------- -#----- Dependencies -#--------------------------------------------------- -FIND_PACKAGE(OpenGL REQUIRED) -if ( OPENGL_FOUND ) - message( "-- OpenGL found. include=${OPENGL_INCLUDE_DIR}" ) - include_directories( ${OPENGL_INCLUDE_DIR} ) -endif ( OPENGL_FOUND ) - -FIND_PACKAGE(ZLIB REQUIRED) -if ( ZLIB_FOUND ) - message( "-- zlib found. include=${ZLIB_INCLUDE_DIR}" ) - include_directories( ${ZLIB_INCLUDE_DIR} ) -endif ( ZLIB_FOUND ) - -FIND_PACKAGE(PNG REQUIRED) -if ( PNG_FOUND ) - message( "-- PNG found. include=${PNG_INCLUDE_DIR}" ) - include_directories( ${PNG_INCLUDE_DIR} ) -endif ( PNG_FOUND ) - -##-- GLUI dependency -#FIND_PATH(GLUI_INCLUDE_DIR GL/glui.h ~/pub/system/glui-2.36/src/include) -#FIND_LIBRARY(GLUI_LIBRARIES -# NAMES GLUI glui -# GLUT glut -# PATHS /usr/local/lib/ -# /usr/lib/ -# /opt/graphics/OpenGL/lib -# /usr/openwin/lib -# /usr/shlib -# /usr/X11R6/lib -# ~/pub/system/glui-2.36/src/lib -# ) -#if ( GLUI_INCLUDE_DIR ) -# message( "-- GL/glui.h found. include=${GLUI_INCLUDE_DIR}" ) -# include_directories( ${GLUI_INCLUDE_DIR} ) -#else ( GLUI_INCLUDE_DIR ) -# message( "-- GL/glui.h not found." ) -#endif ( GLUI_INCLUDE_DIR ) -#if ( GLUI_LIBRARIES ) -# message( "-- libglui found. include=${GLUI_LIBRARIES}" ) -#else( GLUI_LIBRARIES ) -# message( "-- libglui not found." ) -#endif ( GLUI_LIBRARIES ) - -#--------------------------------------------------- -# -- Environement variables -#--------------------------------------------------- -if (UNIX) - add_definitions(-DUNIX) -endif (UNIX) -if (WIN32) - add_definitions(-DWIN32) -endif (WIN32) -if (APPLE) - add_definitions(-DAPPLE) -endif (APPLE) - -#--------------------------------------------------- -# -- SRCs -#--------------------------------------------------- - -SET(Perf_SRC ${Perf_SRC} - data_access.cpp - hash_octree.cpp - mc_draw.cpp - opt_octree.cpp - fparser.cpp - leaf_octree.cpp - mem_octree.cpp - fpoptimizer.cpp - MarchingCubes.cpp - morton.cpp - ptr_octree.cpp -) - -#SET(VIZ_SRC ${VIZ_SRC} -# viz_glui_cmdline.cpp -# viz_glui_controls.cpp -# viz_glui_draws.cpp -# viz_glui_export.cpp -# viz_glui_mouse.cpp -#) - - -add_executable(perf_main perf_main ${Perf_SRC}) -target_link_libraries(perf_main ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES}) - - -#add_executable(viz_glui_main viz_glui_main ${Perf_SRC} ${VIZ_SRC} ) -#target_link_libraries(viz_glui_main ${OPENGL_LIBRARIES} ${ZLIB_LIBRARIES} ${PNG_LIBRARIES} ${GLUI_LIBRARIES}) diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/Doxyfile b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/Doxyfile deleted file mode 100644 index 2667a0f7b6..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/Doxyfile +++ /dev/null @@ -1,1551 +0,0 @@ -# Doxyfile 1.6.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = DualOctree - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = 1.0 - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = "." - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it parses. -# With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this tag. -# The format is ext=language, where ext is a file extension, and language is one of -# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, -# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat -# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen to replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penality. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will rougly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespace are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = YES - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = YES - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = YES - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = YES - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by -# doxygen. The layout file controls the global structure of the generated output files -# in an output format independent way. The create the layout file that represents -# doxygen's defaults, run doxygen with the -l option. You can optionally specify a -# file name after the option, if omitted DoxygenLayout.xml will be used as the name -# of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = . - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = *gl2ps* \ - *mathexpr* - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER -# are set, an additional index file will be generated that can be used as input for -# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated -# HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. -# For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's -# filter section matches. -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = YES - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) -# there is already a search function so this one should typically -# be disabled. - -SEARCHENGINE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = NO - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# By default doxygen will write a font called FreeSans.ttf to the output -# directory and reference it in all dot files that doxygen generates. This -# font does not include all possible unicode characters however, so when you need -# these (or just want a differently looking font) you can specify the font name -# using DOT_FONTNAME. You need need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = FreeSans - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = YES - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 1000 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/LookUpTable.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/LookUpTable.h deleted file mode 100644 index f6b06e76b6..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/LookUpTable.h +++ /dev/null @@ -1,2317 +0,0 @@ -/** - * @file LookUpTable.h - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.2 - * @date 12/08/2002 - * - * @brief LookUpTable for the MarchingCubes 33 Algorithm - */ -//________________________________________________ - - - -#pragma once - - -//_____________________________________________________________________________ -/** - * \brief case mapping - * For each of the possible vertex states listed in this table there is a - * specific triangulation of the edge intersection points. The table lists - * all of them in the form of 0-5 edge triples with the list terminated by - * the invalid value -1. For example: case[3] list the 2 triangles - * formed when cube[0] and cube[1] are inside of the surface, but the rest of - * the cube is not. - * - * Cube description: - * 7 ________ 6 _____6__ ________ - * /| /| 7/| /| /| /| - * / | / | / | /5 | / 6 / | - * 4 /_______ / | /__4____ / 10 /_______3/ | - * | | |5 | | 11 | | | | | 2 | - * | 3|__|_____|2 | |__|__2__| | 4 |__|_____| - * | / | / 8 3/ 9 / | / | / - * | / | / | / | /1 | / 5 / - * |/_______|/ |/___0___|/ |/_1_____|/ - * 0 1 0 1 - */ -//----------------------------------------------------------------------------- -static const char cases[256][2] = { -/* 0: */ { 0, -1 }, -/* 1: 0, */ { 1, 0 }, -/* 2: 1, */ { 1, 1 }, -/* 3: 0, 1, */ { 2, 0 }, -/* 4: 2, */ { 1, 2 }, -/* 5: 0, 2, */ { 3, 0 }, -/* 6: 1, 2, */ { 2, 3 }, -/* 7: 0, 1, 2, */ { 5, 0 }, -/* 8: 3, */ { 1, 3 }, -/* 9: 0, 3, */ { 2, 1 }, -/* 10: 1, 3, */ { 3, 3 }, -/* 11: 0, 1, 3, */ { 5, 1 }, -/* 12: 2, 3, */ { 2, 5 }, -/* 13: 0, 2, 3, */ { 5, 4 }, -/* 14: 1, 2, 3, */ { 5, 9 }, -/* 15: 0, 1, 2, 3, */ { 8, 0 }, -/* 16: 4, */ { 1, 4 }, -/* 17: 0, 4, */ { 2, 2 }, -/* 18: 1, 4, */ { 3, 4 }, -/* 19: 0, 1, 4, */ { 5, 2 }, -/* 20: 2, 4, */ { 4, 2 }, -/* 21: 0, 2, 4, */ { 6, 2 }, -/* 22: 1, 2, 4, */ { 6, 9 }, -/* 23: 0, 1, 2, 4, */ { 11, 0 }, -/* 24: 3, 4, */ { 3, 8 }, -/* 25: 0, 3, 4, */ { 5, 5 }, -/* 26: 1, 3, 4, */ { 7, 3 }, -/* 27: 0, 1, 3, 4, */ { 9, 1 }, -/* 28: 2, 3, 4, */ { 6, 16 }, -/* 29: 0, 2, 3, 4, */ { 14, 3 }, -/* 30: 1, 2, 3, 4, */ { 12, 12 }, -/* 31: 0, 1, 2, 3, 4, */ { 5, 24 }, -/* 32: 5, */ { 1, 5 }, -/* 33: 0, 5, */ { 3, 1 }, -/* 34: 1, 5, */ { 2, 4 }, -/* 35: 0, 1, 5, */ { 5, 3 }, -/* 36: 2, 5, */ { 3, 6 }, -/* 37: 0, 2, 5, */ { 7, 0 }, -/* 38: 1, 2, 5, */ { 5, 10 }, -/* 39: 0, 1, 2, 5, */ { 9, 0 }, -/* 40: 3, 5, */ { 4, 3 }, -/* 41: 0, 3, 5, */ { 6, 4 }, -/* 42: 1, 3, 5, */ { 6, 11 }, -/* 43: 0, 1, 3, 5, */ { 14, 1 }, -/* 44: 2, 3, 5, */ { 6, 17 }, -/* 45: 0, 2, 3, 5, */ { 12, 4 }, -/* 46: 1, 2, 3, 5, */ { 11, 6 }, -/* 47: 0, 1, 2, 3, 5, */ { 5, 25 }, -/* 48: 4, 5, */ { 2, 8 }, -/* 49: 0, 4, 5, */ { 5, 7 }, -/* 50: 1, 4, 5, */ { 5, 12 }, -/* 51: 0, 1, 4, 5, */ { 8, 1 }, -/* 52: 2, 4, 5, */ { 6, 18 }, -/* 53: 0, 2, 4, 5, */ { 12, 5 }, -/* 54: 1, 2, 4, 5, */ { 14, 7 }, -/* 55: 0, 1, 2, 4, 5, */ { 5, 28 }, -/* 56: 3, 4, 5, */ { 6, 21 }, -/* 57: 0, 3, 4, 5, */ { 11, 4 }, -/* 58: 1, 3, 4, 5, */ { 12, 15 }, -/* 59: 0, 1, 3, 4, 5, */ { 5, 30 }, -/* 60: 2, 3, 4, 5, */ { 10, 5 }, -/* 61: 0, 2, 3, 4, 5, */ { 6, 32 }, -/* 62: 1, 2, 3, 4, 5, */ { 6, 39 }, -/* 63: 0, 1, 2, 3, 4, 5, */ { 2, 12 }, -/* 64: 6, */ { 1, 6 }, -/* 65: 0, 6, */ { 4, 0 }, -/* 66: 1, 6, */ { 3, 5 }, -/* 67: 0, 1, 6, */ { 6, 0 }, -/* 68: 2, 6, */ { 2, 6 }, -/* 69: 0, 2, 6, */ { 6, 3 }, -/* 70: 1, 2, 6, */ { 5, 11 }, -/* 71: 0, 1, 2, 6, */ { 14, 0 }, -/* 72: 3, 6, */ { 3, 9 }, -/* 73: 0, 3, 6, */ { 6, 5 }, -/* 74: 1, 3, 6, */ { 7, 4 }, -/* 75: 0, 1, 3, 6, */ { 12, 1 }, -/* 76: 2, 3, 6, */ { 5, 14 }, -/* 77: 0, 2, 3, 6, */ { 11, 3 }, -/* 78: 1, 2, 3, 6, */ { 9, 4 }, -/* 79: 0, 1, 2, 3, 6, */ { 5, 26 }, -/* 80: 4, 6, */ { 3, 10 }, -/* 81: 0, 4, 6, */ { 6, 6 }, -/* 82: 1, 4, 6, */ { 7, 5 }, -/* 83: 0, 1, 4, 6, */ { 12, 2 }, -/* 84: 2, 4, 6, */ { 6, 19 }, -/* 85: 0, 2, 4, 6, */ { 10, 1 }, -/* 86: 1, 2, 4, 6, */ { 12, 13 }, -/* 87: 0, 1, 2, 4, 6, */ { 6, 24 }, -/* 88: 3, 4, 6, */ { 7, 7 }, -/* 89: 0, 3, 4, 6, */ { 12, 9 }, -/* 90: 1, 3, 4, 6, */ { 13, 1 }, -/* 91: 0, 1, 3, 4, 6, */ { 7, 9 }, -/* 92: 2, 3, 4, 6, */ { 12, 20 }, -/* 93: 0, 2, 3, 4, 6, */ { 6, 33 }, -/* 94: 1, 2, 3, 4, 6, */ { 7, 13 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 3, 12 }, -/* 96: 5, 6, */ { 2, 10 }, -/* 97: 0, 5, 6, */ { 6, 7 }, -/* 98: 1, 5, 6, */ { 5, 13 }, -/* 99: 0, 1, 5, 6, */ { 11, 2 }, -/* 100: 2, 5, 6, */ { 5, 16 }, -/* 101: 0, 2, 5, 6, */ { 12, 7 }, -/* 102: 1, 2, 5, 6, */ { 8, 3 }, -/* 103: 0, 1, 2, 5, 6, */ { 5, 29 }, -/* 104: 3, 5, 6, */ { 6, 22 }, -/* 105: 0, 3, 5, 6, */ { 10, 2 }, -/* 106: 1, 3, 5, 6, */ { 12, 17 }, -/* 107: 0, 1, 3, 5, 6, */ { 6, 27 }, -/* 108: 2, 3, 5, 6, */ { 14, 9 }, -/* 109: 0, 2, 3, 5, 6, */ { 6, 34 }, -/* 110: 1, 2, 3, 5, 6, */ { 5, 39 }, -/* 111: 0, 1, 2, 3, 5, 6, */ { 2, 14 }, -/* 112: 4, 5, 6, */ { 5, 20 }, -/* 113: 0, 4, 5, 6, */ { 14, 5 }, -/* 114: 1, 4, 5, 6, */ { 9, 5 }, -/* 115: 0, 1, 4, 5, 6, */ { 5, 32 }, -/* 116: 2, 4, 5, 6, */ { 11, 10 }, -/* 117: 0, 2, 4, 5, 6, */ { 6, 35 }, -/* 118: 1, 2, 4, 5, 6, */ { 5, 41 }, -/* 119: 0, 1, 2, 4, 5, 6, */ { 2, 16 }, -/* 120: 3, 4, 5, 6, */ { 12, 23 }, -/* 121: 0, 3, 4, 5, 6, */ { 6, 37 }, -/* 122: 1, 3, 4, 5, 6, */ { 7, 14 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 3, 16 }, -/* 124: 2, 3, 4, 5, 6, */ { 6, 46 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 4, 6 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 3, 21 }, -/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 1, 8 }, -/* 128: 7, */ { 1, 7 }, -/* 129: 0, 7, */ { 3, 2 }, -/* 130: 1, 7, */ { 4, 1 }, -/* 131: 0, 1, 7, */ { 6, 1 }, -/* 132: 2, 7, */ { 3, 7 }, -/* 133: 0, 2, 7, */ { 7, 1 }, -/* 134: 1, 2, 7, */ { 6, 10 }, -/* 135: 0, 1, 2, 7, */ { 12, 0 }, -/* 136: 3, 7, */ { 2, 7 }, -/* 137: 0, 3, 7, */ { 5, 6 }, -/* 138: 1, 3, 7, */ { 6, 12 }, -/* 139: 0, 1, 3, 7, */ { 11, 1 }, -/* 140: 2, 3, 7, */ { 5, 15 }, -/* 141: 0, 2, 3, 7, */ { 9, 2 }, -/* 142: 1, 2, 3, 7, */ { 14, 6 }, -/* 143: 0, 1, 2, 3, 7, */ { 5, 27 }, -/* 144: 4, 7, */ { 2, 9 }, -/* 145: 0, 4, 7, */ { 5, 8 }, -/* 146: 1, 4, 7, */ { 6, 13 }, -/* 147: 0, 1, 4, 7, */ { 14, 2 }, -/* 148: 2, 4, 7, */ { 6, 20 }, -/* 149: 0, 2, 4, 7, */ { 12, 6 }, -/* 150: 1, 2, 4, 7, */ { 10, 3 }, -/* 151: 0, 1, 2, 4, 7, */ { 6, 25 }, -/* 152: 3, 4, 7, */ { 5, 18 }, -/* 153: 0, 3, 4, 7, */ { 8, 2 }, -/* 154: 1, 3, 4, 7, */ { 12, 16 }, -/* 155: 0, 1, 3, 4, 7, */ { 5, 31 }, -/* 156: 2, 3, 4, 7, */ { 11, 9 }, -/* 157: 0, 2, 3, 4, 7, */ { 5, 34 }, -/* 158: 1, 2, 3, 4, 7, */ { 6, 40 }, -/* 159: 0, 1, 2, 3, 4, 7, */ { 2, 13 }, -/* 160: 5, 7, */ { 3, 11 }, -/* 161: 0, 5, 7, */ { 7, 2 }, -/* 162: 1, 5, 7, */ { 6, 14 }, -/* 163: 0, 1, 5, 7, */ { 12, 3 }, -/* 164: 2, 5, 7, */ { 7, 6 }, -/* 165: 0, 2, 5, 7, */ { 13, 0 }, -/* 166: 1, 2, 5, 7, */ { 12, 14 }, -/* 167: 0, 1, 2, 5, 7, */ { 7, 8 }, -/* 168: 3, 5, 7, */ { 6, 23 }, -/* 169: 0, 3, 5, 7, */ { 12, 10 }, -/* 170: 1, 3, 5, 7, */ { 10, 4 }, -/* 171: 0, 1, 3, 5, 7, */ { 6, 28 }, -/* 172: 2, 3, 5, 7, */ { 12, 21 }, -/* 173: 0, 2, 3, 5, 7, */ { 7, 10 }, -/* 174: 1, 2, 3, 5, 7, */ { 6, 41 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 3, 13 }, -/* 176: 4, 5, 7, */ { 5, 21 }, -/* 177: 0, 4, 5, 7, */ { 9, 3 }, -/* 178: 1, 4, 5, 7, */ { 11, 8 }, -/* 179: 0, 1, 4, 5, 7, */ { 5, 33 }, -/* 180: 2, 4, 5, 7, */ { 12, 22 }, -/* 181: 0, 2, 4, 5, 7, */ { 7, 11 }, -/* 182: 1, 2, 4, 5, 7, */ { 6, 42 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 3, 14 }, -/* 184: 3, 4, 5, 7, */ { 14, 11 }, -/* 185: 0, 3, 4, 5, 7, */ { 5, 36 }, -/* 186: 1, 3, 4, 5, 7, */ { 6, 44 }, -/* 187: 0, 1, 3, 4, 5, 7, */ { 2, 17 }, -/* 188: 2, 3, 4, 5, 7, */ { 6, 47 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 3, 18 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 4, 7 }, -/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 1, 9 }, -/* 192: 6, 7, */ { 2, 11 }, -/* 193: 0, 6, 7, */ { 6, 8 }, -/* 194: 1, 6, 7, */ { 6, 15 }, -/* 195: 0, 1, 6, 7, */ { 10, 0 }, -/* 196: 2, 6, 7, */ { 5, 17 }, -/* 197: 0, 2, 6, 7, */ { 12, 8 }, -/* 198: 1, 2, 6, 7, */ { 11, 7 }, -/* 199: 0, 1, 2, 6, 7, */ { 6, 26 }, -/* 200: 3, 6, 7, */ { 5, 19 }, -/* 201: 0, 3, 6, 7, */ { 14, 4 }, -/* 202: 1, 3, 6, 7, */ { 12, 18 }, -/* 203: 0, 1, 3, 6, 7, */ { 6, 29 }, -/* 204: 2, 3, 6, 7, */ { 8, 4 }, -/* 205: 0, 2, 3, 6, 7, */ { 5, 35 }, -/* 206: 1, 2, 3, 6, 7, */ { 5, 40 }, -/* 207: 0, 1, 2, 3, 6, 7, */ { 2, 15 }, -/* 208: 4, 6, 7, */ { 5, 22 }, -/* 209: 0, 4, 6, 7, */ { 11, 5 }, -/* 210: 1, 4, 6, 7, */ { 12, 19 }, -/* 211: 0, 1, 4, 6, 7, */ { 6, 30 }, -/* 212: 2, 4, 6, 7, */ { 14, 10 }, -/* 213: 0, 2, 4, 6, 7, */ { 6, 36 }, -/* 214: 1, 2, 4, 6, 7, */ { 6, 43 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 4 }, -/* 216: 3, 4, 6, 7, */ { 9, 7 }, -/* 217: 0, 3, 4, 6, 7, */ { 5, 37 }, -/* 218: 1, 3, 4, 6, 7, */ { 7, 15 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 3, 17 }, -/* 220: 2, 3, 4, 6, 7, */ { 5, 44 }, -/* 221: 0, 2, 3, 4, 6, 7, */ { 2, 19 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 3, 22 }, -/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 1, 10 }, -/* 224: 5, 6, 7, */ { 5, 23 }, -/* 225: 0, 5, 6, 7, */ { 12, 11 }, -/* 226: 1, 5, 6, 7, */ { 14, 8 }, -/* 227: 0, 1, 5, 6, 7, */ { 6, 31 }, -/* 228: 2, 5, 6, 7, */ { 9, 6 }, -/* 229: 0, 2, 5, 6, 7, */ { 7, 12 }, -/* 230: 1, 2, 5, 6, 7, */ { 5, 42 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 3, 15 }, -/* 232: 3, 5, 6, 7, */ { 11, 11 }, -/* 233: 0, 3, 5, 6, 7, */ { 6, 38 }, -/* 234: 1, 3, 5, 6, 7, */ { 6, 45 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 4, 5 }, -/* 236: 2, 3, 5, 6, 7, */ { 5, 45 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 3, 19 }, -/* 238: 1, 2, 3, 5, 6, 7, */ { 2, 21 }, -/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 1, 11 }, -/* 240: 4, 5, 6, 7, */ { 8, 5 }, -/* 241: 0, 4, 5, 6, 7, */ { 5, 38 }, -/* 242: 1, 4, 5, 6, 7, */ { 5, 43 }, -/* 243: 0, 1, 4, 5, 6, 7, */ { 2, 18 }, -/* 244: 2, 4, 5, 6, 7, */ { 5, 46 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 20 }, -/* 246: 1, 2, 4, 5, 6, 7, */ { 2, 22 }, -/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 1, 12 }, -/* 248: 3, 4, 5, 6, 7, */ { 5, 47 }, -/* 249: 0, 3, 4, 5, 6, 7, */ { 2, 20 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 23 }, -/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 13 }, -/* 252: 2, 3, 4, 5, 6, 7, */ { 2, 23 }, -/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 1, 14 }, -/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 1, 15 }, -/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { 0, -1 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling1[16][3] = { -/* 1: 0, */ { 0, 8, 3 }, -/* 2: 1, */ { 0, 1, 9 }, -/* 4: 2, */ { 1, 2, 10 }, -/* 8: 3, */ { 3, 11, 2 }, -/* 16: 4, */ { 4, 7, 8 }, -/* 32: 5, */ { 9, 5, 4 }, -/* 64: 6, */ { 10, 6, 5 }, -/* 128: 7, */ { 7, 6, 11 }, -/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6 }, -/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6 }, -/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5 }, -/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7 }, -/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11 }, -/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2 }, -/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1 }, -/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling2[24][6] = { -/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1 }, -/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0 }, -/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4 }, -/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9 }, -/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0 }, -/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3 }, -/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1 }, -/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7 }, -/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9 }, -/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6 }, -/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10 }, -/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11 }, -/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5 }, -/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4 }, -/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8 }, -/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7 }, -/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2 }, -/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6 }, -/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10 }, -/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5 }, -/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2 }, -/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3 }, -/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11 }, -/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8 } -}; -//_____________________________________________________________________________ - -//_____________________________________________________________________________ -/** - * \brief test table for case 3 - * One face to test - * When the test on the specified face is positive : 4 first triangles - * When the test on the specified face is negative : 2 last triangles - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test3[24] = { -/* 5: 0, 2, */ 5, -/* 33: 0, 5, */ 1, -/* 129: 0, 7, */ 4, -/* 10: 1, 3, */ 5, -/* 18: 1, 4, */ 1, -/* 66: 1, 6, */ 2, -/* 36: 2, 5, */ 2, -/* 132: 2, 7, */ 3, -/* 24: 3, 4, */ 4, -/* 72: 3, 6, */ 3, -/* 80: 4, 6, */ 6, -/* 160: 5, 7, */ 6, -/* 95: 0, 1, 2, 3, 4, 6, */ -6, -/* 175: 0, 1, 2, 3, 5, 7, */ -6, -/* 183: 0, 1, 2, 4, 5, 7, */ -3, -/* 231: 0, 1, 2, 5, 6, 7, */ -4, -/* 123: 0, 1, 3, 4, 5, 6, */ -3, -/* 219: 0, 1, 3, 4, 6, 7, */ -2, -/* 189: 0, 2, 3, 4, 5, 7, */ -2, -/* 237: 0, 2, 3, 5, 6, 7, */ -1, -/* 245: 0, 2, 4, 5, 6, 7, */ -5, -/* 126: 1, 2, 3, 4, 5, 6, */ -4, -/* 222: 1, 2, 3, 4, 6, 7, */ -1, -/* 250: 1, 3, 4, 5, 6, 7, */ -5 -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 3.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling3_1[24][6] = { -/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10 }, -/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3 }, -/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6 }, -/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11 }, -/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7 }, -/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6 }, -/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4 }, -/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7 }, -/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2 }, -/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5 }, -/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8 }, -/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 5, 9, 4, 11, 6, 7 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 6, 10, 5, 8, 7, 4 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 11, 3, 2, 5, 6, 10 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 7, 4, 8, 2, 11, 3 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 2, 1, 10, 7, 11, 6 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 10, 2, 1, 4, 5, 9 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 1, 0, 9, 6, 10, 5 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 9, 1, 0, 7, 4, 8 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 0, 9, 1, 11, 3, 2 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 8, 0, 3, 6, 7, 11 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 4, 5, 9, 3, 8, 0 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 3, 8, 0, 10, 2, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 3.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling3_2[24][12] = { -/* 5: 0, 2, */ { 10, 3, 2, 10, 8, 3, 10, 1, 0, 8, 10, 0 }, -/* 33: 0, 5, */ { 3, 4, 8, 3, 5, 4, 3, 0, 9, 5, 3, 9 }, -/* 129: 0, 7, */ { 6, 8, 7, 6, 0, 8, 6, 11, 3, 0, 6, 3 }, -/* 10: 1, 3, */ { 11, 0, 3, 11, 9, 0, 11, 2, 1, 9, 11, 1 }, -/* 18: 1, 4, */ { 7, 9, 4, 7, 1, 9, 7, 8, 0, 1, 7, 0 }, -/* 66: 1, 6, */ { 6, 1, 10, 6, 0, 1, 9, 0, 6, 9, 6, 5 }, -/* 36: 2, 5, */ { 4, 10, 5, 4, 2, 10, 4, 9, 1, 2, 4, 1 }, -/* 132: 2, 7, */ { 7, 2, 11, 7, 1, 2, 7, 6, 10, 1, 7, 10 }, -/* 24: 3, 4, */ { 2, 7, 11, 2, 4, 7, 2, 3, 8, 4, 2, 8 }, -/* 72: 3, 6, */ { 5, 11, 6, 5, 3, 11, 5, 10, 2, 3, 5, 2 }, -/* 80: 4, 6, */ { 8, 6, 7, 8, 10, 6, 8, 4, 5, 10, 8, 5 }, -/* 160: 5, 7, */ { 11, 5, 6, 11, 9, 5, 11, 7, 4, 9, 11, 4 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 11, 5, 9, 11, 4, 7, 11, 4, 11, 9 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 8, 6, 10, 8, 5, 4, 8, 5, 8, 10 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 5, 11, 3, 5, 2, 10, 5, 2, 5, 3 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 2, 7, 4, 2, 8, 3, 2, 8, 2, 4 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 7, 2, 1, 7, 10, 6, 7, 10, 7, 1 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 4, 10, 2, 4, 1, 9, 4, 1, 4, 2 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 6, 1, 0, 6, 6, 0, 9, 5, 6, 9 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 7, 9, 1, 7, 0, 8, 7, 0, 7, 1 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 11, 0, 9, 11, 1, 2, 11, 1, 11, 9 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 6, 8, 0, 6, 3, 11, 6, 3, 6, 0 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 3, 4, 5, 3, 9, 0, 3, 9, 3, 5 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 10, 3, 8, 10, 0, 1, 10, 0, 10, 8 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 4 - * Interior to test - * When the test on the interior is negative : 2 first triangles - * When the test on the interior is positive : 6 last triangles - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test4[8] = { -/* 65: 0, 6, */ 7, -/* 130: 1, 7, */ 7, -/* 20: 2, 4, */ 7, -/* 40: 3, 5, */ 7, -/* 215: 0, 1, 2, 4, 6, 7, */ -7, -/* 235: 0, 1, 3, 5, 6, 7, */ -7, -/* 125: 0, 2, 3, 4, 5, 6, */ -7, -/* 190: 1, 2, 3, 4, 5, 7, */ -7 -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 4.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling4_1[8][6] = { -/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6 }, -/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6 }, -/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7 }, -/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 4, 5, 9, 11, 3, 2 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 10, 2, 1, 7, 4, 8 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 9, 1, 0, 6, 7, 11 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 3, 8, 0, 6, 10, 5 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 4.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling4_2[8][18] = { -/* 65: 0, 6, */ { 8, 5, 0, 5, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 5 }, -/* 130: 1, 7, */ { 9, 6, 1, 6, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 6 }, -/* 20: 2, 4, */ { 10, 7, 2, 7, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 7 }, -/* 40: 3, 5, */ { 11, 4, 3, 4, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 4 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 3, 4, 11, 5, 11, 4, 11, 5, 2, 9, 2, 5, 2, 9, 3, 4, 3, 9 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 2, 7, 10, 4, 10, 7, 10, 4, 1, 8, 1, 4, 1, 8, 2, 7, 2, 8 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 1, 6, 9, 7, 9, 6, 9, 7, 0, 11, 0, 7, 0, 11, 1, 6, 1, 11 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 5, 8, 6, 8, 5, 8, 6, 3, 10, 3, 6, 3, 10, 0, 5, 0, 10 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 5 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling5[48][9] = { -/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8 }, -/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11 }, -/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1 }, -/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5 }, -/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10 }, -/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4 }, -/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0 }, -/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3 }, -/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6 }, -/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9 }, -/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2 }, -/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6 }, -/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7 }, -/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0 }, -/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3 }, -/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7 }, -/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4 }, -/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1 }, -/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2 }, -/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5 }, -/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10 }, -/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9 }, -/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8 }, -/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11 }, -/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10 }, -/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11 }, -/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8 }, -/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9 }, -/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7 }, -/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6 }, -/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5 }, -/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6 }, -/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3 }, -/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1 }, -/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4 }, -/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5 }, -/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2 }, -/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0 }, -/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10 }, -/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4 }, -/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7 }, -/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2 }, -/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0 }, -/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11 }, -/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1 }, -/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3 }, -/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8 }, -/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief test table for case 6 - * 1 face to test + eventually the interior - * When the test on the specified face is positive : 5 first triangles - * When the test on the specified face is negative : - * - if the test on the interior is negative : 3 middle triangles - * - if the test on the interior is positive : 8 last triangles - * The support edge for the interior test is marked as the 3rd column. - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test6[48][3] = { -/* 67: 0, 1, 6, */ { 2, 7, 10 }, -/* 131: 0, 1, 7, */ { 4, 7, 11 }, -/* 21: 0, 2, 4, */ { 5, 7, 1 }, -/* 69: 0, 2, 6, */ { 5, 7, 3 }, -/* 41: 0, 3, 5, */ { 1, 7, 9 }, -/* 73: 0, 3, 6, */ { 3, 7, 10 }, -/* 81: 0, 4, 6, */ { 6, 7, 5 }, -/* 97: 0, 5, 6, */ { 1, 7, 8 }, -/* 193: 0, 6, 7, */ { 4, 7, 8 }, -/* 22: 1, 2, 4, */ { 1, 7, 8 }, -/* 134: 1, 2, 7, */ { 3, 7, 11 }, -/* 42: 1, 3, 5, */ { 5, 7, 2 }, -/* 138: 1, 3, 7, */ { 5, 7, 0 }, -/* 146: 1, 4, 7, */ { 1, 7, 9 }, -/* 162: 1, 5, 7, */ { 6, 7, 6 }, -/* 194: 1, 6, 7, */ { 2, 7, 9 }, -/* 28: 2, 3, 4, */ { 4, 7, 8 }, -/* 44: 2, 3, 5, */ { 2, 7, 9 }, -/* 52: 2, 4, 5, */ { 2, 7, 10 }, -/* 84: 2, 4, 6, */ { 6, 7, 7 }, -/* 148: 2, 4, 7, */ { 3, 7, 10 }, -/* 56: 3, 4, 5, */ { 4, 7, 11 }, -/* 104: 3, 5, 6, */ { 3, 7, 11 }, -/* 168: 3, 5, 7, */ { 6, 7, 4 }, -/* 87: 0, 1, 2, 4, 6, */ { -6, -7, 4 }, -/* 151: 0, 1, 2, 4, 7, */ { -3, -7, 11 }, -/* 199: 0, 1, 2, 6, 7, */ { -4, -7, 11 }, -/* 107: 0, 1, 3, 5, 6, */ { -3, -7, 10 }, -/* 171: 0, 1, 3, 5, 7, */ { -6, -7, 7 }, -/* 203: 0, 1, 3, 6, 7, */ { -2, -7, 10 }, -/* 211: 0, 1, 4, 6, 7, */ { -2, -7, 9 }, -/* 227: 0, 1, 5, 6, 7, */ { -4, -7, 8 }, -/* 61: 0, 2, 3, 4, 5, */ { -2, -7, 9 }, -/* 93: 0, 2, 3, 4, 6, */ { -6, -7, 6 }, -/* 109: 0, 2, 3, 5, 6, */ { -1, -7, 9 }, -/* 117: 0, 2, 4, 5, 6, */ { -5, -7, 0 }, -/* 213: 0, 2, 4, 6, 7, */ { -5, -7, 2 }, -/* 121: 0, 3, 4, 5, 6, */ { -3, -7, 11 }, -/* 233: 0, 3, 5, 6, 7, */ { -1, -7, 8 }, -/* 62: 1, 2, 3, 4, 5, */ { -4, -7, 8 }, -/* 158: 1, 2, 3, 4, 7, */ { -1, -7, 8 }, -/* 174: 1, 2, 3, 5, 7, */ { -6, -7, 5 }, -/* 182: 1, 2, 4, 5, 7, */ { -3, -7, 10 }, -/* 214: 1, 2, 4, 6, 7, */ { -1, -7, 9 }, -/* 186: 1, 3, 4, 5, 7, */ { -5, -7, 3 }, -/* 234: 1, 3, 5, 6, 7, */ { -5, -7, 1 }, -/* 124: 2, 3, 4, 5, 6, */ { -4, -7, 11 }, -/* 188: 2, 3, 4, 5, 7, */ { -2, -7, 10 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 6.1.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling6_1_1[48][9] = { -/* 67: 0, 1, 6, */ { 6, 5, 10, 3, 1, 8, 9, 8, 1 }, -/* 131: 0, 1, 7, */ { 11, 7, 6, 9, 3, 1, 3, 9, 8 }, -/* 21: 0, 2, 4, */ { 1, 2, 10, 7, 0, 4, 0, 7, 3 }, -/* 69: 0, 2, 6, */ { 3, 0, 8, 5, 2, 6, 2, 5, 1 }, -/* 41: 0, 3, 5, */ { 5, 4, 9, 2, 0, 11, 8, 11, 0 }, -/* 73: 0, 3, 6, */ { 10, 6, 5, 8, 2, 0, 2, 8, 11 }, -/* 81: 0, 4, 6, */ { 10, 6, 5, 0, 4, 3, 7, 3, 4 }, -/* 97: 0, 5, 6, */ { 3, 0, 8, 6, 4, 10, 9, 10, 4 }, -/* 193: 0, 6, 7, */ { 8, 3, 0, 10, 7, 5, 7, 10, 11 }, -/* 22: 1, 2, 4, */ { 8, 4, 7, 10, 0, 2, 0, 10, 9 }, -/* 134: 1, 2, 7, */ { 7, 6, 11, 0, 2, 9, 10, 9, 2 }, -/* 42: 1, 3, 5, */ { 2, 3, 11, 4, 1, 5, 1, 4, 0 }, -/* 138: 1, 3, 7, */ { 0, 1, 9, 6, 3, 7, 3, 6, 2 }, -/* 146: 1, 4, 7, */ { 9, 0, 1, 11, 4, 6, 4, 11, 8 }, -/* 162: 1, 5, 7, */ { 11, 7, 6, 1, 5, 0, 4, 0, 5 }, -/* 194: 1, 6, 7, */ { 0, 1, 9, 7, 5, 11, 10, 11, 5 }, -/* 28: 2, 3, 4, */ { 4, 7, 8, 1, 3, 10, 11, 10, 3 }, -/* 44: 2, 3, 5, */ { 9, 5, 4, 11, 1, 3, 1, 11, 10 }, -/* 52: 2, 4, 5, */ { 10, 1, 2, 8, 5, 7, 5, 8, 9 }, -/* 84: 2, 4, 6, */ { 8, 4, 7, 2, 6, 1, 5, 1, 6 }, -/* 148: 2, 4, 7, */ { 1, 2, 10, 4, 6, 8, 11, 8, 6 }, -/* 56: 3, 4, 5, */ { 2, 3, 11, 5, 7, 9, 8, 9, 7 }, -/* 104: 3, 5, 6, */ { 11, 2, 3, 9, 6, 4, 6, 9, 10 }, -/* 168: 3, 5, 7, */ { 9, 5, 4, 3, 7, 2, 6, 2, 7 }, -/* 87: 0, 1, 2, 4, 6, */ { 4, 5, 9, 2, 7, 3, 7, 2, 6 }, -/* 151: 0, 1, 2, 4, 7, */ { 3, 2, 11, 4, 6, 9, 10, 9, 6 }, -/* 199: 0, 1, 2, 6, 7, */ { 11, 3, 2, 9, 7, 5, 7, 9, 8 }, -/* 107: 0, 1, 3, 5, 6, */ { 10, 2, 1, 8, 6, 4, 6, 8, 11 }, -/* 171: 0, 1, 3, 5, 7, */ { 7, 4, 8, 1, 6, 2, 6, 1, 5 }, -/* 203: 0, 1, 3, 6, 7, */ { 2, 1, 10, 7, 5, 8, 9, 8, 5 }, -/* 211: 0, 1, 4, 6, 7, */ { 4, 5, 9, 3, 1, 11, 10, 11, 1 }, -/* 227: 0, 1, 5, 6, 7, */ { 8, 7, 4, 10, 3, 1, 3, 10, 11 }, -/* 61: 0, 2, 3, 4, 5, */ { 9, 1, 0, 11, 5, 7, 5, 11, 10 }, -/* 93: 0, 2, 3, 4, 6, */ { 6, 7, 11, 0, 5, 1, 5, 0, 4 }, -/* 109: 0, 2, 3, 5, 6, */ { 1, 0, 9, 6, 4, 11, 8, 11, 4 }, -/* 117: 0, 2, 4, 5, 6, */ { 9, 1, 0, 7, 3, 6, 2, 6, 3 }, -/* 213: 0, 2, 4, 6, 7, */ { 11, 3, 2, 5, 1, 4, 0, 4, 1 }, -/* 121: 0, 3, 4, 5, 6, */ { 11, 6, 7, 9, 2, 0, 2, 9, 10 }, -/* 233: 0, 3, 5, 6, 7, */ { 7, 4, 8, 2, 0, 10, 9, 10, 0 }, -/* 62: 1, 2, 3, 4, 5, */ { 0, 3, 8, 5, 7, 10, 11, 10, 7 }, -/* 158: 1, 2, 3, 4, 7, */ { 8, 0, 3, 10, 4, 6, 4, 10, 9 }, -/* 174: 1, 2, 3, 5, 7, */ { 5, 6, 10, 3, 4, 0, 4, 3, 7 }, -/* 182: 1, 2, 4, 5, 7, */ { 5, 6, 10, 0, 2, 8, 11, 8, 2 }, -/* 214: 1, 2, 4, 6, 7, */ { 9, 4, 5, 11, 0, 2, 0, 11, 8 }, -/* 186: 1, 3, 4, 5, 7, */ { 8, 0, 3, 6, 2, 5, 1, 5, 2 }, -/* 234: 1, 3, 5, 6, 7, */ { 10, 2, 1, 4, 0, 7, 3, 7, 0 }, -/* 124: 2, 3, 4, 5, 6, */ { 6, 7, 11, 1, 3, 9, 8, 9, 3 }, -/* 188: 2, 3, 4, 5, 7, */ { 10, 5, 6, 8, 1, 3, 1, 8, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 6.1.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling6_1_2[48][27] = { - /* 67: 0, 1, 6, */ { 1, 12, 3, 12, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 12, 12, 9, 8, 1, 9, 12, 12, 5, 10 }, - /* 131: 0, 1, 7, */ { 1, 12, 3, 1, 11, 12, 11, 1, 6, 9, 6, 1, 6, 9, 7, 12, 7, 9, 9, 8, 12, 12, 8, 3, 11, 7, 12 }, - /* 21: 0, 2, 4, */ { 4, 12, 0, 4, 1, 12, 1, 4, 10, 7, 10, 4, 10, 7, 2, 12, 2, 7, 7, 3, 12, 12, 3, 0, 1, 2, 12 }, - /* 69: 0, 2, 6, */ { 6, 12, 2, 6, 3, 12, 3, 6, 8, 5, 8, 6, 8, 5, 0, 12, 0, 5, 5, 1, 12, 12, 1, 2, 3, 0, 12 }, - /* 41: 0, 3, 5, */ { 0, 12, 2, 12, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 12, 12, 8, 11, 0, 8, 12, 12, 4, 9 }, - /* 73: 0, 3, 6, */ { 0, 12, 2, 0, 10, 12, 10, 0, 5, 8, 5, 0, 5, 8, 6, 12, 6, 8, 8, 11, 12, 12, 11, 2, 10, 6, 12 }, - /* 81: 0, 4, 6, */ { 4, 12, 0, 12, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 12, 12, 7, 3, 4, 7, 12, 12, 6, 5 }, - /* 97: 0, 5, 6, */ { 4, 12, 6, 12, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 12, 12, 9, 10, 4, 9, 12, 12, 0, 8 }, - /* 193: 0, 6, 7, */ { 5, 12, 7, 5, 8, 12, 8, 5, 0, 10, 0, 5, 0, 10, 3, 12, 3, 10, 10, 11, 12, 12, 11, 7, 8, 3, 12 }, - /* 22: 1, 2, 4, */ { 2, 12, 0, 2, 8, 12, 8, 2, 7, 10, 7, 2, 7, 10, 4, 12, 4, 10, 10, 9, 12, 12, 9, 0, 8, 4, 12 }, - /* 134: 1, 2, 7, */ { 2, 12, 0, 12, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 12, 12, 10, 9, 2, 10, 12, 12, 6, 11 }, - /* 42: 1, 3, 5, */ { 5, 12, 1, 5, 2, 12, 2, 5, 11, 4, 11, 5, 11, 4, 3, 12, 3, 4, 4, 0, 12, 12, 0, 1, 2, 3, 12 }, - /* 138: 1, 3, 7, */ { 7, 12, 3, 7, 0, 12, 0, 7, 9, 6, 9, 7, 9, 6, 1, 12, 1, 6, 6, 2, 12, 12, 2, 3, 0, 1, 12 }, - /* 146: 1, 4, 7, */ { 6, 12, 4, 6, 9, 12, 9, 6, 1, 11, 1, 6, 1, 11, 0, 12, 0, 11, 11, 8, 12, 12, 8, 4, 9, 0, 12 }, - /* 162: 1, 5, 7, */ { 5, 12, 1, 12, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 12, 12, 4, 0, 5, 4, 12, 12, 7, 6 }, - /* 194: 1, 6, 7, */ { 5, 12, 7, 12, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 12, 12, 10, 11, 5, 10, 12, 12, 1, 9 }, - /* 28: 2, 3, 4, */ { 3, 12, 1, 12, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 12, 12, 11, 10, 3, 11, 12, 12, 7, 8 }, - /* 44: 2, 3, 5, */ { 3, 12, 1, 3, 9, 12, 9, 3, 4, 11, 4, 3, 4, 11, 5, 12, 5, 11, 11, 10, 12, 12, 10, 1, 9, 5, 12 }, - /* 52: 2, 4, 5, */ { 7, 12, 5, 7, 10, 12, 10, 7, 2, 8, 2, 7, 2, 8, 1, 12, 1, 8, 8, 9, 12, 12, 9, 5, 10, 1, 12 }, - /* 84: 2, 4, 6, */ { 6, 12, 2, 12, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 12, 12, 5, 1, 6, 5, 12, 12, 4, 7 }, - /* 148: 2, 4, 7, */ { 6, 12, 4, 12, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 12, 12, 11, 8, 6, 11, 12, 12, 2, 10 }, - /* 56: 3, 4, 5, */ { 7, 12, 5, 12, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 12, 12, 8, 9, 7, 8, 12, 12, 3, 11 }, - /* 104: 3, 5, 6, */ { 4, 12, 6, 4, 11, 12, 11, 4, 3, 9, 3, 4, 3, 9, 2, 12, 2, 9, 9, 10, 12, 12, 10, 6, 11, 2, 12 }, - /* 168: 3, 5, 7, */ { 7, 12, 3, 12, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 12, 12, 6, 2, 7, 6, 12, 12, 5, 4 }, - /* 87: 0, 1, 2, 4, 6, */ { 3, 12, 7, 3, 4, 12, 4, 3, 9, 2, 9, 3, 9, 2, 5, 12, 5, 2, 2, 6, 12, 12, 6, 7, 4, 5, 12 }, - /* 151: 0, 1, 2, 4, 7, */ { 6, 12, 4, 12, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 12, 12, 10, 9, 6, 10, 12, 12, 2, 11 }, - /* 199: 0, 1, 2, 6, 7, */ { 5, 12, 7, 5, 11, 12, 11, 5, 2, 9, 2, 5, 2, 9, 3, 12, 3, 9, 9, 8, 12, 12, 8, 7, 11, 3, 12 }, - /* 107: 0, 1, 3, 5, 6, */ { 4, 12, 6, 4, 10, 12, 10, 4, 1, 8, 1, 4, 1, 8, 2, 12, 2, 8, 8, 11, 12, 12, 11, 6, 10, 2, 12 }, - /* 171: 0, 1, 3, 5, 7, */ { 2, 12, 6, 2, 7, 12, 7, 2, 8, 1, 8, 2, 8, 1, 4, 12, 4, 1, 1, 5, 12, 12, 5, 6, 7, 4, 12 }, - /* 203: 0, 1, 3, 6, 7, */ { 5, 12, 7, 12, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 12, 12, 9, 8, 5, 9, 12, 12, 1, 10 }, - /* 211: 0, 1, 4, 6, 7, */ { 1, 12, 3, 12, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 12, 12, 10, 11, 1, 10, 12, 12, 5, 9 }, - /* 227: 0, 1, 5, 6, 7, */ { 1, 12, 3, 1, 8, 12, 8, 1, 4, 10, 4, 1, 4, 10, 7, 12, 7, 10, 10, 11, 12, 12, 11, 3, 8, 7, 12 }, - /* 61: 0, 2, 3, 4, 5, */ { 7, 12, 5, 7, 9, 12, 9, 7, 0, 11, 0, 7, 0, 11, 1, 12, 1, 11, 11, 10, 12, 12, 10, 5, 9, 1, 12 }, - /* 93: 0, 2, 3, 4, 6, */ { 1, 12, 5, 1, 6, 12, 6, 1, 11, 0, 11, 1, 11, 0, 7, 12, 7, 0, 0, 4, 12, 12, 4, 5, 6, 7, 12 }, - /* 109: 0, 2, 3, 5, 6, */ { 4, 12, 6, 12, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 12, 12, 8, 11, 4, 8, 12, 12, 0, 9 }, - /* 117: 0, 2, 4, 5, 6, */ { 3, 12, 7, 12, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 12, 12, 2, 6, 3, 2, 12, 12, 1, 0 }, - /* 213: 0, 2, 4, 6, 7, */ { 1, 12, 5, 12, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 12, 12, 0, 4, 1, 0, 12, 12, 3, 2 }, - /* 121: 0, 3, 4, 5, 6, */ { 0, 12, 2, 0, 11, 12, 11, 0, 7, 9, 7, 0, 7, 9, 6, 12, 6, 9, 9, 10, 12, 12, 10, 2, 11, 6, 12 }, - /* 233: 0, 3, 5, 6, 7, */ { 0, 12, 2, 12, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 12, 12, 9, 10, 0, 9, 12, 12, 4, 8 }, - /* 62: 1, 2, 3, 4, 5, */ { 7, 12, 5, 12, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 12, 12, 11, 10, 7, 11, 12, 12, 3, 8 }, - /* 158: 1, 2, 3, 4, 7, */ { 6, 12, 4, 6, 8, 12, 8, 6, 3, 10, 3, 6, 3, 10, 0, 12, 0, 10, 10, 9, 12, 12, 9, 4, 8, 0, 12 }, - /* 174: 1, 2, 3, 5, 7, */ { 0, 12, 4, 0, 5, 12, 5, 0, 10, 3, 10, 0, 10, 3, 6, 12, 6, 3, 3, 7, 12, 12, 7, 4, 5, 6, 12 }, - /* 182: 1, 2, 4, 5, 7, */ { 2, 12, 0, 12, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 12, 12, 11, 8, 2, 11, 12, 12, 6, 10 }, - /* 214: 1, 2, 4, 6, 7, */ { 2, 12, 0, 2, 9, 12, 9, 2, 5, 11, 5, 2, 5, 11, 4, 12, 4, 11, 11, 8, 12, 12, 8, 0, 9, 4, 12 }, - /* 186: 1, 3, 4, 5, 7, */ { 2, 12, 6, 12, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 12, 12, 1, 5, 2, 1, 12, 12, 0, 3 }, - /* 234: 1, 3, 5, 6, 7, */ { 0, 12, 4, 12, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 12, 12, 3, 7, 0, 3, 12, 12, 2, 1 }, - /* 124: 2, 3, 4, 5, 6, */ { 3, 12, 1, 12, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 12, 12, 8, 9, 3, 8, 12, 12, 7, 11 }, - /* 188: 2, 3, 4, 5, 7, */ { 3, 12, 1, 3, 10, 12, 10, 3, 6, 8, 6, 3, 6, 8, 5, 12, 5, 8, 8, 9, 12, 12, 9, 1, 10, 5, 12 }, -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 6.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling6_2[48][15] = { -/* 67: 0, 1, 6, */ { 1, 10, 3, 6, 3, 10, 3, 6, 8, 5, 8, 6, 8, 5, 9 }, -/* 131: 0, 1, 7, */ { 1, 11, 3, 11, 1, 6, 9, 6, 1, 6, 9, 7, 8, 7, 9 }, -/* 21: 0, 2, 4, */ { 4, 1, 0, 1, 4, 10, 7, 10, 4, 10, 7, 2, 3, 2, 7 }, -/* 69: 0, 2, 6, */ { 6, 3, 2, 3, 6, 8, 5, 8, 6, 8, 5, 0, 1, 0, 5 }, -/* 41: 0, 3, 5, */ { 0, 9, 2, 5, 2, 9, 2, 5, 11, 4, 11, 5, 11, 4, 8 }, -/* 73: 0, 3, 6, */ { 0, 10, 2, 10, 0, 5, 8, 5, 0, 5, 8, 6, 11, 6, 8 }, -/* 81: 0, 4, 6, */ { 4, 5, 0, 10, 0, 5, 0, 10, 3, 6, 3, 10, 3, 6, 7 }, -/* 97: 0, 5, 6, */ { 4, 8, 6, 3, 6, 8, 6, 3, 10, 0, 10, 3, 10, 0, 9 }, -/* 193: 0, 6, 7, */ { 5, 8, 7, 8, 5, 0, 10, 0, 5, 0, 10, 3, 11, 3, 10 }, -/* 22: 1, 2, 4, */ { 2, 8, 0, 8, 2, 7, 10, 7, 2, 7, 10, 4, 9, 4, 10 }, -/* 134: 1, 2, 7, */ { 2, 11, 0, 7, 0, 11, 0, 7, 9, 6, 9, 7, 9, 6, 10 }, -/* 42: 1, 3, 5, */ { 5, 2, 1, 2, 5, 11, 4, 11, 5, 11, 4, 3, 0, 3, 4 }, -/* 138: 1, 3, 7, */ { 7, 0, 3, 0, 7, 9, 6, 9, 7, 9, 6, 1, 2, 1, 6 }, -/* 146: 1, 4, 7, */ { 6, 9, 4, 9, 6, 1, 11, 1, 6, 1, 11, 0, 8, 0, 11 }, -/* 162: 1, 5, 7, */ { 5, 6, 1, 11, 1, 6, 1, 11, 0, 7, 0, 11, 0, 7, 4 }, -/* 194: 1, 6, 7, */ { 5, 9, 7, 0, 7, 9, 7, 0, 11, 1, 11, 0, 11, 1, 10 }, -/* 28: 2, 3, 4, */ { 3, 8, 1, 4, 1, 8, 1, 4, 10, 7, 10, 4, 10, 7, 11 }, -/* 44: 2, 3, 5, */ { 3, 9, 1, 9, 3, 4, 11, 4, 3, 4, 11, 5, 10, 5, 11 }, -/* 52: 2, 4, 5, */ { 7, 10, 5, 10, 7, 2, 8, 2, 7, 2, 8, 1, 9, 1, 8 }, -/* 84: 2, 4, 6, */ { 6, 7, 2, 8, 2, 7, 2, 8, 1, 4, 1, 8, 1, 4, 5 }, -/* 148: 2, 4, 7, */ { 6, 10, 4, 1, 4, 10, 4, 1, 8, 2, 8, 1, 8, 2, 11 }, -/* 56: 3, 4, 5, */ { 7, 11, 5, 2, 5, 11, 5, 2, 9, 3, 9, 2, 9, 3, 8 }, -/* 104: 3, 5, 6, */ { 4, 11, 6, 11, 4, 3, 9, 3, 4, 3, 9, 2, 10, 2, 9 }, -/* 168: 3, 5, 7, */ { 7, 4, 3, 9, 3, 4, 3, 9, 2, 5, 2, 9, 2, 5, 6 }, -/* 87: 0, 1, 2, 4, 6, */ { 3, 4, 7, 4, 3, 9, 2, 9, 3, 9, 2, 5, 6, 5, 2 }, -/* 151: 0, 1, 2, 4, 7, */ { 6, 11, 4, 3, 4, 11, 4, 3, 9, 2, 9, 3, 9, 2, 10 }, -/* 199: 0, 1, 2, 6, 7, */ { 5, 11, 7, 11, 5, 2, 9, 2, 5, 2, 9, 3, 8, 3, 9 }, -/* 107: 0, 1, 3, 5, 6, */ { 4, 10, 6, 10, 4, 1, 8, 1, 4, 1, 8, 2, 11, 2, 8 }, -/* 171: 0, 1, 3, 5, 7, */ { 2, 7, 6, 7, 2, 8, 1, 8, 2, 8, 1, 4, 5, 4, 1 }, -/* 203: 0, 1, 3, 6, 7, */ { 5, 10, 7, 2, 7, 10, 7, 2, 8, 1, 8, 2, 8, 1, 9 }, -/* 211: 0, 1, 4, 6, 7, */ { 1, 9, 3, 4, 3, 9, 3, 4, 11, 5, 11, 4, 11, 5, 10 }, -/* 227: 0, 1, 5, 6, 7, */ { 1, 8, 3, 8, 1, 4, 10, 4, 1, 4, 10, 7, 11, 7, 10 }, -/* 61: 0, 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 0, 11, 0, 7, 0, 11, 1, 10, 1, 11 }, -/* 93: 0, 2, 3, 4, 6, */ { 1, 6, 5, 6, 1, 11, 0, 11, 1, 11, 0, 7, 4, 7, 0 }, -/* 109: 0, 2, 3, 5, 6, */ { 4, 9, 6, 1, 6, 9, 6, 1, 11, 0, 11, 1, 11, 0, 8 }, -/* 117: 0, 2, 4, 5, 6, */ { 3, 0, 7, 9, 7, 0, 7, 9, 6, 1, 6, 9, 6, 1, 2 }, -/* 213: 0, 2, 4, 6, 7, */ { 1, 2, 5, 11, 5, 2, 5, 11, 4, 3, 4, 11, 4, 3, 0 }, -/* 121: 0, 3, 4, 5, 6, */ { 0, 11, 2, 11, 0, 7, 9, 7, 0, 7, 9, 6, 10, 6, 9 }, -/* 233: 0, 3, 5, 6, 7, */ { 0, 8, 2, 7, 2, 8, 2, 7, 10, 4, 10, 7, 10, 4, 9 }, -/* 62: 1, 2, 3, 4, 5, */ { 7, 8, 5, 0, 5, 8, 5, 0, 10, 3, 10, 0, 10, 3, 11 }, -/* 158: 1, 2, 3, 4, 7, */ { 6, 8, 4, 8, 6, 3, 10, 3, 6, 3, 10, 0, 9, 0, 10 }, -/* 174: 1, 2, 3, 5, 7, */ { 0, 5, 4, 5, 0, 10, 3, 10, 0, 10, 3, 6, 7, 6, 3 }, -/* 182: 1, 2, 4, 5, 7, */ { 2, 10, 0, 5, 0, 10, 0, 5, 8, 6, 8, 5, 8, 6, 11 }, -/* 214: 1, 2, 4, 6, 7, */ { 2, 9, 0, 9, 2, 5, 11, 5, 2, 5, 11, 4, 8, 4, 11 }, -/* 186: 1, 3, 4, 5, 7, */ { 2, 3, 6, 8, 6, 3, 6, 8, 5, 0, 5, 8, 5, 0, 1 }, -/* 234: 1, 3, 5, 6, 7, */ { 0, 1, 4, 10, 4, 1, 4, 10, 7, 2, 7, 10, 7, 2, 3 }, -/* 124: 2, 3, 4, 5, 6, */ { 3, 11, 1, 6, 1, 11, 1, 6, 9, 7, 9, 6, 9, 7, 8 }, -/* 188: 2, 3, 4, 5, 7, */ { 3, 10, 1, 10, 3, 6, 8, 6, 3, 6, 8, 5, 9, 5, 8 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 7 - * 3 faces to test + eventually the interior - * When the tests on the 3 specified faces are positive : - * - if the test on the interior is positive : 5 first triangles - * - if the test on the interior is negative : 9 next triangles - * When the tests on the first and the second specified faces are positive : 9 next triangles - * When the tests on the first and the third specified faces are positive : 9 next triangles - * When the tests on the second and the third specified faces are positive : 9 next triangles - * When the test on the first specified face is positive : 5 next triangles - * When the test on the second specified face is positive : 5 next triangles - * When the test on the third specified face is positive : 5 next triangles - * When the tests on the 3 specified faces are negative : 3 last triangles - * The support edge for the interior test is marked as the 5th column. - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test7[16][5] = { -/* 37: 0, 2, 5, */ { 1, 2, 5, 7, 1 }, -/* 133: 0, 2, 7, */ { 3, 4, 5, 7, 3 }, -/* 161: 0, 5, 7, */ { 4, 1, 6, 7, 4 }, -/* 26: 1, 3, 4, */ { 4, 1, 5, 7, 0 }, -/* 74: 1, 3, 6, */ { 2, 3, 5, 7, 2 }, -/* 82: 1, 4, 6, */ { 1, 2, 6, 7, 5 }, -/* 164: 2, 5, 7, */ { 2, 3, 6, 7, 6 }, -/* 88: 3, 4, 6, */ { 3, 4, 6, 7, 7 }, -/* 167: 0, 1, 2, 5, 7, */ { -3, -4, -6, -7, 7 }, -/* 91: 0, 1, 3, 4, 6, */ { -2, -3, -6, -7, 6 }, -/* 173: 0, 2, 3, 5, 7, */ { -1, -2, -6, -7, 5 }, -/* 181: 0, 2, 4, 5, 7, */ { -2, -3, -5, -7, 2 }, -/* 229: 0, 2, 5, 6, 7, */ { -4, -1, -5, -7, 0 }, -/* 94: 1, 2, 3, 4, 6, */ { -4, -1, -6, -7, 4 }, -/* 122: 1, 3, 4, 5, 6, */ { -3, -4, -5, -7, 3 }, -/* 218: 1, 3, 4, 6, 7, */ { -1, -2, -5, -7, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_1[16][9] = { -/* 37: 0, 2, 5, */ { 9, 5, 4, 10, 1, 2, 8, 3, 0 }, -/* 133: 0, 2, 7, */ { 11, 7, 6, 8, 3, 0, 10, 1, 2 }, -/* 161: 0, 5, 7, */ { 3, 0, 8, 5, 4, 9, 7, 6, 11 }, -/* 26: 1, 3, 4, */ { 8, 4, 7, 9, 0, 1, 11, 2, 3 }, -/* 74: 1, 3, 6, */ { 10, 6, 5, 11, 2, 3, 9, 0, 1 }, -/* 82: 1, 4, 6, */ { 0, 1, 9, 6, 5, 10, 4, 7, 8 }, -/* 164: 2, 5, 7, */ { 1, 2, 10, 7, 6, 11, 5, 4, 9 }, -/* 88: 3, 4, 6, */ { 2, 3, 11, 4, 7, 8, 6, 5, 10 }, -/* 167: 0, 1, 2, 5, 7, */ { 11, 3, 2, 8, 7, 4, 10, 5, 6 }, -/* 91: 0, 1, 3, 4, 6, */ { 10, 2, 1, 11, 6, 7, 9, 4, 5 }, -/* 173: 0, 2, 3, 5, 7, */ { 9, 1, 0, 10, 5, 6, 8, 7, 4 }, -/* 181: 0, 2, 4, 5, 7, */ { 5, 6, 10, 3, 2, 11, 1, 0, 9 }, -/* 229: 0, 2, 5, 6, 7, */ { 7, 4, 8, 1, 0, 9, 3, 2, 11 }, -/* 94: 1, 2, 3, 4, 6, */ { 8, 0, 3, 9, 4, 5, 11, 6, 7 }, -/* 122: 1, 3, 4, 5, 6, */ { 6, 7, 11, 0, 3, 8, 2, 1, 10 }, -/* 218: 1, 3, 4, 6, 7, */ { 4, 5, 9, 2, 1, 10, 0, 3, 8 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_2[16][3][15] = { -/* 37: 0, 2, 5, */ { - /* 1,0 */ { 1, 2, 10, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, - /* 0,1 */ { 3, 0, 8, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, - /* 1,1 */ { 9, 5, 4, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 } -}, -/* 133: 0, 2, 7, */ { - /* 1,0 */ { 3, 0, 8, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, - /* 0,1 */ { 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, - /* 1,1 */ { 11, 7, 6, 2, 8, 3, 8, 2, 10, 8, 10, 0, 1, 0, 10 } -}, -/* 161: 0, 5, 7, */ { - /* 1,0 */ { 9, 5, 4, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, - /* 0,1 */ { 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, - /* 1,1 */ { 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 } -}, -/* 26: 1, 3, 4, */ { - /* 1,0 */ { 0, 1, 9, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, - /* 0,1 */ { 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, - /* 1,1 */ { 8, 4, 7, 3, 9, 0, 9, 3, 11, 9, 11, 1, 2, 1, 11 } -}, -/* 74: 1, 3, 6, */ { - /* 1,0 */ { 2, 3, 11, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, - /* 0,1 */ { 0, 1, 9, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, - /* 1,1 */ { 6, 5, 10, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 } -}, -/* 82: 1, 4, 6, */ { - /* 1,0 */ { 6, 5, 10, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, - /* 0,1 */ { 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, - /* 1,1 */ { 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 } -}, -/* 164: 2, 5, 7, */ { - /* 1,0 */ { 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, - /* 0,1 */ { 9, 5, 4, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, - /* 1,1 */ { 1, 2, 10, 6, 11, 5, 9, 5, 11, 7, 9, 11, 9, 7, 4 } -}, -/* 88: 3, 4, 6, */ { - /* 1,0 */ { 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, - /* 0,1 */ { 6, 5, 10, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, - /* 1,1 */ { 2, 3, 11, 7, 8, 6, 10, 6, 8, 4, 10, 8, 10, 4, 5 } -}, -/* 167: 0, 1, 2, 5, 7, */ { - /* 1,0 */ { 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, - /* 0,1 */ { 10, 5, 6, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, - /* 1,1 */ { 11, 3, 2, 6, 8, 7, 8, 6, 10, 8, 10, 4, 5, 4, 10 } -}, -/* 91: 0, 1, 3, 4, 6, */ { - /* 1,0 */ { 6, 7, 11, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, - /* 0,1 */ { 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, - /* 1,1 */ { 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 } -}, -/* 173: 0, 2, 3, 5, 7, */ { - /* 1,0 */ { 10, 5, 6, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, - /* 0,1 */ { 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, - /* 1,1 */ { 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 } -}, -/* 181: 0, 2, 4, 5, 7, */ { - /* 1,0 */ { 11, 3, 2, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, - /* 0,1 */ { 9, 1, 0, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, - /* 1,1 */ { 10, 5, 6, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 } -}, -/* 229: 0, 2, 5, 6, 7, */ { - /* 1,0 */ { 9, 1, 0, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, - /* 0,1 */ { 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, - /* 1,1 */ { 7, 4, 8, 0, 9, 3, 11, 3, 9, 1, 11, 9, 11, 1, 2 } -}, -/* 94: 1, 2, 3, 4, 6, */ { - /* 1,0 */ { 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, - /* 0,1 */ { 6, 7, 11, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, - /* 1,1 */ { 8, 0, 3, 7, 9, 4, 9, 7, 11, 9, 11, 5, 6, 5, 11 } -}, -/* 122: 1, 3, 4, 5, 6, */ { - /* 1,0 */ { 8, 0, 3, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, - /* 0,1 */ { 10, 2, 1, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, - /* 1,1 */ { 6, 7, 11, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 } -}, -/* 218: 1, 3, 4, 6, 7, */ { - /* 1,0 */ { 10, 2, 1, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, - /* 0,1 */ { 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, - /* 1,1 */ { 4, 5, 9, 1, 10, 0, 8, 0, 10, 2, 8, 10, 8, 2, 3 } } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.3 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_3[16][3][27] = { -/* 37: 0, 2, 5, */ { - /* 1,0 */ { 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, - /* 0,1 */ { 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, - /* 1,1 */ { 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 } -}, -/* 133: 0, 2, 7, */ { - /* 1,0 */ { 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 }, - /* 0,1 */ { 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, - /* 1,1 */ { 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 } -}, -/* 161: 0, 5, 7, */ { - /* 1,0 */ { 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 }, - /* 0,1 */ { 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 }, - /* 1,1 */ { 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 } -}, -/* 26: 1, 3, 4, */ { - /* 1,0 */ { 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 }, - /* 0,1 */ { 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 }, - /* 1,1 */ { 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 } -}, -/* 74: 1, 3, 6, */ { - /* 1,0 */ { 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, - /* 0,1 */ { 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 }, - /* 1,1 */ { 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 } -}, -/* 82: 1, 4, 6, */ { - /* 1,0 */ { 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 }, - /* 0,1 */ { 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 }, - /* 1,1 */ { 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 } -}, -/* 164: 2, 5, 7, */ { - /* 1,0 */ { 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 }, - /* 0,1 */ { 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 }, - /* 1,1 */ { 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 } -}, -/* 88: 3, 4, 6, */ { - /* 1,0 */ { 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 }, - /* 0,1 */ { 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 }, - /* 1,1 */ { 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 } -}, -/* 167: 0, 1, 2, 5, 7, */ { - /* 1,0 */ { 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 }, - /* 0,1 */ { 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 }, - /* 1,1 */ { 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 } -}, -/* 91: 0, 1, 3, 4, 6, */ { - /* 1,0 */ { 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7 }, - /* 0,1 */ { 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 }, - /* 1,1 */ { 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 } -}, -/* 173: 0, 2, 3, 5, 7, */ { - /* 1,0 */ { 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6 }, - /* 0,1 */ { 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 }, - /* 1,1 */ { 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 } -}, -/* 181: 0, 2, 4, 5, 7, */ { - /* 1,0 */ { 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, - /* 0,1 */ { 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 }, - /* 1,1 */ { 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 } -}, -/* 229: 0, 2, 5, 6, 7, */ { - /* 1,0 */ { 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 }, - /* 0,1 */ { 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 }, - /* 1,1 */ { 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 } -}, -/* 94: 1, 2, 3, 4, 6, */ { - /* 1,0 */ { 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 }, - /* 0,1 */ { 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 }, - /* 1,1 */ { 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 } -}, -/* 122: 1, 3, 4, 5, 6, */ { - /* 1,0 */ { 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, - /* 0,1 */ { 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, - /* 1,1 */ { 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 } -}, -/* 218: 1, 3, 4, 6, 7, */ { - /* 1,0 */ { 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 }, - /* 0,1 */ { 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, - /* 1,1 */ { 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 } } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.4.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_4_1[16][15] = { -/* 37: 0, 2, 5, */ { 3, 4, 8, 4, 3, 10, 2, 10, 3, 4, 10, 5, 9, 1, 0 }, -/* 133: 0, 2, 7, */ { 1, 6, 10, 6, 1, 8, 0, 8, 1, 6, 8, 7, 11, 3, 2 }, -/* 161: 0, 5, 7, */ { 11, 3, 6, 9, 6, 3, 6, 9, 5, 0, 9, 3, 7, 4, 8 }, -/* 26: 1, 3, 4, */ { 2, 7, 11, 7, 2, 9, 1, 9, 2, 7, 9, 4, 8, 0, 3 }, -/* 74: 1, 3, 6, */ { 0, 5, 9, 5, 0, 11, 3, 11, 0, 5, 11, 6, 10, 2, 1 }, -/* 82: 1, 4, 6, */ { 8, 0, 7, 10, 7, 0, 7, 10, 6, 1, 10, 0, 4, 5, 9 }, -/* 164: 2, 5, 7, */ { 9, 1, 4, 11, 4, 1, 4, 11, 7, 2, 11, 1, 5, 6, 10 }, -/* 88: 3, 4, 6, */ { 10, 2, 5, 8, 5, 2, 5, 8, 4, 3, 8, 2, 6, 7, 11 }, -/* 167: 0, 1, 2, 5, 7, */ { 5, 2, 10, 2, 5, 8, 4, 8, 5, 2, 8, 3, 11, 7, 6 }, -/* 91: 0, 1, 3, 4, 6, */ { 4, 1, 9, 1, 4, 11, 7, 11, 4, 1, 11, 2, 10, 6, 5 }, -/* 173: 0, 2, 3, 5, 7, */ { 7, 0, 8, 0, 7, 10, 6, 10, 7, 0, 10, 1, 9, 5, 4 }, -/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 0, 11, 0, 5, 0, 11, 3, 6, 11, 5, 1, 2, 10 }, -/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 2, 9, 2, 7, 2, 9, 1, 4, 9, 7, 3, 0, 8 }, -/* 94: 1, 2, 3, 4, 6, */ { 6, 3, 11, 3, 6, 9, 5, 9, 6, 3, 9, 0, 8, 4, 7 }, -/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 1, 8, 1, 6, 1, 8, 0, 7, 8, 6, 2, 3, 11 }, -/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 3, 10, 3, 4, 3, 10, 2, 5, 10, 4, 0, 1, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 7.4.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling7_4_2[16][27] = { -/* 37: 0, 2, 5, */ { 9, 4, 8, 4, 9, 5, 10, 5, 9, 1, 10, 9, 10, 1, 2, 0, 2, 1, 2, 0, 3, 8, 3, 0, 9, 8, 0 }, -/* 133: 0, 2, 7, */ { 11, 6, 10, 6, 11, 7, 8, 7, 11, 3, 8, 11, 8, 3, 0, 2, 0, 3, 0, 2, 1, 10, 1, 2, 11, 10, 2 }, -/* 161: 0, 5, 7, */ { 11, 3, 8, 0, 8, 3, 8, 0, 9, 8, 9, 4, 5, 4, 9, 4, 5, 7, 6, 7, 5, 7, 6, 11, 7, 11, 8 }, -/* 26: 1, 3, 4, */ { 8, 7, 11, 7, 8, 4, 9, 4, 8, 0, 9, 8, 9, 0, 1, 3, 1, 0, 1, 3, 2, 11, 2, 3, 8, 11, 3 }, -/* 74: 1, 3, 6, */ { 10, 5, 9, 5, 10, 6, 11, 6, 10, 2, 11, 10, 11, 2, 3, 1, 3, 2, 3, 1, 0, 9, 0, 1, 10, 9, 1 }, -/* 82: 1, 4, 6, */ { 8, 0, 9, 1, 9, 0, 9, 1, 10, 9, 10, 5, 6, 5, 10, 5, 6, 4, 7, 4, 6, 4, 7, 8, 4, 8, 9 }, -/* 164: 2, 5, 7, */ { 9, 1, 10, 2, 10, 1, 10, 2, 11, 10, 11, 6, 7, 6, 11, 6, 7, 5, 4, 5, 7, 5, 4, 9, 5, 9, 10 }, -/* 88: 3, 4, 6, */ { 10, 2, 11, 3, 11, 2, 11, 3, 8, 11, 8, 7, 4, 7, 8, 7, 4, 6, 5, 6, 4, 6, 5, 10, 6, 10, 11 }, -/* 167: 0, 1, 2, 5, 7, */ { 11, 2, 10, 2, 11, 3, 8, 3, 11, 7, 8, 11, 8, 7, 4, 6, 4, 7, 4, 6, 5, 10, 5, 6, 11, 10, 6 }, -/* 91: 0, 1, 3, 4, 6, */ { 10, 1, 9, 1, 10, 2, 11, 2, 10, 6, 11, 10, 11, 6, 7, 5, 7, 6, 7, 5, 4, 9, 4, 5, 10, 9, 5 }, -/* 173: 0, 2, 3, 5, 7, */ { 9, 0, 8, 0, 9, 1, 10, 1, 9, 5, 10, 9, 10, 5, 6, 4, 6, 5, 6, 4, 7, 8, 7, 4, 9, 8, 4 }, -/* 181: 0, 2, 4, 5, 7, */ { 9, 5, 10, 6, 10, 5, 10, 6, 11, 10, 11, 2, 3, 2, 11, 2, 3, 1, 0, 1, 3, 1, 0, 9, 1, 9, 10 }, -/* 229: 0, 2, 5, 6, 7, */ { 11, 7, 8, 4, 8, 7, 8, 4, 9, 8, 9, 0, 1, 0, 9, 0, 1, 3, 2, 3, 1, 3, 2, 11, 3, 11, 8 }, -/* 94: 1, 2, 3, 4, 6, */ { 8, 3, 11, 3, 8, 0, 9, 0, 8, 4, 9, 8, 9, 4, 5, 7, 5, 4, 5, 7, 6, 11, 6, 7, 8, 11, 7 }, -/* 122: 1, 3, 4, 5, 6, */ { 10, 6, 11, 7, 11, 6, 11, 7, 8, 11, 8, 3, 0, 3, 8, 3, 0, 2, 1, 2, 0, 2, 1, 10, 2, 10, 11 }, -/* 218: 1, 3, 4, 6, 7, */ { 8, 4, 9, 5, 9, 4, 9, 5, 10, 9, 10, 1, 2, 1, 10, 1, 2, 0, 3, 0, 2, 0, 3, 8, 0, 8, 9 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 8 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling8[6][6] = { -/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11 }, -/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7 }, -/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2 }, -/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6 }, -/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5 }, -/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 9 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling9[8][12] = { -/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8 }, -/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1 }, -/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8 }, -/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5 }, -/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9 }, -/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0 }, -/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2 }, -/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 10 - * 2 faces to test + eventually the interior - * When the tests on both specified faces are positive : 4 middle triangles (1) - * When the test on the first specified face is positive : 8 first triangles - * When the test on the second specified face is positive : 8 next triangles - * When the tests on both specified faces are negative : - * - if the test on the interior is negative : 4 middle triangles - * - if the test on the interior is positive : 8 last triangles - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test10[6][3] = { -/* 195: 0, 1, 6, 7, */ { 2, 4, 7 }, -/* 85: 0, 2, 4, 6, */ { 5, 6, 7 }, -/* 105: 0, 3, 5, 6, */ { 1, 3, 7 }, -/* 150: 1, 2, 4, 7, */ { 1, 3, 7 }, -/* 170: 1, 3, 5, 7, */ { 5, 6, 7 }, -/* 60: 2, 3, 4, 5, */ { 2, 4, 7 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.1.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_1_1[6][12] = { -/* 195: 0, 1, 6, 7, */ { 5, 10, 7, 11, 7, 10, 8, 1, 9, 1, 8, 3 }, -/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 6, 5, 2, 4, 3, 0, 3, 4, 7 }, -/* 105: 0, 3, 5, 6, */ { 11, 0, 8, 0, 11, 2, 4, 9, 6, 10, 6, 9 }, -/* 150: 1, 2, 4, 7, */ { 9, 0, 10, 2, 10, 0, 6, 8, 4, 8, 6, 11 }, -/* 170: 1, 3, 5, 7, */ { 7, 2, 3, 2, 7, 6, 0, 1, 4, 5, 4, 1 }, -/* 60: 2, 3, 4, 5, */ { 7, 9, 5, 9, 7, 8, 10, 1, 11, 3, 11, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.1.1 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_1_1_[6][12] = { -/* 195: 0, 1, 6, 7, */ { 5, 9, 7, 8, 7, 9, 11, 1, 10, 1, 11, 3 }, -/* 85: 0, 2, 4, 6, */ { 3, 2, 7, 6, 7, 2, 4, 1, 0, 1, 4, 5 }, -/* 105: 0, 3, 5, 6, */ { 10, 0, 9, 0, 10, 2, 4, 8, 6, 11, 6, 8 }, -/* 150: 1, 2, 4, 7, */ { 8, 0, 11, 2, 11, 0, 6, 9, 4, 9, 6, 10 }, -/* 170: 1, 3, 5, 7, */ { 5, 2, 1, 2, 5, 6, 0, 3, 4, 7, 4, 3 }, -/* 60: 2, 3, 4, 5, */ { 7, 10, 5, 10, 7, 11, 9, 1, 8, 3, 8, 1 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.1.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_1_2[6][24] = { -/* 195: 0, 1, 6, 7, */ { 3, 11, 7, 3, 7, 8, 9, 8, 7, 5, 9, 7, 9, 5, 10, 9, 10, 1, 3, 1, 10, 11, 3, 10 }, -/* 85: 0, 2, 4, 6, */ { 7, 6, 5, 7, 5, 4, 0, 4, 5, 1, 0, 5, 0, 1, 2, 0, 2, 3, 7, 3, 2, 6, 7, 2 }, -/* 105: 0, 3, 5, 6, */ { 11, 2, 10, 6, 11, 10, 11, 6, 4, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 10, 0, 10, 2 }, -/* 150: 1, 2, 4, 7, */ { 11, 2, 10, 11, 10, 6, 4, 6, 10, 9, 4, 10, 4, 9, 0, 4, 0, 8, 11, 8, 0, 2, 11, 0 }, -/* 170: 1, 3, 5, 7, */ { 7, 6, 5, 4, 7, 5, 7, 4, 0, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 5, 2, 5, 6 }, -/* 60: 2, 3, 4, 5, */ { 7, 8, 3, 11, 7, 3, 7, 11, 10, 7, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 3, 9, 3, 8 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_2[6][24] = { -/* 195: 0, 1, 6, 7, */ { 12, 5, 9, 12, 9, 8, 12, 8, 3, 12, 3, 1, 12, 1, 10, 12, 10, 11, 12, 11, 7, 12, 7, 5 }, -/* 85: 0, 2, 4, 6, */ { 12, 1, 0, 12, 0, 4, 12, 4, 7, 12, 7, 3, 12, 3, 2, 12, 2, 6, 12, 6, 5, 12, 5, 1 }, -/* 105: 0, 3, 5, 6, */ { 4, 8, 12, 6, 4, 12, 10, 6, 12, 9, 10, 12, 0, 9, 12, 2, 0, 12, 11, 2, 12, 8, 11, 12 }, -/* 150: 1, 2, 4, 7, */ { 12, 9, 4, 12, 4, 6, 12, 6, 11, 12, 11, 8, 12, 8, 0, 12, 0, 2, 12, 2, 10, 12, 10, 9 }, -/* 170: 1, 3, 5, 7, */ { 0, 3, 12, 4, 0, 12, 5, 4, 12, 1, 5, 12, 2, 1, 12, 6, 2, 12, 7, 6, 12, 3, 7, 12 }, -/* 60: 2, 3, 4, 5, */ { 10, 5, 12, 11, 10, 12, 3, 11, 12, 1, 3, 12, 9, 1, 12, 8, 9, 12, 7, 8, 12, 5, 7, 12 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 10.2 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling10_2_[6][24] = { -/* 195: 0, 1, 6, 7, */ { 8, 7, 12, 9, 8, 12, 1, 9, 12, 3, 1, 12, 11, 3, 12, 10, 11, 12, 5, 10, 12, 7, 5, 12 }, -/* 85: 0, 2, 4, 6, */ { 4, 5, 12, 0, 4, 12, 3, 0, 12, 7, 3, 12, 6, 7, 12, 2, 6, 12, 1, 2, 12, 5, 1, 12 }, -/* 105: 0, 3, 5, 6, */ { 12, 11, 6, 12, 6, 4, 12, 4, 9, 12, 9, 10, 12, 10, 2, 12, 2, 0, 12, 0, 8, 12, 8, 11 }, -/* 150: 1, 2, 4, 7, */ { 6, 10, 12, 4, 6, 12, 8, 4, 12, 11, 8, 12, 2, 11, 12, 0, 2, 12, 9, 0, 12, 10, 9, 12 }, -/* 170: 1, 3, 5, 7, */ { 12, 7, 4, 12, 4, 0, 12, 0, 1, 12, 1, 5, 12, 5, 6, 12, 6, 2, 12, 2, 3, 12, 3, 7 }, -/* 60: 2, 3, 4, 5, */ { 12, 7, 11, 12, 11, 10, 12, 10, 1, 12, 1, 3, 12, 3, 8, 12, 8, 9, 12, 9, 5, 12, 5, 7 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 11 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling11[12][12] = { -/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4 }, -/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6 }, -/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10 }, -/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6 }, -/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11 }, -/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0 }, -/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3 }, -/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7 }, -/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11 }, -/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1 }, -/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7 }, -/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9 } -}; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -/** - * \brief test table for case 12 - * 2 faces to test + eventually the interior - * When the tests on both specified faces are positive : 4 middle triangles (1) - * When the test on the first specified face is positive : 8 first triangles - * When the test on the second specified face is positive : 8 next triangles - * When the tests on both specified faces are negative : - * - if the test on the interior is negative : 4 middle triangles - * - if the test on the interior is positive : 8 last triangles - * The support edge for the interior test is marked as the 4th column. - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char test12[24][4] = { -/* 135: 0, 1, 2, 7, */ { 4, 3, 7, 11 }, -/* 75: 0, 1, 3, 6, */ { 3, 2, 7, 10 }, -/* 83: 0, 1, 4, 6, */ { 2, 6, 7, 5 }, -/* 163: 0, 1, 5, 7, */ { 6, 4, 7, 7 }, -/* 45: 0, 2, 3, 5, */ { 2, 1, 7, 9 }, -/* 53: 0, 2, 4, 5, */ { 5, 2, 7, 1 }, -/* 149: 0, 2, 4, 7, */ { 5, 3, 7, 2 }, -/* 101: 0, 2, 5, 6, */ { 5, 1, 7, 0 }, -/* 197: 0, 2, 6, 7, */ { 5, 4, 7, 3 }, -/* 89: 0, 3, 4, 6, */ { 6, 3, 7, 6 }, -/* 169: 0, 3, 5, 7, */ { 1, 6, 7, 4 }, -/* 225: 0, 5, 6, 7, */ { 1, 4, 7, 8 }, -/* 30: 1, 2, 3, 4, */ { 4, 1, 7, 8 }, -/* 86: 1, 2, 4, 6, */ { 6, 1, 7, 4 }, -/* 166: 1, 2, 5, 7, */ { 3, 6, 7, 6 }, -/* 58: 1, 3, 4, 5, */ { 4, 5, 7, 3 }, -/* 154: 1, 3, 4, 7, */ { 1, 5, 7, 0 }, -/* 106: 1, 3, 5, 6, */ { 3, 5, 7, 2 }, -/* 202: 1, 3, 6, 7, */ { 2, 5, 7, 1 }, -/* 210: 1, 4, 6, 7, */ { 1, 2, 7, 9 }, -/* 92: 2, 3, 4, 6, */ { 4, 6, 7, 7 }, -/* 172: 2, 3, 5, 7, */ { 6, 2, 7, 5 }, -/* 180: 2, 4, 5, 7, */ { 2, 3, 7, 10 }, -/* 120: 3, 4, 5, 6, */ { 3, 4, 7, 11 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.1.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_1_1[24][12] = { -/* 135: 0, 1, 2, 7, */ { 7, 6, 11, 10, 3, 2, 3, 10, 8, 9, 8, 10 }, -/* 75: 0, 1, 3, 6, */ { 6, 5, 10, 9, 2, 1, 2, 9, 11, 8, 11, 9 }, -/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 7, 9, 4, 9, 7, 1, 3, 1, 7 }, -/* 163: 0, 1, 5, 7, */ { 7, 6, 11, 4, 8, 5, 3, 5, 8, 5, 3, 1 }, -/* 45: 0, 2, 3, 5, */ { 5, 4, 9, 8, 1, 0, 1, 8, 10, 11, 10, 8 }, -/* 53: 0, 2, 4, 5, */ { 1, 2, 10, 0, 9, 3, 5, 3, 9, 3, 5, 7 }, -/* 149: 0, 2, 4, 7, */ { 10, 1, 2, 0, 11, 3, 11, 0, 6, 4, 6, 0 }, -/* 101: 0, 2, 5, 6, */ { 8, 3, 0, 2, 9, 1, 9, 2, 4, 6, 4, 2 }, -/* 197: 0, 2, 6, 7, */ { 3, 0, 8, 2, 11, 1, 7, 1, 11, 1, 7, 5 }, -/* 89: 0, 3, 4, 6, */ { 6, 5, 10, 7, 11, 4, 2, 4, 11, 4, 2, 0 }, -/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 6, 8, 7, 8, 6, 0, 2, 0, 6 }, -/* 225: 0, 5, 6, 7, */ { 8, 3, 0, 7, 4, 11, 9, 11, 4, 11, 9, 10 }, -/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 11, 0, 3, 0, 11, 9, 10, 9, 11 }, -/* 86: 1, 2, 4, 6, */ { 4, 7, 8, 5, 9, 6, 0, 6, 9, 6, 0, 2 }, -/* 166: 1, 2, 5, 7, */ { 11, 7, 6, 4, 10, 5, 10, 4, 2, 0, 2, 4 }, -/* 58: 1, 3, 4, 5, */ { 11, 2, 3, 1, 8, 0, 8, 1, 7, 5, 7, 1 }, -/* 154: 1, 3, 4, 7, */ { 0, 1, 9, 3, 8, 2, 4, 2, 8, 2, 4, 6 }, -/* 106: 1, 3, 5, 6, */ { 2, 3, 11, 1, 10, 0, 6, 0, 10, 0, 6, 4 }, -/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 3, 10, 2, 10, 3, 5, 7, 5, 3 }, -/* 210: 1, 4, 6, 7, */ { 9, 0, 1, 4, 5, 8, 10, 8, 5, 8, 10, 11 }, -/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 5, 11, 6, 11, 5, 3, 1, 3, 5 }, -/* 172: 2, 3, 5, 7, */ { 5, 4, 9, 6, 10, 7, 1, 7, 10, 7, 1, 3 }, -/* 180: 2, 4, 5, 7, */ { 10, 1, 2, 5, 6, 9, 11, 9, 6, 9, 11, 8 }, -/* 120: 3, 4, 5, 6, */ { 11, 2, 3, 6, 7, 10, 8, 10, 7, 10, 8, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.1.1 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_1_1_[24][12] = { -/* 135: 0, 1, 2, 7, */ { 3, 2, 11, 10, 7, 6, 7, 10, 8, 9, 8, 10 }, -/* 75: 0, 1, 3, 6, */ { 2, 1, 10, 9, 6, 5, 6, 9, 11, 8, 11, 9 }, -/* 83: 0, 1, 4, 6, */ { 9, 4, 5, 7, 10, 6, 10, 7, 1, 3, 1, 7 }, -/* 163: 0, 1, 5, 7, */ { 7, 4, 8, 6, 11, 5, 3, 5, 11, 5, 3, 1 }, -/* 45: 0, 2, 3, 5, */ { 1, 0, 9, 8, 5, 4, 5, 8, 10, 11, 10, 8 }, -/* 53: 0, 2, 4, 5, */ { 1, 0, 9, 2, 10, 3, 5, 3, 10, 3, 5, 7 }, -/* 149: 0, 2, 4, 7, */ { 11, 3, 2, 0, 10, 1, 10, 0, 6, 4, 6, 0 }, -/* 101: 0, 2, 5, 6, */ { 9, 1, 0, 2, 8, 3, 8, 2, 4, 6, 4, 2 }, -/* 197: 0, 2, 6, 7, */ { 3, 2, 11, 0, 8, 1, 7, 1, 8, 1, 7, 5 }, -/* 89: 0, 3, 4, 6, */ { 6, 7, 11, 5, 10, 4, 2, 4, 10, 4, 2, 0 }, -/* 169: 0, 3, 5, 7, */ { 8, 7, 4, 6, 9, 5, 9, 6, 0, 2, 0, 6 }, -/* 225: 0, 5, 6, 7, */ { 8, 7, 4, 3, 0, 11, 9, 11, 0, 11, 9, 10 }, -/* 30: 1, 2, 3, 4, */ { 0, 3, 8, 11, 4, 7, 4, 11, 9, 10, 9, 11 }, -/* 86: 1, 2, 4, 6, */ { 4, 5, 9, 7, 8, 6, 0, 6, 8, 6, 0, 2 }, -/* 166: 1, 2, 5, 7, */ { 10, 5, 6, 4, 11, 7, 11, 4, 2, 0, 2, 4 }, -/* 58: 1, 3, 4, 5, */ { 8, 0, 3, 1, 11, 2, 11, 1, 7, 5, 7, 1 }, -/* 154: 1, 3, 4, 7, */ { 0, 3, 8, 1, 9, 2, 4, 2, 9, 2, 4, 6 }, -/* 106: 1, 3, 5, 6, */ { 2, 1, 10, 3, 11, 0, 6, 0, 11, 0, 6, 4 }, -/* 202: 1, 3, 6, 7, */ { 10, 2, 1, 3, 9, 0, 9, 3, 5, 7, 5, 3 }, -/* 210: 1, 4, 6, 7, */ { 9, 4, 5, 0, 1, 8, 10, 8, 1, 8, 10, 11 }, -/* 92: 2, 3, 4, 6, */ { 11, 6, 7, 5, 8, 4, 8, 5, 3, 1, 3, 5 }, -/* 172: 2, 3, 5, 7, */ { 5, 6, 10, 4, 9, 7, 1, 7, 9, 7, 1, 3 }, -/* 180: 2, 4, 5, 7, */ { 10, 5, 6, 1, 2, 9, 11, 9, 2, 9, 11, 8 }, -/* 120: 3, 4, 5, 6, */ { 11, 6, 7, 2, 3, 10, 8, 10, 3, 10, 8, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.1.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_1_2[24][24] = { -/* 135: 0, 1, 2, 7, */ { 7, 3, 11, 3, 7, 8, 9, 8, 7, 6, 9, 7, 9, 6, 10, 2, 10, 6, 11, 2, 6, 2, 11, 3 }, -/* 75: 0, 1, 3, 6, */ { 6, 2, 10, 2, 6, 11, 8, 11, 6, 5, 8, 6, 8, 5, 9, 1, 9, 5, 10, 1, 5, 1, 10, 2 }, -/* 83: 0, 1, 4, 6, */ { 10, 9, 5, 9, 10, 1, 3, 1, 10, 6, 3, 10, 3, 6, 7, 4, 7, 6, 5, 4, 6, 4, 5, 9 }, -/* 163: 0, 1, 5, 7, */ { 7, 8, 11, 3, 11, 8, 11, 3, 1, 11, 1, 6, 5, 6, 1, 6, 5, 4, 6, 4, 7, 8, 7, 4 }, -/* 45: 0, 2, 3, 5, */ { 5, 1, 9, 1, 5, 10, 11, 10, 5, 4, 11, 5, 11, 4, 8, 0, 8, 4, 9, 0, 4, 0, 9, 1 }, -/* 53: 0, 2, 4, 5, */ { 1, 9, 10, 5, 10, 9, 10, 5, 7, 10, 7, 2, 3, 2, 7, 2, 3, 0, 2, 0, 1, 9, 1, 0 }, -/* 149: 0, 2, 4, 7, */ { 10, 11, 2, 11, 10, 6, 4, 6, 10, 1, 4, 10, 4, 1, 0, 3, 0, 1, 2, 3, 1, 3, 2, 11 }, -/* 101: 0, 2, 5, 6, */ { 8, 9, 0, 9, 8, 4, 6, 4, 8, 3, 6, 8, 6, 3, 2, 1, 2, 3, 0, 1, 3, 1, 0, 9 }, -/* 197: 0, 2, 6, 7, */ { 3, 11, 8, 7, 8, 11, 8, 7, 5, 8, 5, 0, 1, 0, 5, 0, 1, 2, 0, 2, 3, 11, 3, 2 }, -/* 89: 0, 3, 4, 6, */ { 6, 11, 10, 2, 10, 11, 10, 2, 0, 10, 0, 5, 4, 5, 0, 5, 4, 7, 5, 7, 6, 11, 6, 7 }, -/* 169: 0, 3, 5, 7, */ { 9, 8, 4, 8, 9, 0, 2, 0, 9, 5, 2, 9, 2, 5, 6, 7, 6, 5, 4, 7, 5, 7, 4, 8 }, -/* 225: 0, 5, 6, 7, */ { 8, 4, 0, 9, 0, 4, 0, 9, 10, 0, 10, 3, 11, 3, 10, 3, 11, 7, 3, 7, 8, 4, 8, 7 }, -/* 30: 1, 2, 3, 4, */ { 4, 0, 8, 0, 4, 9, 10, 9, 4, 7, 10, 4, 10, 7, 11, 3, 11, 7, 8, 3, 7, 3, 8, 0 }, -/* 86: 1, 2, 4, 6, */ { 4, 9, 8, 0, 8, 9, 8, 0, 2, 8, 2, 7, 6, 7, 2, 7, 6, 5, 7, 5, 4, 9, 4, 5 }, -/* 166: 1, 2, 5, 7, */ { 11, 10, 6, 10, 11, 2, 0, 2, 11, 7, 0, 11, 0, 7, 4, 5, 4, 7, 6, 5, 7, 5, 6, 10 }, -/* 58: 1, 3, 4, 5, */ { 11, 8, 3, 8, 11, 7, 5, 7, 11, 2, 5, 11, 5, 2, 1, 0, 1, 2, 3, 0, 2, 0, 3, 8 }, -/* 154: 1, 3, 4, 7, */ { 0, 8, 9, 4, 9, 8, 9, 4, 6, 9, 6, 1, 2, 1, 6, 1, 2, 3, 1, 3, 0, 8, 0, 3 }, -/* 106: 1, 3, 5, 6, */ { 2, 10, 11, 6, 11, 10, 11, 6, 4, 11, 4, 3, 0, 3, 4, 3, 0, 1, 3, 1, 2, 10, 2, 1 }, -/* 202: 1, 3, 6, 7, */ { 9, 10, 1, 10, 9, 5, 7, 5, 9, 0, 7, 9, 7, 0, 3, 2, 3, 0, 1, 2, 0, 2, 1, 10 }, -/* 210: 1, 4, 6, 7, */ { 9, 5, 1, 10, 1, 5, 1, 10, 11, 1, 11, 0, 8, 0, 11, 0, 8, 4, 0, 4, 9, 5, 9, 4 }, -/* 92: 2, 3, 4, 6, */ { 8, 11, 7, 11, 8, 3, 1, 3, 8, 4, 1, 8, 1, 4, 5, 6, 5, 4, 7, 6, 4, 6, 7, 11 }, -/* 172: 2, 3, 5, 7, */ { 5, 10, 9, 1, 9, 10, 9, 1, 3, 9, 3, 4, 7, 4, 3, 4, 7, 6, 4, 6, 5, 10, 5, 6 }, -/* 180: 2, 4, 5, 7, */ { 10, 6, 2, 11, 2, 6, 2, 11, 8, 2, 8, 1, 9, 1, 8, 1, 9, 5, 1, 5, 10, 6, 10, 5 }, -/* 120: 3, 4, 5, 6, */ { 11, 7, 3, 8, 3, 7, 3, 8, 9, 3, 9, 2, 10, 2, 9, 2, 10, 6, 2, 6, 11, 7, 11, 6 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_2[24][24] = { -/* 135: 0, 1, 2, 7, */ { 9, 8, 12, 10, 9, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12 }, -/* 75: 0, 1, 3, 6, */ { 8, 11, 12, 9, 8, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12 }, -/* 83: 0, 1, 4, 6, */ { 3, 1, 12, 7, 3, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 }, -/* 163: 0, 1, 5, 7, */ { 12, 3, 1, 12, 1, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 }, -/* 45: 0, 2, 3, 5, */ { 11, 10, 12, 8, 11, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12 }, -/* 53: 0, 2, 4, 5, */ { 12, 5, 7, 12, 7, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, -/* 149: 0, 2, 4, 7, */ { 4, 6, 12, 0, 4, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 }, -/* 101: 0, 2, 5, 6, */ { 6, 4, 12, 2, 6, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 }, -/* 197: 0, 2, 6, 7, */ { 12, 7, 5, 12, 5, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, -/* 89: 0, 3, 4, 6, */ { 12, 2, 0, 12, 0, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 }, -/* 169: 0, 3, 5, 7, */ { 2, 0, 12, 6, 2, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 }, -/* 225: 0, 5, 6, 7, */ { 12, 9, 10, 12, 10, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9 }, -/* 30: 1, 2, 3, 4, */ { 10, 9, 12, 11, 10, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12 }, -/* 86: 1, 2, 4, 6, */ { 12, 0, 2, 12, 2, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 }, -/* 166: 1, 2, 5, 7, */ { 0, 2, 12, 4, 0, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 }, -/* 58: 1, 3, 4, 5, */ { 5, 7, 12, 1, 5, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, -/* 154: 1, 3, 4, 7, */ { 12, 4, 6, 12, 6, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 }, -/* 106: 1, 3, 5, 6, */ { 12, 6, 4, 12, 4, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 }, -/* 202: 1, 3, 6, 7, */ { 7, 5, 12, 3, 7, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, -/* 210: 1, 4, 6, 7, */ { 12, 10, 11, 12, 11, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10 }, -/* 92: 2, 3, 4, 6, */ { 1, 3, 12, 5, 1, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 }, -/* 172: 2, 3, 5, 7, */ { 12, 1, 3, 12, 3, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 }, -/* 180: 2, 4, 5, 7, */ { 12, 11, 8, 12, 8, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11 }, -/* 120: 3, 4, 5, 6, */ { 12, 8, 9, 12, 9, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 12.2 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling12_2_[24][24] = { -/* 135: 0, 1, 2, 7, */ { 12, 2, 11, 12, 11, 7, 12, 7, 6, 12, 6, 10, 12, 10, 9, 12, 9, 8, 12, 8, 3, 12, 3, 2 }, -/* 75: 0, 1, 3, 6, */ { 12, 1, 10, 12, 10, 6, 12, 6, 5, 12, 5, 9, 12, 9, 8, 12, 8, 11, 12, 11, 2, 12, 2, 1 }, -/* 83: 0, 1, 4, 6, */ { 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 3, 12, 3, 1, 12, 1, 9, 12, 9, 4 }, -/* 163: 0, 1, 5, 7, */ { 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 1, 5, 12, 3, 1, 12, 11, 3, 12, 6, 11, 12 }, -/* 45: 0, 2, 3, 5, */ { 12, 0, 9, 12, 9, 5, 12, 5, 4, 12, 4, 8, 12, 8, 11, 12, 11, 10, 12, 10, 1, 12, 1, 0 }, -/* 53: 0, 2, 4, 5, */ { 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 7, 3, 12, 5, 7, 12, 10, 5, 12, 2, 10, 12 }, -/* 149: 0, 2, 4, 7, */ { 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 4, 12, 4, 6, 12, 6, 10, 12, 10, 1 }, -/* 101: 0, 2, 5, 6, */ { 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 6, 12, 6, 4, 12, 4, 8, 12, 8, 3 }, -/* 197: 0, 2, 6, 7, */ { 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 5, 1, 12, 7, 5, 12, 8, 7, 12, 0, 8, 12 }, -/* 89: 0, 3, 4, 6, */ { 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 0, 4, 12, 2, 0, 12, 10, 2, 12, 5, 10, 12 }, -/* 169: 0, 3, 5, 7, */ { 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 2, 12, 2, 0, 12, 0, 8, 12, 8, 7 }, -/* 225: 0, 5, 6, 7, */ { 8, 7, 12, 0, 8, 12, 3, 0, 12, 11, 3, 12, 10, 11, 12, 9, 10, 12, 4, 9, 12, 7, 4, 12 }, -/* 30: 1, 2, 3, 4, */ { 12, 7, 8, 12, 8, 0, 12, 0, 3, 12, 3, 11, 12, 11, 10, 12, 10, 9, 12, 9, 4, 12, 4, 7 }, -/* 86: 1, 2, 4, 6, */ { 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 2, 6, 12, 0, 2, 12, 8, 0, 12, 7, 8, 12 }, -/* 166: 1, 2, 5, 7, */ { 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 0, 12, 0, 2, 12, 2, 10, 12, 10, 5 }, -/* 58: 1, 3, 4, 5, */ { 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 5, 12, 5, 7, 12, 7, 8, 12, 8, 0 }, -/* 154: 1, 3, 4, 7, */ { 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 6, 2, 12, 4, 6, 12, 8, 4, 12, 3, 8, 12 }, -/* 106: 1, 3, 5, 6, */ { 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 4, 0, 12, 6, 4, 12, 10, 6, 12, 1, 10, 12 }, -/* 202: 1, 3, 6, 7, */ { 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 7, 12, 7, 5, 12, 5, 10, 12, 10, 2 }, -/* 210: 1, 4, 6, 7, */ { 9, 0, 12, 5, 9, 12, 4, 5, 12, 8, 4, 12, 11, 8, 12, 10, 11, 12, 1, 10, 12, 0, 1, 12 }, -/* 92: 2, 3, 4, 6, */ { 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 1, 12, 1, 3, 12, 3, 11, 12, 11, 6 }, -/* 172: 2, 3, 5, 7, */ { 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 3, 7, 12, 1, 3, 12, 9, 1, 12, 4, 9, 12 }, -/* 180: 2, 4, 5, 7, */ { 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 8, 9, 12, 11, 8, 12, 2, 11, 12, 1, 2, 12 }, -/* 120: 3, 4, 5, 6, */ { 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 9, 10, 12, 8, 9, 12, 3, 8, 12, 2, 3, 12 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief test table for case 13 - * All faces are to be tested - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13: face test */ -static const char test13[2][7] = { -/* 165: 0, 2, 5, 7, */ { 1,2,3,4,5,6, 7 }, -/* 90: 1, 3, 4, 6, */ { 2,3,4,1,5,6,-7 }, -}; - - - -//_____________________________________________________________________________ -/** - * \brief subconfiguration table for case 13 - * Hard-coded tests for the subconfiguration determination - * - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13: sub configs */ -static const char subconfig13[64] = { -/* 0: 0,0,0,0,0,0 */ 0, -/* 1: 1,0,0,0,0,0 */ 1, -/* 2: 0,1,0,0,0,0 */ 2, -/* 3: 1,1,0,0,0,0 */ 7, -/* 4: 0,0,1,0,0,0 */ 3, -/* 5: 1,0,1,0,0,0 */ -1, -/* 6: 0,1,1,0,0,0 */ 11, -/* 7: 1,1,1,0,0,0 */ -1, -/* 8: 0,0,0,1,0,0 */ 4, -/* 9: 1,0,0,1,0,0 */ 8, -/* 10: 0,1,0,1,0,0 */ -1, -/* 11: 1,1,0,1,0,0 */ -1, -/* 12: 0,0,1,1,0,0 */ 14, -/* 13: 1,0,1,1,0,0 */ -1, -/* 14: 0,1,1,1,0,0 */ -1, -/* 15: 1,1,1,1,0,0 */ -1, -/* 16: 0,0,0,0,1,0 */ 5, -/* 17: 1,0,0,0,1,0 */ 9, -/* 18: 0,1,0,0,1,0 */ 12, -/* 19: 1,1,0,0,1,0 */ 23, -/* 20: 0,0,1,0,1,0 */ 15, -/* 21: 1,0,1,0,1,0 */ -1, -/* 22: 0,1,1,0,1,0 */ 21, -/* 23: 1,1,1,0,1,0 */ 38, -/* 24: 0,0,0,1,1,0 */ 17, -/* 25: 1,0,0,1,1,0 */ 20, -/* 26: 0,1,0,1,1,0 */ -1, -/* 27: 1,1,0,1,1,0 */ 36, -/* 28: 0,0,1,1,1,0 */ 26, -/* 29: 1,0,1,1,1,0 */ 33, -/* 30: 0,1,1,1,1,0 */ 30, -/* 31: 1,1,1,1,1,0 */ 44, -/* 32: 0,0,0,0,0,1 */ 6, -/* 33: 1,0,0,0,0,1 */ 10, -/* 34: 0,1,0,0,0,1 */ 13, -/* 35: 1,1,0,0,0,1 */ 19, -/* 36: 0,0,1,0,0,1 */ 16, -/* 37: 1,0,1,0,0,1 */ -1, -/* 38: 0,1,1,0,0,1 */ 25, -/* 39: 1,1,1,0,0,1 */ 37, -/* 40: 0,0,0,1,0,1 */ 18, -/* 41: 1,0,0,1,0,1 */ 24, -/* 42: 0,1,0,1,0,1 */ -1, -/* 43: 1,1,0,1,0,1 */ 35, -/* 44: 0,0,1,1,0,1 */ 22, -/* 45: 1,0,1,1,0,1 */ 32, -/* 46: 0,1,1,1,0,1 */ 29, -/* 47: 1,1,1,1,0,1 */ 43, -/* 48: 0,0,0,0,1,1 */ -1, -/* 49: 1,0,0,0,1,1 */ -1, -/* 50: 0,1,0,0,1,1 */ -1, -/* 51: 1,1,0,0,1,1 */ 34, -/* 52: 0,0,1,0,1,1 */ -1, -/* 53: 1,0,1,0,1,1 */ -1, -/* 54: 0,1,1,0,1,1 */ 28, -/* 55: 1,1,1,0,1,1 */ 42, -/* 56: 0,0,0,1,1,1 */ -1, -/* 57: 1,0,0,1,1,1 */ 31, -/* 58: 0,1,0,1,1,1 */ -1, -/* 59: 1,1,0,1,1,1 */ 41, -/* 60: 0,0,1,1,1,1 */ 27, -/* 61: 1,0,1,1,1,1 */ 40, -/* 62: 0,1,1,1,1,1 */ 39, -/* 63: 1,1,1,1,1,1 */ 45, -}; - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.1 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.1 */ -static const char tiling13_1[2][12] = { -/* 165: 0, 2, 5, 7, */ { 11, 7, 6, 1, 2, 10, 8, 3, 0, 9, 5, 4 }, -/* 90: 1, 3, 4, 6, */ { 8, 4, 7, 2, 3, 11, 9, 0, 1, 10, 6, 5 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.1 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.1 */ -static const char tiling13_1_[2][12] = { -/* 165: 0, 2, 5, 7, */ { 7, 4, 8, 11, 3, 2, 1, 0, 9, 5, 6, 10 }, -/* 90: 1, 3, 4, 6, */ { 6, 7, 11, 10, 2, 1, 0, 3, 8, 4, 5, 9 } -}; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.2 */ -static const char tiling13_2[2][6][18] = { -/* 165: 0, 2, 5, 7, */ { - /* 1 */ { 1, 2, 10, 11, 7, 6, 3, 4, 8, 4, 3, 5, 0, 5, 3, 5, 0, 9 }, - /* 2 */ { 8, 3, 0, 11, 7, 6, 9, 1, 4, 2, 4, 1, 4, 2, 5, 10, 5, 2 }, - /* 3 */ { 9, 5, 4, 8, 3, 0, 1, 6, 10, 6, 1, 7, 2, 7, 1, 7, 2, 11 }, - /* 4 */ { 9, 5, 4, 1, 2, 10, 11, 3, 6, 0, 6, 3, 6, 0, 7, 8, 7, 0 }, - /* 5 */ { 9, 5, 4, 11, 7, 6, 0, 10, 1, 10, 0, 8, 10, 8, 2, 3, 2, 8 }, - /* 6 */ { 1, 2, 10, 3, 0, 8, 4, 9, 7, 11, 7, 9, 5, 11, 9, 11, 5, 6 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1 */ { 2, 3, 11, 8, 4, 7, 0, 5, 9, 5, 0, 6, 1, 6, 0, 6, 1, 10 }, - /* 2 */ { 9, 0, 1, 8, 4, 7, 10, 2, 5, 3, 5, 2, 5, 3, 6, 11, 6, 3 }, - /* 3 */ { 6, 5, 10, 9, 0, 1, 2, 7, 11, 7, 2, 4, 3, 4, 2, 4, 3, 8 }, - /* 4 */ { 6, 5, 10, 2, 3, 11, 8, 0, 7, 1, 7, 0, 7, 1, 4, 9, 4, 1 }, - /* 5 */ { 6, 5, 10, 8, 4, 7, 1, 11, 2, 11, 1, 9, 11, 9, 3, 0, 3, 9 }, - /* 6 */ { 2, 3, 11, 0, 1, 9, 5, 10, 4, 8, 4, 10, 6, 8, 10, 8, 6, 7 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.2 inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.2 */ -static const char tiling13_2_[2][6][18] = { -/* 165: 0, 2, 5, 7, */ { - /* 1 */ { 10, 5, 6, 11, 3, 2, 7, 0, 8, 0, 7, 1, 4, 1, 7, 1, 4, 9 }, - /* 2 */ { 11, 3, 2, 7, 4, 8, 9, 5, 0, 6, 0, 5, 0, 6, 1, 10, 1, 6 }, - /* 3 */ { 1, 0, 9, 7, 4, 8, 5, 2, 10, 2, 5, 3, 6, 3, 5, 3, 6, 11 }, - /* 4 */ { 10, 5, 6, 1, 0, 9, 11, 7, 2, 4, 2, 7, 2, 4, 3, 8, 3, 4 }, - /* 5 */ { 10, 5, 6, 7, 4, 8, 2, 11, 1, 9, 1, 11, 3, 9, 11, 9, 3, 0 }, - /* 6 */ { 11, 3, 2, 9, 1, 0, 4, 10, 5, 10, 4, 8, 10, 8, 6, 7, 6, 8 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1 */ { 6, 7, 11, 8, 0, 3, 4, 1, 9, 1, 4, 2, 5, 2, 4, 2, 5, 10 }, - /* 2 */ { 8, 0, 3, 4, 5, 9, 10, 6, 1, 7, 1, 6, 1, 7, 2, 11, 2, 7 }, - /* 3 */ { 2, 1, 10, 4, 5, 9, 6, 3, 11, 3, 6, 0, 7, 0, 6, 0, 7, 8 }, - /* 4 */ { 6, 7, 11, 2, 1, 10, 8, 4, 3, 5, 3, 4, 3, 5, 0, 9, 0, 5 }, - /* 5 */ { 6, 7, 11, 4, 5, 9, 3, 8, 2, 10, 2, 8, 0, 10, 8, 10, 0, 1 }, - /* 6 */ { 8, 0, 3, 10, 2, 1, 5, 11, 6, 11, 5, 9, 11, 9, 7, 4, 7, 9 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.3 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.3 */ -static const char tiling13_3[2][12][30] = { -/* 165: 0, 2, 5, 7, */ { - /* 1,2 */ { 11, 7, 6, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, - /* 1,4 */ { 1, 2, 10, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12 }, - /* 1,5 */ { 11, 7, 6, 12, 5, 4, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 1, 12, 1, 0, 12, 0, 9, 12, 9, 5 }, - /* 1,6 */ { 1, 2, 10, 12, 3, 0, 12, 0, 9, 12, 9, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3 }, - /* 2,3 */ { 8, 3, 0, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12 }, - /* 2,5 */ { 11, 7, 6, 5, 4, 12, 10, 5, 12, 2, 10, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12, 9, 1, 12, 4, 9, 12 }, - /* 2,6 */ { 8, 3, 0, 1, 2, 12, 9, 1, 12, 4, 9, 12, 7, 4, 12, 11, 7, 12, 6, 11, 12, 5, 6, 12, 10, 5, 12, 2, 10, 12 }, - /* 3,4 */ { 9, 5, 4, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 }, - /* 3,5 */ { 9, 5, 4, 12, 7, 6, 12, 6, 10, 12, 10, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2, 12, 2, 11, 12, 11, 7 }, - /* 3,6 */ { 8, 3, 0, 12, 1, 2, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1 }, - /* 4,5 */ { 9, 5, 4, 7, 6, 12, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12, 11, 3, 12, 6, 11, 12 }, - /* 4,6 */ { 1, 2, 10, 3, 0, 12, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12, 8, 7, 12, 0, 8, 12 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1,2 */ { 8, 4, 7, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, - /* 1,4 */ { 2, 3, 11, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12 }, - /* 1,5 */ { 8, 4, 7, 12, 6, 5, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 2, 12, 2, 1, 12, 1, 10, 12, 10, 6 }, - /* 1,6 */ { 2, 3, 11, 12, 0, 1, 12, 1, 10, 12, 10, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0 }, - /* 2,3 */ { 0, 1, 9, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12 }, - /* 2,5 */ { 8, 4, 7, 6, 5, 12, 11, 6, 12, 3, 11, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12, 10, 2, 12, 5, 10, 12 }, - /* 2,6 */ { 9, 0, 1, 2, 3, 12, 10, 2, 12, 5, 10, 12, 4, 5, 12, 8, 4, 12, 7, 8, 12, 6, 7, 12, 11, 6, 12, 3, 11, 12 }, - /* 3,4 */ { 6, 5, 10, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 }, - /* 3,5 */ { 6, 5, 10, 12, 4, 7, 12, 7, 11, 12, 11, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3, 12, 3, 8, 12, 8, 4 }, - /* 3,6 */ { 9, 0, 1, 12, 2, 3, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2 }, - /* 4,5 */ { 6, 5, 10, 4, 7, 12, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12, 8, 0, 12, 7, 8, 12 }, - /* 4,6 */ { 2, 3, 11, 0, 1, 12, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12, 9, 4, 12, 1, 9, 12 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.3, inverted - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.3 */ -static const char tiling13_3_[2][12][30] = { -/* 165: 0, 2, 5, 7, */ { - /* 1,2 */ { 3, 2, 11, 8, 7, 12, 0, 8, 12, 1, 0, 12, 10, 1, 12, 6, 10, 12, 5, 6, 12, 9, 5, 12, 4, 9, 12, 7, 4, 12 }, - /* 1,4 */ { 5, 6, 10, 12, 2, 11, 12, 11, 7, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 0, 12, 0, 8, 12, 8, 3, 12, 3, 2 }, - /* 1,5 */ { 10, 5, 6, 12, 7, 4, 12, 4, 9, 12, 9, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0, 12, 0, 8, 12, 8, 7 }, - /* 1,6 */ { 11, 3, 2, 12, 1, 0, 12, 0, 8, 12, 8, 7, 12, 7, 6, 12, 6, 10, 12, 10, 5, 12, 5, 4, 12, 4, 9, 12, 9, 1 }, - /* 2,3 */ { 7, 4, 8, 11, 3, 12, 6, 11, 12, 5, 6, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, - /* 2,5 */ { 7, 4, 8, 5, 6, 12, 9, 5, 12, 0, 9, 12, 3, 0, 12, 11, 3, 12, 2, 11, 12, 1, 2, 12, 10, 1, 12, 6, 10, 12 }, - /* 2,6 */ { 11, 3, 2, 1, 0, 12, 10, 1, 12, 6, 10, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12 }, - /* 3,4 */ { 1, 0, 9, 12, 4, 8, 12, 8, 3, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4 }, - /* 3,5 */ { 7, 4, 8, 12, 5, 6, 12, 6, 11, 12, 11, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2, 12, 2, 10, 12, 10, 5 }, - /* 3,6 */ { 1, 0, 9, 12, 3, 2, 12, 2, 10, 12, 10, 5, 12, 5, 4, 12, 4, 8, 12, 8, 7, 12, 7, 6, 12, 6, 11, 12, 11, 3 }, - /* 4,5 */ { 10, 5, 6, 7, 4, 12, 11, 7, 12, 2, 11, 12, 1, 2, 12, 9, 1, 12, 0, 9, 12, 3, 0, 12, 8, 3, 12, 4, 8, 12 }, - /* 4,6 */ { 9, 1, 0, 3, 2, 12, 8, 3, 12, 4, 8, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12 } -}, -/* 90: 1, 3, 4, 6, */ { - /* 1,2 */ { 0, 3, 8, 9, 4, 12, 1, 9, 12, 2, 1, 12, 11, 2, 12, 7, 11, 12, 6, 7, 12, 10, 6, 12, 5, 10, 12, 4, 5, 12 }, - /* 1,4 */ { 11, 6, 7, 12, 3, 8, 12, 8, 4, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 1, 12, 1, 9, 12, 9, 0, 12, 0, 3 }, - /* 1,5 */ { 6, 7, 11, 12, 4, 5, 12, 5, 10, 12, 10, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1, 12, 1, 9, 12, 9, 4 }, - /* 1,6 */ { 8, 0, 3, 12, 2, 1, 12, 1, 9, 12, 9, 4, 12, 4, 7, 12, 7, 11, 12, 11, 6, 12, 6, 5, 12, 5, 10, 12, 10, 2 }, - /* 2,3 */ { 4, 5, 9, 8, 0, 12, 7, 8, 12, 6, 7, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, - /* 2,5 */ { 4, 5, 9, 6, 7, 12, 10, 6, 12, 1, 10, 12, 0, 1, 12, 8, 0, 12, 3, 8, 12, 2, 3, 12, 11, 2, 12, 7, 11, 12 }, - /* 2,6 */ { 8, 0, 3, 2, 1, 12, 11, 2, 12, 7, 11, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12 }, - /* 3,4 */ { 2, 1, 10, 12, 5, 9, 12, 9, 0, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5 }, - /* 3,5 */ { 4, 5, 9, 12, 6, 7, 12, 7, 8, 12, 8, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3, 12, 3, 11, 12, 11, 6 }, - /* 3,6 */ { 2, 1, 10, 12, 0, 3, 12, 3, 11, 12, 11, 6, 12, 6, 5, 12, 5, 9, 12, 9, 4, 12, 4, 7, 12, 7, 8, 12, 8, 0 }, - /* 4,5 */ { 6, 7, 11, 4, 5, 12, 8, 4, 12, 3, 8, 12, 2, 3, 12, 10, 2, 12, 1, 10, 12, 0, 1, 12, 9, 0, 12, 5, 9, 12 }, - /* 4,6 */ { 10, 2, 1, 0, 3, 12, 9, 0, 12, 5, 9, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.4 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.4 */ -static const char tiling13_4[2][4][36] = { -/* 165: 0, 2, 5, 7, */ { -/* 1,2,6 */ { 12, 2, 10, 12, 10, 5, 12, 5, 6, 12, 6, 11, 12, 11, 7, 12, 7, 4, 12, 4, 8, 12, 8, 3, 12, 3, 0, 12, 0, 9, 12, 9, 1, 12, 1, 2 }, -/* 1,4,5 */ { 11, 3, 12, 6, 11, 12, 7, 6, 12, 8, 7, 12, 4, 8, 12, 5, 4, 12, 9, 5, 12, 0, 9, 12, 1, 0, 12, 10, 1, 12, 2, 10, 12, 3, 2, 12 }, -/* 2,3,5 */ { 9, 1, 12, 4, 9, 12, 5, 4, 12, 10, 5, 12, 6, 10, 12, 7, 6, 12, 11, 7, 12, 2, 11, 12, 3, 2, 12, 8, 3, 12, 0, 8, 12, 1, 0, 12 }, -/* 3,4,6 */ { 12, 0, 8, 12, 8, 7, 12, 7, 4, 12, 4, 9, 12, 9, 5, 12, 5, 6, 12, 6, 10, 12, 10, 1, 12, 1, 2, 12, 2, 11, 12, 11, 3, 12, 3, 0 } -}, -/* 90: 1, 3, 4, 6, */ { -/* 1,2,6 */ { 12, 3, 11, 12, 11, 6, 12, 6, 7, 12, 7, 8, 12, 8, 4, 12, 4, 5, 12, 5, 9, 12, 9, 0, 12, 0, 1, 12, 1, 10, 12, 10, 2, 12, 2, 3 }, -/* 1,4,5 */ { 8, 0, 12, 7, 8, 12, 4, 7, 12, 9, 4, 12, 5, 9, 12, 6, 5, 12, 10, 6, 12, 1, 10, 12, 2, 1, 12, 11, 2, 12, 3, 11, 12, 0, 3, 12 }, -/* 2,3,5 */ { 10, 2, 12, 5, 10, 12, 6, 5, 12, 11, 6, 12, 7, 11, 12, 4, 7, 12, 8, 4, 12, 3, 8, 12, 0, 3, 12, 9, 0, 12, 1, 9, 12, 2, 1, 12 }, -/* 3,4,6 */ { 12, 1, 9, 12, 9, 4, 12, 4, 5, 12, 5, 10, 12, 10, 6, 12, 6, 7, 12, 7, 11, 12, 11, 2, 12, 2, 3, 12, 3, 8, 12, 8, 0, 12, 0, 1 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.5.1 - * The support edge for the interior test is marked as the 1st column. - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.5.1 */ -static const char tiling13_5_1[2][4][18] = { -/* 165: 0, 2, 5, 7, */ { -/* 1,2,5 */ { 7, 6, 11, 1, 0, 9, 10, 3, 2, 3, 10, 5, 3, 5, 8, 4, 8, 5 }, -/* 1,4,6 */ { 1, 2, 10, 7, 4, 8, 3, 0, 11, 6, 11, 0, 9, 6, 0, 6, 9, 5 }, -/* 2,3,6 */ { 3, 0, 8, 5, 6, 10, 1, 2, 9, 4, 9, 2, 11, 4, 2, 4, 11, 7 }, -/* 3,4,5 */ { 5, 4, 9, 3, 2, 11, 8, 1, 0, 1, 8, 7, 1, 7, 10, 6, 10, 7 } -}, -/* 90: 1, 3, 4, 6, */ { -/* 1,2,5 */ { 4, 7, 8, 2, 1, 10, 11, 0, 3, 0, 11, 6, 0, 6, 9, 5, 9, 6 }, -/* 1,4,6 */ { 2, 3, 11, 4, 5, 9, 0, 1, 8, 7, 8, 1, 10, 7, 1, 7, 10, 6 }, -/* 2,3,6 */ { 0, 1, 9, 6, 7, 11, 2, 3, 10, 5, 10, 3, 8, 5, 3, 5, 8, 4 }, -/* 3,4,5 */ { 6, 5, 10, 0, 3, 8, 9, 2, 1, 2, 9, 4, 2, 4, 11, 7, 11, 4 } -} }; - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 13.5.2 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -/* 13.5.2 */ -static const char tiling13_5_2[2][4][30] = { -/* 165: 0, 2, 5, 7, */ { -/* 1,2,5 */ { 1, 0, 9, 7, 4, 8, 7, 8, 3, 7, 3, 11, 2, 11, 3, 11, 2, 10, 11, 10, 6, 5, 6, 10, 6, 5, 7, 4, 7, 5 }, -/* 1,4,6 */ { 7, 4, 8, 11, 3, 2, 6, 11, 2, 10, 6, 2, 6, 10, 5, 9, 5, 10, 1, 9, 10, 9, 1, 0, 2, 0, 1, 0, 2, 3 }, -/* 2,3,6 */ { 5, 6, 10, 9, 1, 0, 4, 9, 0, 8, 4, 0, 4, 8, 7, 11, 7, 8, 3, 11, 8, 11, 3, 2, 0, 2, 3, 2, 0, 1 }, -/* 3,4,5 */ { 3, 2, 11, 5, 6, 10, 5, 10, 1, 5, 1, 9, 0, 9, 1, 9, 0, 8, 9, 8, 4, 4, 8, 7, 4, 7, 5, 6, 5, 7 } -}, -/* 90: 1, 3, 4, 6, */ { -/* 1,2,5 */ { 2, 1, 10, 4, 5, 9, 4, 9, 0, 4, 0, 8, 3, 8, 0, 8, 3, 11, 8, 11, 7, 6, 7, 11, 7, 6, 4, 5, 4, 6 }, -/* 1,4,6 */ { 4, 5, 9, 8, 0, 3, 7, 8, 3, 11, 7, 3, 7, 11, 6, 10, 6, 11, 2, 10, 11, 10, 2, 1, 3, 1, 2, 1, 3, 0 }, -/* 2,3,6 */ { 6, 7, 11, 10, 2, 1, 5, 10, 1, 9, 5, 1, 5, 9, 4, 8, 4, 9, 0, 8, 9, 8, 0, 3, 1, 3, 0, 3, 1, 2 }, -/* 3,4,5 */ { 0, 3, 8, 6, 7, 11, 6, 11, 2, 6, 2, 10, 1, 10, 2, 10, 1, 9, 10, 9, 5, 5, 9, 4, 5, 4, 6, 7, 6, 4 } -} }; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief tiling table for case 14 - * For each of the case above, the specific triangulation of the edge - * intersection points is given. - * When a case is ambiguous, there is an auxiliary table that contains - * the face number to test and the tiling table contains the specific - * triangulations depending on the results - * A minus sign means to invert the result of the test. - */ -//----------------------------------------------------------------------------- -static const char tiling14[12][12] = { -/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8 }, -/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5 }, -/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6 }, -/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4 }, -/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5 }, -/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10 }, -/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7 }, -/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2 }, -/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11 }, -/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3 }, -/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8 }, -/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2 } -}; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** - * \brief original Marching Cubes implementation - * For each of the possible vertex states listed in this table there is a - * specific triangulation of the edge intersection points. The table lists - * all of them in the form of 0-5 edge triples with the list terminated by - * the invalid value -1. For example: casesClassic[3] list the 2 triangles - * formed when cube[0] and cube[1] are inside of the surface, but the rest of - * the cube is not. - */ -//----------------------------------------------------------------------------- -static const char casesClassic[256][16] = { -/* 0: */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 1: 0, */ { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 2: 1, */ { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 3: 0, 1, */ { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 4: 2, */ { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 5: 0, 2, */ { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 6: 1, 2, */ { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 7: 0, 1, 2, */ { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 8: 3, */ { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 9: 0, 3, */ { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 10: 1, 3, */ { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 11: 0, 1, 3, */ { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 12: 2, 3, */ { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 13: 0, 2, 3, */ { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 14: 1, 2, 3, */ { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 15: 0, 1, 2, 3, */ { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 16: 4, */ { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 17: 0, 4, */ { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 18: 1, 4, */ { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 19: 0, 1, 4, */ { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 20: 2, 4, */ { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 21: 0, 2, 4, */ { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 22: 1, 2, 4, */ { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 23: 0, 1, 2, 4, */ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, -/* 24: 3, 4, */ { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 25: 0, 3, 4, */ { 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 26: 1, 3, 4, */ { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 27: 0, 1, 3, 4, */ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1 }, -/* 28: 2, 3, 4, */ { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 29: 0, 2, 3, 4, */ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1 }, -/* 30: 1, 2, 3, 4, */ { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, -/* 31: 0, 1, 2, 3, 4, */ { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 32: 5, */ { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 33: 0, 5, */ { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 34: 1, 5, */ { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 35: 0, 1, 5, */ { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 36: 2, 5, */ { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 37: 0, 2, 5, */ { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 38: 1, 2, 5, */ { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 39: 0, 1, 2, 5, */ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1 }, -/* 40: 3, 5, */ { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 41: 0, 3, 5, */ { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 42: 1, 3, 5, */ { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 43: 0, 1, 3, 5, */ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1 }, -/* 44: 2, 3, 5, */ { 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 45: 0, 2, 3, 5, */ { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1 }, -/* 46: 1, 2, 3, 5, */ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1 }, -/* 47: 0, 1, 2, 3, 5, */ { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 48: 4, 5, */ { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 49: 0, 4, 5, */ { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 50: 1, 4, 5, */ { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 51: 0, 1, 4, 5, */ { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 52: 2, 4, 5, */ { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 53: 0, 2, 4, 5, */ { 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1 }, -/* 54: 1, 2, 4, 5, */ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1 }, -/* 55: 0, 1, 2, 4, 5, */ { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 56: 3, 4, 5, */ { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 57: 0, 3, 4, 5, */ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, -/* 58: 1, 3, 4, 5, */ { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1 }, -/* 59: 0, 1, 3, 4, 5, */ { 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 60: 2, 3, 4, 5, */ { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1 }, -/* 61: 0, 2, 3, 4, 5, */ { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1 }, -/* 62: 1, 2, 3, 4, 5, */ { 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1 }, -/* 63: 0, 1, 2, 3, 4, 5, */ { 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 64: 6, */ { 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 65: 0, 6, */ { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 66: 1, 6, */ { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 67: 0, 1, 6, */ { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 68: 2, 6, */ { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 69: 0, 2, 6, */ { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 70: 1, 2, 6, */ { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 71: 0, 1, 2, 6, */ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1 }, -/* 72: 3, 6, */ { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 73: 0, 3, 6, */ { 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 74: 1, 3, 6, */ { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 75: 0, 1, 3, 6, */ { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1 }, -/* 76: 2, 3, 6, */ { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 77: 0, 2, 3, 6, */ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, -/* 78: 1, 2, 3, 6, */ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1 }, -/* 79: 0, 1, 2, 3, 6, */ { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 80: 4, 6, */ { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 81: 0, 4, 6, */ { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 82: 1, 4, 6, */ { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 83: 0, 1, 4, 6, */ { 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1 }, -/* 84: 2, 4, 6, */ { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 85: 0, 2, 4, 6, */ { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1 }, -/* 86: 1, 2, 4, 6, */ { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1 }, -/* 87: 0, 1, 2, 4, 6, */ { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1 }, -/* 88: 3, 4, 6, */ { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 89: 0, 3, 4, 6, */ { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1 }, -/* 90: 1, 3, 4, 6, */ { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1 }, -/* 91: 0, 1, 3, 4, 6, */ { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1 }, -/* 92: 2, 3, 4, 6, */ { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1 }, -/* 93: 0, 2, 3, 4, 6, */ { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1 }, -/* 94: 1, 2, 3, 4, 6, */ { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1 }, -/* 95: 0, 1, 2, 3, 4, 6, */ { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1 }, -/* 96: 5, 6, */ { 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 97: 0, 5, 6, */ { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 98: 1, 5, 6, */ { 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 99: 0, 1, 5, 6, */ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, -/* 100: 2, 5, 6, */ { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 101: 0, 2, 5, 6, */ { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1 }, -/* 102: 1, 2, 5, 6, */ { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 103: 0, 1, 2, 5, 6, */ { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 104: 3, 5, 6, */ { 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 105: 0, 3, 5, 6, */ { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1 }, -/* 106: 1, 3, 5, 6, */ { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1 }, -/* 107: 0, 1, 3, 5, 6, */ { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1 }, -/* 108: 2, 3, 5, 6, */ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1 }, -/* 109: 0, 2, 3, 5, 6, */ { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1 }, -/* 110: 1, 2, 3, 5, 6, */ { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 111: 0, 1, 2, 3, 5, 6, */ { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 112: 4, 5, 6, */ { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 113: 0, 4, 5, 6, */ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1 }, -/* 114: 1, 4, 5, 6, */ { 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1 }, -/* 115: 0, 1, 4, 5, 6, */ { 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 116: 2, 4, 5, 6, */ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, -/* 117: 0, 2, 4, 5, 6, */ { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1 }, -/* 118: 1, 2, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 119: 0, 1, 2, 4, 5, 6, */ { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 120: 3, 4, 5, 6, */ { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1 }, -/* 121: 0, 3, 4, 5, 6, */ { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1 }, -/* 122: 1, 3, 4, 5, 6, */ { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1 }, -/* 123: 0, 1, 3, 4, 5, 6, */ { 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1 }, -/* 124: 2, 3, 4, 5, 6, */ { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1 }, -/* 125: 0, 2, 3, 4, 5, 6, */ { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 126: 1, 2, 3, 4, 5, 6, */ { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1 }, -/* 127: 0, 1, 2, 3, 4, 5, 6, */ { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 128: 7, */ { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 129: 0, 7, */ { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 130: 1, 7, */ { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 131: 0, 1, 7, */ { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 132: 2, 7, */ { 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 133: 0, 2, 7, */ { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 134: 1, 2, 7, */ { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 135: 0, 1, 2, 7, */ { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1 }, -/* 136: 3, 7, */ { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 137: 0, 3, 7, */ { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 138: 1, 3, 7, */ { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 139: 0, 1, 3, 7, */ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1 }, -/* 140: 2, 3, 7, */ { 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 141: 0, 2, 3, 7, */ { 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1 }, -/* 142: 1, 2, 3, 7, */ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1 }, -/* 143: 0, 1, 2, 3, 7, */ { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 144: 4, 7, */ { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 145: 0, 4, 7, */ { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 146: 1, 4, 7, */ { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 147: 0, 1, 4, 7, */ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1 }, -/* 148: 2, 4, 7, */ { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 149: 0, 2, 4, 7, */ { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1 }, -/* 150: 1, 2, 4, 7, */ { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1 }, -/* 151: 0, 1, 2, 4, 7, */ { 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1 }, -/* 152: 3, 4, 7, */ { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 153: 0, 3, 4, 7, */ { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 154: 1, 3, 4, 7, */ { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1 }, -/* 155: 0, 1, 3, 4, 7, */ { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 156: 2, 3, 4, 7, */ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1 }, -/* 157: 0, 2, 3, 4, 7, */ { 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1 }, -/* 158: 1, 2, 3, 4, 7, */ { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1 }, -/* 159: 0, 1, 2, 3, 4, 7, */ { 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 160: 5, 7, */ { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 161: 0, 5, 7, */ { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1 }, -/* 162: 1, 5, 7, */ { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 163: 0, 1, 5, 7, */ { 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1 }, -/* 164: 2, 5, 7, */ { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 165: 0, 2, 5, 7, */ { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1 }, -/* 166: 1, 2, 5, 7, */ { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1 }, -/* 167: 0, 1, 2, 5, 7, */ { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1 }, -/* 168: 3, 5, 7, */ { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 169: 0, 3, 5, 7, */ { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1 }, -/* 170: 1, 3, 5, 7, */ { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1 }, -/* 171: 0, 1, 3, 5, 7, */ { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1 }, -/* 172: 2, 3, 5, 7, */ { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1 }, -/* 173: 0, 2, 3, 5, 7, */ { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1 }, -/* 174: 1, 2, 3, 5, 7, */ { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1 }, -/* 175: 0, 1, 2, 3, 5, 7, */ { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1 }, -/* 176: 4, 5, 7, */ { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 177: 0, 4, 5, 7, */ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1 }, -/* 178: 1, 4, 5, 7, */ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1 }, -/* 179: 0, 1, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 180: 2, 4, 5, 7, */ { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1 }, -/* 181: 0, 2, 4, 5, 7, */ { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1 }, -/* 182: 1, 2, 4, 5, 7, */ { 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1 }, -/* 183: 0, 1, 2, 4, 5, 7, */ { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1 }, -/* 184: 3, 4, 5, 7, */ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1 }, -/* 185: 0, 3, 4, 5, 7, */ { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1 }, -/* 186: 1, 3, 4, 5, 7, */ { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1 }, -/* 187: 0, 1, 3, 4, 5, 7, */ { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 188: 2, 3, 4, 5, 7, */ { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1 }, -/* 189: 0, 2, 3, 4, 5, 7, */ { 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1 }, -/* 190: 1, 2, 3, 4, 5, 7, */ { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 191: 0, 1, 2, 3, 4, 5, 7, */ { 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 192: 6, 7, */ { 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 193: 0, 6, 7, */ { 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 194: 1, 6, 7, */ { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 195: 0, 1, 6, 7, */ { 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1 }, -/* 196: 2, 6, 7, */ { 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 197: 0, 2, 6, 7, */ { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1 }, -/* 198: 1, 2, 6, 7, */ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1 }, -/* 199: 0, 1, 2, 6, 7, */ { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1 }, -/* 200: 3, 6, 7, */ { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 201: 0, 3, 6, 7, */ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1 }, -/* 202: 1, 3, 6, 7, */ { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1 }, -/* 203: 0, 1, 3, 6, 7, */ { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1 }, -/* 204: 2, 3, 6, 7, */ { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 205: 0, 2, 3, 6, 7, */ { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1 }, -/* 206: 1, 2, 3, 6, 7, */ { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1 }, -/* 207: 0, 1, 2, 3, 6, 7, */ { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 208: 4, 6, 7, */ { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 209: 0, 4, 6, 7, */ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1 }, -/* 210: 1, 4, 6, 7, */ { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1 }, -/* 211: 0, 1, 4, 6, 7, */ { 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1 }, -/* 212: 2, 4, 6, 7, */ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1 }, -/* 213: 0, 2, 4, 6, 7, */ { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1 }, -/* 214: 1, 2, 4, 6, 7, */ { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1 }, -/* 215: 0, 1, 2, 4, 6, 7, */ { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 216: 3, 4, 6, 7, */ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1 }, -/* 217: 0, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 218: 1, 3, 4, 6, 7, */ { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1 }, -/* 219: 0, 1, 3, 4, 6, 7, */ { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1 }, -/* 220: 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1 }, -/* 221: 0, 2, 3, 4, 6, 7, */ { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 222: 1, 2, 3, 4, 6, 7, */ { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1 }, -/* 223: 0, 1, 2, 3, 4, 6, 7, */ { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 224: 5, 6, 7, */ { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 225: 0, 5, 6, 7, */ { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1 }, -/* 226: 1, 5, 6, 7, */ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1 }, -/* 227: 0, 1, 5, 6, 7, */ { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1 }, -/* 228: 2, 5, 6, 7, */ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1 }, -/* 229: 0, 2, 5, 6, 7, */ { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1 }, -/* 230: 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1 }, -/* 231: 0, 1, 2, 5, 6, 7, */ { 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1 }, -/* 232: 3, 5, 6, 7, */ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1 }, -/* 233: 0, 3, 5, 6, 7, */ { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1 }, -/* 234: 1, 3, 5, 6, 7, */ { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1 }, -/* 235: 0, 1, 3, 5, 6, 7, */ { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 236: 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1 }, -/* 237: 0, 2, 3, 5, 6, 7, */ { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1 }, -/* 238: 1, 2, 3, 5, 6, 7, */ { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 239: 0, 1, 2, 3, 5, 6, 7, */ { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 240: 4, 5, 6, 7, */ { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 241: 0, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1 }, -/* 242: 1, 4, 5, 6, 7, */ { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1 }, -/* 243: 0, 1, 4, 5, 6, 7, */ { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 244: 2, 4, 5, 6, 7, */ { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1 }, -/* 245: 0, 2, 4, 5, 6, 7, */ { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1 }, -/* 246: 1, 2, 4, 5, 6, 7, */ { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 247: 0, 1, 2, 4, 5, 6, 7, */ { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 248: 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1 }, -/* 249: 0, 3, 4, 5, 6, 7, */ { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 250: 1, 3, 4, 5, 6, 7, */ { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1 }, -/* 251: 0, 1, 3, 4, 5, 6, 7, */ { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 252: 2, 3, 4, 5, 6, 7, */ { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 253: 0, 2, 3, 4, 5, 6, 7, */ { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 254: 1, 2, 3, 4, 5, 6, 7, */ { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, -/* 255: 0, 1, 2, 3, 4, 5, 6, 7, */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } -}; -//_____________________________________________________________________________ - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/MarchingCubes.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/MarchingCubes.cpp deleted file mode 100644 index 0197e8d1b2..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/MarchingCubes.cpp +++ /dev/null @@ -1,850 +0,0 @@ -/** - * @file MarchingCubes.cpp - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.2 - * @date 12/08/2002 - * - * @brief MarchingCubes Algorithm - */ -//________________________________________________ - - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma implementation -#endif // WIN32 - -#include -#include -#include -#include -#include -#include -#include "MarchingCubes.h" -#include "LookUpTable.h" - -// step size of the arrays of vertices and triangles -#define ALLOC_SIZE 65536 - -//_____________________________________________________________________________ -// print cube for debug -void MarchingCubes::print_cube() { printf( "\t%f %f %f %f %f %f %f %f\n", _cube[0], _cube[1], _cube[2], _cube[3], _cube[4], _cube[5], _cube[6], _cube[7]) ; } -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Constructor -MarchingCubes::MarchingCubes() : -//----------------------------------------------------------------------------- - _originalMC(true), - _nverts (0), - _ntrigs (0), - _Nverts (0), - _Ntrigs (0), - _vertices (( Point *)NULL), - _triangles ((Triangle*)NULL) -{} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Destructor -MarchingCubes::~MarchingCubes() -//----------------------------------------------------------------------------- -{ - clean_all() ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// main algorithm -bool MarchingCubes::tesselate_cube( real iso ) -//----------------------------------------------------------------------------- -{ - for( int p = 0 ; p < 8 ; ++p ) - { - real &v = _cube[p] ; - v -= iso ; - if( fabs( v ) < R_EPSILON ) v = R_EPSILON ; -// printf( "%d - %+0.2f\t", (int)_indexes[p], v ) ; - } -// printf( "\n" ) ; - - if( !compute_intersection_points() ) return false ; - - _lut_entry = 0 ; - for( int p = 0 ; p < 8 ; ++p ) - { - if( _cube[p] > 0 ) _lut_entry += 1 << p ; - } - - return process_cube( ) ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// init all structures (must set sizes before call) -void MarchingCubes::init_all () -//----------------------------------------------------------------------------- -{ - _nverts = _ntrigs = 0 ; - _Nverts = _Ntrigs = ALLOC_SIZE ; - _vertices = new Point [_Nverts] ; - _triangles = new Triangle[_Ntrigs] ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// clean temporary structures -void MarchingCubes::clean_temps() -//----------------------------------------------------------------------------- -{ - _stored_vertices.clear() ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// clean all structures -void MarchingCubes::clean_all() -//----------------------------------------------------------------------------- -{ - clean_temps() ; - delete [] _vertices ; - delete [] _triangles ; - _vertices = (Point *)NULL ; - _triangles = (Triangle *)NULL ; - _nverts = _ntrigs = 0 ; - _Nverts = _Ntrigs = 0 ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Compute the intersection points -bool MarchingCubes::compute_intersection_points() -//----------------------------------------------------------------------------- -{ - bool res = false ; - res |= add_vertex( 0,1 ) ; - res |= add_vertex( 1,2 ) ; - res |= add_vertex( 2,3 ) ; - res |= add_vertex( 3,0 ) ; - - res |= add_vertex( 4,5 ) ; - res |= add_vertex( 5,6 ) ; - res |= add_vertex( 6,7 ) ; - res |= add_vertex( 7,4 ) ; - - res |= add_vertex( 0,4 ) ; - res |= add_vertex( 1,5 ) ; - res |= add_vertex( 2,6 ) ; - res |= add_vertex( 3,7 ) ; - - return res ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Test a face -// if face>0 return true if the face contains a part of the surface -bool MarchingCubes::test_face( schar face ) -//----------------------------------------------------------------------------- -{ - real A,B,C,D ; - - switch( face ) - { - case -1 : case 1 : A = _cube[0] ; B = _cube[4] ; C = _cube[5] ; D = _cube[1] ; break ; - case -2 : case 2 : A = _cube[1] ; B = _cube[5] ; C = _cube[6] ; D = _cube[2] ; break ; - case -3 : case 3 : A = _cube[2] ; B = _cube[6] ; C = _cube[7] ; D = _cube[3] ; break ; - case -4 : case 4 : A = _cube[3] ; B = _cube[7] ; C = _cube[4] ; D = _cube[0] ; break ; - case -5 : case 5 : A = _cube[0] ; B = _cube[3] ; C = _cube[2] ; D = _cube[1] ; break ; - case -6 : case 6 : A = _cube[4] ; B = _cube[7] ; C = _cube[6] ; D = _cube[5] ; break ; - default : printf( "Invalid face code %d\n", face ) ; print_cube() ; A = B = C = D = 0 ; - }; - - if( fabs( A*C - B*D ) < R_EPSILON ) - return face >= 0 ; - return face * A * ( A*C - B*D ) >= 0 ; // face and A invert signs -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Test the interior of a cube -// if s == 7, return true if the interior is empty -// if s ==-7, return false if the interior is empty -bool MarchingCubes::test_interior( schar s ) -//----------------------------------------------------------------------------- -{ - real t, At=0, Bt=0, Ct=0, Dt=0, a, b ; - char test = 0 ; - char edge = -1 ; // reference edge of the triangulation - - switch( _case ) - { - case 4 : - case 10 : - case 13 : - a = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ; - b = _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] ) - - _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ; - t = - b / (2*a) ; - if( t<0 || t>1 ) return s>0 ; - - At = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - break ; - - case 6 : - case 7 : - case 12 : - switch( _case ) - { - case 6 : edge = test6 [_config][2] ; break ; - case 7 : edge = test7 [_config][4] ; break ; - case 12 : edge = test12[_config][3] ; break ; - } - switch( edge ) - { - case 0 : - t = _cube[0] / ( _cube[0] - _cube[1] ) ; - At = 0 ; - Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ; - Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ; - Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ; - break ; - case 1 : - t = _cube[1] / ( _cube[1] - _cube[2] ) ; - At = 0 ; - Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ; - Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ; - Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ; - break ; - case 2 : - t = _cube[2] / ( _cube[2] - _cube[3] ) ; - At = 0 ; - Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ; - Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ; - Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ; - break ; - case 3 : - t = _cube[3] / ( _cube[3] - _cube[0] ) ; - At = 0 ; - Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ; - Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ; - Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ; - break ; - case 4 : - t = _cube[4] / ( _cube[4] - _cube[5] ) ; - At = 0 ; - Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ; - Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ; - Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ; - break ; - case 5 : - t = _cube[5] / ( _cube[5] - _cube[6] ) ; - At = 0 ; - Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ; - Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ; - Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ; - break ; - case 6 : - t = _cube[6] / ( _cube[6] - _cube[7] ) ; - At = 0 ; - Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ; - Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ; - Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ; - break ; - case 7 : - t = _cube[7] / ( _cube[7] - _cube[4] ) ; - At = 0 ; - Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ; - Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ; - Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ; - break ; - case 8 : - t = _cube[0] / ( _cube[0] - _cube[4] ) ; - At = 0 ; - Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - break ; - case 9 : - t = _cube[1] / ( _cube[1] - _cube[5] ) ; - At = 0 ; - Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - break ; - case 10 : - t = _cube[2] / ( _cube[2] - _cube[6] ) ; - At = 0 ; - Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - break ; - case 11 : - t = _cube[3] / ( _cube[3] - _cube[7] ) ; - At = 0 ; - Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - break ; - default : printf( "Invalid edge %d\n", edge ) ; print_cube() ; break ; - } - break ; - - default : printf( "Invalid ambiguous case %d\n", _case ) ; print_cube() ; break ; - } - - if( At >= 0 ) test ++ ; - if( Bt >= 0 ) test += 2 ; - if( Ct >= 0 ) test += 4 ; - if( Dt >= 0 ) test += 8 ; - switch( test ) - { - case 0 : return s>0 ; - case 1 : return s>0 ; - case 2 : return s>0 ; - case 3 : return s>0 ; - case 4 : return s>0 ; - case 5 : if( At * Ct - Bt * Dt < R_EPSILON ) return s>0 ; break ; - case 6 : return s>0 ; - case 7 : return s<0 ; - case 8 : return s>0 ; - case 9 : return s>0 ; - case 10 : if( At * Ct - Bt * Dt >= R_EPSILON ) return s>0 ; break ; - case 11 : return s<0 ; - case 12 : return s>0 ; - case 13 : return s<0 ; - case 14 : return s<0 ; - case 15 : return s<0 ; - } - - return s<0 ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Process a unit cube -bool MarchingCubes::process_cube( ) -//----------------------------------------------------------------------------- -{ - if( _originalMC ) - { - char nt = 0 ; - while( casesClassic[_lut_entry][3*nt] != -1 ) nt++ ; - add_triangle( casesClassic[_lut_entry], nt ) ; - return true ; - } - - int v12 = -1 ; - _case = cases[_lut_entry][0] ; - _config = cases[_lut_entry][1] ; - _subconfig = 0 ; - - switch( _case ) - { - case 0 : - break ; - - case 1 : - add_triangle( tiling1[_config], 1 ) ; - break ; - - case 2 : - add_triangle( tiling2[_config], 2 ) ; - break ; - - case 3 : - if( test_face( test3[_config]) ) - add_triangle( tiling3_2[_config], 4 ) ; // 3.2 - else - add_triangle( tiling3_1[_config], 2 ) ; // 3.1 - break ; - - case 4 : - if( test_interior( test4[_config]) ) - add_triangle( tiling4_1[_config], 2 ) ; // 4.1.1 - else - add_triangle( tiling4_2[_config], 6 ) ; // 4.1.2 - break ; - - case 5 : - add_triangle( tiling5[_config], 3 ) ; - break ; - - case 6 : - if( test_face( test6[_config][0]) ) - add_triangle( tiling6_2[_config], 5 ) ; // 6.2 - else - { - if( test_interior( test6[_config][1]) ) - add_triangle( tiling6_1_1[_config], 3 ) ; // 6.1.1 - else - { - v12 = add_c_vertex() ; - add_triangle( tiling6_1_2[_config], 9 , v12) ; // 6.1.2 - } - } - break ; - - case 7 : - if( test_face( test7[_config][0] ) ) _subconfig += 1 ; - if( test_face( test7[_config][1] ) ) _subconfig += 2 ; - if( test_face( test7[_config][2] ) ) _subconfig += 4 ; - switch( _subconfig ) - { - case 0 : - add_triangle( tiling7_1[_config], 3 ) ; break ; - case 1 : - add_triangle( tiling7_2[_config][0], 5 ) ; break ; - case 2 : - add_triangle( tiling7_2[_config][1], 5 ) ; break ; - case 3 : - v12 = add_c_vertex() ; - add_triangle( tiling7_3[_config][0], 9, v12 ) ; break ; - case 4 : - add_triangle( tiling7_2[_config][2], 5 ) ; break ; - case 5 : - v12 = add_c_vertex() ; - add_triangle( tiling7_3[_config][1], 9, v12 ) ; break ; - case 6 : - v12 = add_c_vertex() ; - add_triangle( tiling7_3[_config][2], 9, v12 ) ; break ; - case 7 : - if( test_interior( test7[_config][3]) ) - add_triangle( tiling7_4_2[_config], 9 ) ; - else - add_triangle( tiling7_4_1[_config], 5 ) ; - break ; - }; - break ; - - case 8 : - add_triangle( tiling8[_config], 2 ) ; - break ; - - case 9 : - add_triangle( tiling9[_config], 4 ) ; - break ; - - case 10 : - if( test_face( test10[_config][0]) ) - { - if( test_face( test10[_config][1]) ) - add_triangle( tiling10_1_1_[_config], 4 ) ; // 10.1.1 - else - { - v12 = add_c_vertex() ; - add_triangle( tiling10_2[_config], 8, v12 ) ; // 10.2 - } - } - else - { - if( test_face( test10[_config][1]) ) - { - v12 = add_c_vertex() ; - add_triangle( tiling10_2_[_config], 8, v12 ) ; // 10.2 - } - else - { - if( test_interior( test10[_config][2]) ) - add_triangle( tiling10_1_1[_config], 4 ) ; // 10.1.1 - else - add_triangle( tiling10_1_2[_config], 8 ) ; // 10.1.2 - } - } - break ; - - case 11 : - add_triangle( tiling11[_config], 4 ) ; - break ; - - case 12 : - if( test_face( test12[_config][0]) ) - { - if( test_face( test12[_config][1]) ) - add_triangle( tiling12_1_1_[_config], 4 ) ; // 12.1.1 - else - { - v12 = add_c_vertex() ; - add_triangle( tiling12_2[_config], 8, v12 ) ; // 12.2 - } - } - else - { - if( test_face( test12[_config][1]) ) - { - v12 = add_c_vertex() ; - add_triangle( tiling12_2_[_config], 8, v12 ) ; // 12.2 - } - else - { - if( test_interior( test12[_config][2]) ) - add_triangle( tiling12_1_1[_config], 4 ) ; // 12.1.1 - else - add_triangle( tiling12_1_2[_config], 8 ) ; // 12.1.2 - } - } - break ; - - case 13 : - if( test_face( test13[_config][0] ) ) _subconfig += 1 ; - if( test_face( test13[_config][1] ) ) _subconfig += 2 ; - if( test_face( test13[_config][2] ) ) _subconfig += 4 ; - if( test_face( test13[_config][3] ) ) _subconfig += 8 ; - if( test_face( test13[_config][4] ) ) _subconfig += 16 ; - if( test_face( test13[_config][5] ) ) _subconfig += 32 ; - switch( subconfig13[_subconfig] ) - { - case 0 :/* 13.1 */ - add_triangle( tiling13_1[_config], 4 ) ; break ; - - case 1 :/* 13.2 */ - add_triangle( tiling13_2[_config][0], 6 ) ; break ; - case 2 :/* 13.2 */ - add_triangle( tiling13_2[_config][1], 6 ) ; break ; - case 3 :/* 13.2 */ - add_triangle( tiling13_2[_config][2], 6 ) ; break ; - case 4 :/* 13.2 */ - add_triangle( tiling13_2[_config][3], 6 ) ; break ; - case 5 :/* 13.2 */ - add_triangle( tiling13_2[_config][4], 6 ) ; break ; - case 6 :/* 13.2 */ - add_triangle( tiling13_2[_config][5], 6 ) ; break ; - - case 7 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][0], 10, v12 ) ; break ; - case 8 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][1], 10, v12 ) ; break ; - case 9 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][2], 10, v12 ) ; break ; - case 10 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][3], 10, v12 ) ; break ; - case 11 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][4], 10, v12 ) ; break ; - case 12 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][5], 10, v12 ) ; break ; - case 13 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][6], 10, v12 ) ; break ; - case 14 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][7], 10, v12 ) ; break ; - case 15 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][8], 10, v12 ) ; break ; - case 16 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][9], 10, v12 ) ; break ; - case 17 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][10], 10, v12 ) ; break ; - case 18 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3[_config][11], 10, v12 ) ; break ; - - case 19 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][0], 12, v12 ) ; break ; - case 20 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][1], 12, v12 ) ; break ; - case 21 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][2], 12, v12 ) ; break ; - case 22 :/* 13.4 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_4[_config][3], 12, v12 ) ; break ; - - case 23 :/* 13.5 */ - _subconfig = 0 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][0], 6 ) ; - else - add_triangle( tiling13_5_2[_config][0], 10 ) ; - break ; - case 24 :/* 13.5 */ - _subconfig = 1 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][1], 6 ) ; - else - add_triangle( tiling13_5_2[_config][1], 10 ) ; - break ; - case 25 :/* 13.5 */ - _subconfig = 2 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][2], 6 ) ; - else - add_triangle( tiling13_5_2[_config][2], 10 ) ; - break ; - case 26 :/* 13.5 */ - _subconfig = 3 ; - if( test_interior( test13[_config][6] ) ) - add_triangle( tiling13_5_1[_config][3], 6 ) ; - else - add_triangle( tiling13_5_2[_config][3], 10 ) ; - break ; - - case 27 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][0], 10, v12 ) ; break ; - case 28 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][1], 10, v12 ) ; break ; - case 29 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][2], 10, v12 ) ; break ; - case 30 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][3], 10, v12 ) ; break ; - case 31 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][4], 10, v12 ) ; break ; - case 32 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][5], 10, v12 ) ; break ; - case 33 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][6], 10, v12 ) ; break ; - case 34 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][7], 10, v12 ) ; break ; - case 35 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][8], 10, v12 ) ; break ; - case 36 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][9], 10, v12 ) ; break ; - case 37 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][10], 10, v12 ) ; break ; - case 38 :/* 13.3 */ - v12 = add_c_vertex() ; - add_triangle( tiling13_3_[_config][11], 10, v12 ) ; break ; - - case 39 :/* 13.2 */ - add_triangle( tiling13_2_[_config][0], 6 ) ; break ; - case 40 :/* 13.2 */ - add_triangle( tiling13_2_[_config][1], 6 ) ; break ; - case 41 :/* 13.2 */ - add_triangle( tiling13_2_[_config][2], 6 ) ; break ; - case 42 :/* 13.2 */ - add_triangle( tiling13_2_[_config][3], 6 ) ; break ; - case 43 :/* 13.2 */ - add_triangle( tiling13_2_[_config][4], 6 ) ; break ; - case 44 :/* 13.2 */ - add_triangle( tiling13_2_[_config][5], 6 ) ; break ; - - case 45 :/* 13.1 */ - add_triangle( tiling13_1_[_config], 4 ) ; break ; - - default : - printf("Marching Cubes: Impossible case 13?\n" ) ; print_cube() ; - } - break ; - - case 14 : - add_triangle( tiling14[_config], 4 ) ; - break ; - }; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Adding triangles -void MarchingCubes::add_triangle( const char* trig_, char n, int v12 ) -//----------------------------------------------------------------------------- -{ - int tv[3] ; - - for( int t = 0 ; t < 3*n ; t++ ) - { - switch( trig_[t] ) - { - case 0 : tv[ t % 3 ] = get_vertex(0,1) ; break ; - case 1 : tv[ t % 3 ] = get_vertex(1,2) ; break ; - case 2 : tv[ t % 3 ] = get_vertex(2,3) ; break ; - case 3 : tv[ t % 3 ] = get_vertex(3,0) ; break ; - case 4 : tv[ t % 3 ] = get_vertex(4,5) ; break ; - case 5 : tv[ t % 3 ] = get_vertex(5,6) ; break ; - case 6 : tv[ t % 3 ] = get_vertex(6,7) ; break ; - case 7 : tv[ t % 3 ] = get_vertex(7,4) ; break ; - case 8 : tv[ t % 3 ] = get_vertex(0,4) ; break ; - case 9 : tv[ t % 3 ] = get_vertex(1,5) ; break ; - case 10 : tv[ t % 3 ] = get_vertex(2,6) ; break ; - case 11 : tv[ t % 3 ] = get_vertex(3,7) ; break ; - case 12 : tv[ t % 3 ] = v12 ; break ; - default : break ; - } - - if( tv[t%3] == -1 ) - { - printf("Marching Cubes: invalid triangle %d\n", _ntrigs+1) ; - print_cube() ; - } - - if( t%3 == 2 ) - { - if( _ntrigs >= _Ntrigs ) - { - Triangle *temp = _triangles ; - _triangles = new Triangle[ 2*_Ntrigs ] ; - memcpy( _triangles, temp, _Ntrigs*sizeof(Triangle) ) ; - delete[] temp ; - printf("%d allocated triangles\n", _Ntrigs) ; - _Ntrigs *= 2 ; - } - - Triangle *T = _triangles + _ntrigs++ ; - T->v1 = tv[0] ; - T->v2 = tv[1] ; - T->v3 = tv[2] ; - } - } -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Adding vertices - -void MarchingCubes::test_vertex_addition() -{ - if( _nverts >= _Nverts ) - { - Point *temp = _vertices ; - _vertices = new Point [ _Nverts*2 ] ; - memcpy( _vertices, temp, _Nverts*sizeof(Point ) ) ; - delete[] temp ; - printf("%d allocated vertices\n", _Nverts) ; - _Nverts *= 2 ; - } -} - - -bool MarchingCubes::add_vertex( char i, char j ) -//----------------------------------------------------------------------------- -{ - real ci = _cube[i] ; - real cj = _cube[j] ; - if( ci * cj >= 0 ) return false ; - - Key ki = _indexes[i] ; - Key kj = _indexes[j] ; - std::pair ij_key = std::make_pair( ki,kj ) ; - if( _stored_vertices.find( ij_key ) != _stored_vertices.end() ) return true ; - - test_vertex_addition() ; - - Point p ; - _dat_access->interpolate( ci,cj, _space[i],_space[j], p ) ; - - _stored_vertices[ ij_key ] = _nverts ; - _stored_vertices[ std::make_pair( kj,ki ) ] = _nverts ; - _vertices[_nverts++] = p ; - - return true ; -} -//----------------------------------------------------------------------------- - -int MarchingCubes::add_c_vertex( ) -//----------------------------------------------------------------------------- -{ - test_vertex_addition() ; - Point &vert_ = _vertices[_nverts++] ; - - real u = 0 ; - int vid ; - - vert_.x() = vert_.y() = vert_.z() = 0 ; - - // Computes the average of the intersection points of the cube - vid = get_vertex( 0,1 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 1,2 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 2,3 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 3,0 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 4,5 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 5,6 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 6,7 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 7,4 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 0,4 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 1,5 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 2,6 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - vid = get_vertex( 3,7 ) ; if( vid != -1 ) { ++u ; vert_ += _vertices[vid] ; } - - vert_ /= u ; - - return _nverts-1 ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// OFF ascii exportation -void MarchingCubes::writeOFF(const char *fn ) -//----------------------------------------------------------------------------- -{ - FILE *fp = fopen( fn, "w" ) ; - int i ; - - printf("Marching Cubes::exportOFF(%s)...", fn) ; - - fprintf( fp, "OFF\n%d %d 0\n", _nverts, _ntrigs ) ; - for ( i = 0; i < _nverts; i++ ) - fprintf( fp, " %f %f %f\n", _vertices[i].x(), _vertices[i].y(), _vertices[i].z() ) ; - printf(" %d vertices written\n", _nverts ) ; - - for ( i = 0; i < _ntrigs; i++ ) - fprintf( fp, "3 %d %d %d\n", _triangles[i].v1, _triangles[i].v2, _triangles[i].v3 ) ; - fclose( fp ) ; - printf(" %d triangles written\n", _ntrigs ) ; -} -//_____________________________________________________________________________ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/MarchingCubes.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/MarchingCubes.h deleted file mode 100644 index 9be9aff343..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/MarchingCubes.h +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @file MarchingCubes.h - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.2 - * @date 12/08/2002 - * - * @brief MarchingCubes Algorithm - */ -//________________________________________________ - - -#pragma once - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma interface -#endif // WIN32 - -#include -#include "morton.h" -#include "point.h" -#include "data_access.h" - -//----------------------------------------------------------------------------- -// Triangle structure -/** \struct Triangle "MarchingCubes.h" MarchingCubes - * Indices of the oriented triange vertices - * \brief triangle structure - * \param v1 First vertex index - * \param v2 Second vertex index - * \param v3 Third vertex index - */ -typedef struct -{ - int v1,v2,v3 ; /**< Triangle vertices */ -} Triangle ; -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -/** Marching Cubes algorithm wrapper */ -/** \class MarchingCubes - * \brief Marching Cubes algorithm. - */ -class MarchingCubes -//----------------------------------------------------------------------------- -{ -// Constructors -public : - /** - * Main and default constructor - * \brief constructor - */ - MarchingCubes () ; - /** Destructor */ - ~MarchingCubes() ; - -//----------------------------------------------------------------------------- -// Accessors -public : - /** accesses the number of vertices of the generated mesh */ - inline const int nverts() const { return _nverts ; } - /** accesses the number of triangles of the generated mesh */ - inline const int ntrigs() const { return _ntrigs ; } - /** accesses a specific vertex of the generated mesh */ - inline Point * vert( const int i ) const { if( i < 0 || i >= _nverts ) return ( Point *)NULL ; return _vertices + i ; } - /** accesses a specific triangle of the generated mesh */ - inline Triangle * trig( const int i ) const { if( i < 0 || i >= _ntrigs ) return (Triangle*)NULL ; return _triangles + i ; } - - /** accesses the vertex buffer of the generated mesh */ - inline Point *vertices () { return _vertices ; } - /** accesses the triangle buffer of the generated mesh */ - inline Triangle *triangles() { return _triangles ; } - - /** - * selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes - * \param originalMC true for the original Marching Cubes - */ - inline void set_method ( const bool originalMC = false ) { _originalMC = originalMC ; } - - // Data initialization - /** inits all structures (must set sizes before call) : the temporary structures and the mesh buffers */ - void init_all () ; - /** clears temporary structures : the grid and the main */ - void clean_temps() ; - /** clears all structures : the temporary structures and the mesh buffers */ - void clean_all () ; - - -//----------------------------------------------------------------------------- -// Exportation -public : - /** - * OFF exportation of the generated mesh - * \param fn name of the IV file to create - */ - void writeOFF( const char *fn ) ; - - -//----------------------------------------------------------------------------- -// Algorithm -public : - /** retrieves the isovalues at the cube vertices */ - real *cube () { return _cube ; } - /** retrieves the geometry of the cube */ - Point *space () { return _space; } - /** retrieves the indexes of the cube */ - Key *indexes() { return _indexes; } - /** retrieves the data accessor */ - data_access *&dat_access() { return _dat_access ; } - /** - * Main algorithm - * \param iso isovalue - */ - bool tesselate_cube( real iso ) ; - -protected : - /** tesselates one cube */ - bool process_cube () ; - /** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */ - bool test_face ( schar face ) ; - /** tests if the components of the tesselation of the cube should be connected through the interior of the cube */ - bool test_interior( schar s ) ; - - -//----------------------------------------------------------------------------- -// Operations -protected : - /** computes almost all the vertices of the mesh by interpolation along the cubes edges */ - bool compute_intersection_points() ; - - /** - * routine to add a triangle to the mesh - * \param trig the code for the triangle as a sequence of edges index - * \param n the number of triangles to produce - * \param v12 the index of the interior vertex to use, if necessary - */ - void add_triangle ( const char* trig, char n, int v12 = -1 ) ; - - /** tests and eventually doubles the vertex buffer capacity for a new vertex insertion */ - void test_vertex_addition() ; - /** adds a vertex on edge cube[i] cube[j] */ - bool add_vertex( char i, char j ) ; - /** gets the vertex of edge cube[i] cube[j] (no check) */ - int get_vertex( char i, char j ) { std::map< std::pair< Key,Key >, int >::const_iterator it = _stored_vertices.find( std::make_pair( _indexes[i],_indexes[j] ) ) ; if( it == _stored_vertices.end() ) return -1 ; else return it->second ; } - /** adds a vertex inside the current cube */ - int add_c_vertex() ; - - /** prints cube for debug */ - void print_cube() ; - -public: - /** draw the surface using openGL */ - void draw_surf() { Triangle *ptr = _triangles ; for( int i = 0 ; i < _ntrigs ; ++i, ++ptr ) { _vertices[ptr->v1].draw() ; _vertices[ptr->v2].draw() ; _vertices[ptr->v3].draw() ; } } - -//----------------------------------------------------------------------------- -// Elements -protected : - bool _originalMC ; /**< selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes */ - - int _nverts ; /**< number of allocated vertices in the vertex buffer */ - int _ntrigs ; /**< number of allocated triangles in the triangle buffer */ - int _Nverts ; /**< size of the vertex buffer */ - int _Ntrigs ; /**< size of the triangle buffer */ - Point *_vertices ; /**< vertex buffer */ - Triangle *_triangles ; /**< triangle buffer */ - - std::map< std::pair< Key,Key >, int > _stored_vertices ; - - real _cube[8] ; /**< values of the implicit function on the active cube */ - Point _space[8] ; /**< coordinates of the active cube */ - Key _indexes[8] ; /**< indiexs of the active cube */ - uchar _lut_entry ; /**< cube sign representation in [0..255] */ - uchar _case ; /**< case of the active cube in [0..15] */ - uchar _config ; /**< configuration of the active cube */ - uchar _subconfig ; /**< subconfiguration of the active cube */ - data_access *_dat_access ; /**< data accessor */ -}; -//_____________________________________________________________________________ - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/README.txt b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/README.txt deleted file mode 100644 index 01cb605922..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/README.txt +++ /dev/null @@ -1,123 +0,0 @@ - - Statistical optimization of octree searches - Fast generation of pointerless octree duals ---------------------------------------------------- -Rener Castro, Thomas Lewiner, HŽlio Lopes, Geovan Tavares, Alex Bordignon -Thomas Lewiner, Vin’cius Mello, Adelailson Peixoto, SinŽsio Pesco, HŽlio Lopes - - -http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=octree_cgf -http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=fastdualoctree_sgp - -1. Disclaimer -2. Available code compared to the papers -3. Octrees implementations -4. Morton codes -5. Data -6. Hash table -7. Requirements - - -Disclaimer --------------- - This code is implements fast searches and the dual generation of static -or dynamic pointer-based or pointerless octrees. It is provided "as is" -and can be used freely. We just ask the users who would use this code to -mention in their academic paper, patent or software documentation the -original articles: - -@article{octree_cgf, - author = {Rener Castro and Thomas Lewiner and HŽlio Lopes and Geovan Tavares and Alex Bordignon}, - title = {Statistical optimization of octree searches}, - year = {2008}, - month = {march}, - journal = {Computer Graphics Forum}, - volume = {27}, - number = {6}, - pages = {1557--1566}, - publisher = {Eurographics}, - doi = {10.1111/j.1467-8659.2007.01104.x}, - url = {\url{http://www.matmidia.mat.puc-rio.br/tomlew/pdfs/octree_cgf.pdf}} -} - -@article{fastdualoctree_sgp, - author = {Thomas Lewiner and Vin’cius Mello and Adelailson Peixoto and SinŽsio Pesco and HŽlio Lopes}, - title = {Fast Generation of Pointerless Octree Duals}, - year = {2010}, - month = {july}, - journal = {Symposium on Geometry Processing 2010}, - booktitle = {Computer Graphics Forum}, - volume = {29}, - number = {5}, - pages = {1661--1669}, - publisher = {Wiley}, - address = {Lyon, France}, - url = {\url{http://www.matmidia.mat.puc-rio.br/tomlew/pdfs/fastdualoctree_sgp.pdf}} -} - - - -If you have any comment, correction, question, please feel free to -contact me at : lewiner@gmail.com . -Thank to David Coeurjolly for the code porting to UNIX. - - - - -Available code compared to the paper ----------------------------------------------- - The code contains simple implementations used to generate the result of -our papers. We stripped down the time measurements (which are platform -specific) and the robust dual marching cubes -(http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=adaptive_implicit_sibgrapi) -code. - - - -Octrees implementations ------------------------------- - The code contains implementations of a pointer-based octree -("ptr_octree.*" files), pointerless octrees with recursive dual -generation ("hash_octree.*"), pointerless octrees with optimized dual -generation for the static strategy representing all the nodes -("opt_octree.*") or only the leaves ("leaf_octree.*"), and the dynamic -strategy ("mem_octree.*"). The octree is chosen at compilation time -through the OCTREE_SWITCH macro. - - -Morton codes ------------------ - The Morton code operations in dilated integers are all grouped in the -"morton.*" files. - - -Data ------- - The data (implicit function or isogrid) is accessed through the -data_access class. The isogrid must be in "iso" format, i.e. a binary -file with 32-bits integers nx, ny and nz for the size of the grid, -32-bits floats xmin, xmax, yminÉ for the geometry of the cube, followed -by nx.ny.nz 32-bits floats for the data. - - -Hash table -------------- - Finally, we made a very simple naive and simple implementations for the -hashtable, in open ("hash_ptr.h") or close ("has_noptr.h") modes. The -parameters of the hash function are chosen at compilation time through -macros defined in the "hash.h" file. - - -Requirements ------------- - - The graphical interfaces require the openGL libraries with the GLU, glut -and glui extension, available at http://glui.sourceforge.net/ . - - We use Juha Nieminen, Joel Yliluoma's function parser for the implicit -function, and our Marching Cube's implementation -(http://www.matmidia.mat.puc-rio.br/tomlew/publication_page.php?pubkey=marching_cubes_jgt). - - -Thank you for your interest, and have fun! -http://www.matmidia.mat.puc-rio.br/tomlew/ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/cube.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/cube.h deleted file mode 100644 index dc0652f9b3..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/cube.h +++ /dev/null @@ -1,256 +0,0 @@ -/** - * \file cube.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * \brief Simple cube class - * - * Simple cube class - */ -//_____________________________________________________________________________ - - - -#pragma once - - -#include "point.h" - -typedef uchar Level ; -extern Level L_INV ; - -//_____________________________________________________________________________ -/// Simple cube class -class Cube : public Point -{ - // Elements -protected : - Level _lv ; ///< cube level (from 0 on): cube corners have coordinates c(xyz) (+/-) (1/2^(lv+1)) - - //----------------------------------------------------------------------------- - // Constructors -public: - /// Default constructor - Cube( const real &cx_ = R_INV, const real &cy_ = R_INV, const real &cz_ = R_INV, Level lv_ = L_INV ) - : Point(cx_,cy_,cz_), _lv(lv_) {} - - /// Default constructor - Cube( const Point& c_, Level lv_ = L_INV ) - : Point(c_), _lv(lv_) {} - - /// Default constructor - Cube( const Cube& c_ ) - : Point((const Point&)c_), _lv(c_._lv) {} - - /// Destructor - ~Cube() {} - - /// Assignment operator - Cube &operator= ( const Cube &c ) - { Point::operator=(c) ; _lv = c._lv ; return *this; } - - //----------------------------------------------------------------------------- - // Accessors -public: - /// const accessor for point center: x coordinate - real cx() const { return Point::x() ; } - /// accessor for point center: x coordinate - real &cx() { return Point::x() ; } - - /// const accessor for point center: y coordinate - real cy() const { return Point::y() ; } - /// accessor for point center: y coordinate - real &cy() { return Point::y() ; } - - /// const accessor for point center: z coordinate - real cz() const { return Point::z() ; } - /// accessor for point center: z coordinate - real &cz() { return Point::z() ; } - - /// const accessor for a coordinate - real coord( Axis a ) const { return Point::operator[](a) ; } - /// accessor for a coordinate - real &coord( Axis a ) { return Point::operator[](a) ; } - - - /// const accessor for the cube half size - real sz() const { return (real)1.0 / (2<<_lv) ; } - /// const accessor for cube level - Level lv() const { return _lv ; } - /// accessor for cube level - Level &lv() { return _lv ; } - - /// const accessor for cube center: min x coordinate - real xmin() const { return cx() - sz() ; } - /// const accessor for cube center: max x coordinate - real xmax() const { return cx() + sz() ; } - - /// const accessor for cube center: min y coordinate - real ymin() const { return cy() - sz() ; } - /// const accessor for cube center: max y coordinate - real ymax() const { return cy() + sz() ; } - - /// const accessor for cube center: min z coordinate - real zmin() const { return cz() - sz() ; } - /// const accessor for cube center: max z coordinate - real zmax() const { return cz() + sz() ; } - - /// const accessor for cube center: min coordinate - real coordmin( Axis a ) const { return coord(a) - this->sz() ; } - /// const accessor for cube center: max coordinate - real coordmax( Axis a ) const { return coord(a) + this->sz() ; } - - //------------------------------------------------ - // Test -public : - /// conained - bool contains( const real &x_, const real &y_, const real &z_ ) const - { - real sz_ = sz() ; - return - ( fabs(x_-cx()) <= sz_ ) && - ( fabs(y_-cy()) <= sz_ ) && - ( fabs(z_-cz()) <= sz_ ) ; - } - - /// conained - bool contains( const Point &p ) const { return contains( p.x(), p.y(), p.z() ) ; } - - /// epsilon-conained - bool contains( const real &x_, const real &y_, const real &z_, const real &epsilon ) const - { - real sz_ = sz() + epsilon ; - return - ( fabs(x_-cx()) <= sz_ ) && - ( fabs(y_-cy()) <= sz_ ) && - ( fabs(z_-cz()) <= sz_ ) ; - } - - /// epsilon-conained - bool contains( const Point &p, const real &epsilon ) const { return contains( p.x(), p.y(), p.z(), epsilon ) ; } - - //----------------------------------------------------------------------------- - // Drawing -public: - /// Draws the cube center with opengl - void draw_center () const { ::glVertex3f( (float)x(), (float)y(), (float)z() ) ; } - - /// Draws the cube corners with opengl - void draw_corners( real fact = 0.9 ) const - { - const float ix = (const float) x() ; - const float iy = (const float) y() ; - const float iz = (const float) z() ; - const float is = (const float) (fact*sz()) ; - - ::glVertex3f( ix-is, iy-is, iz-is ) ; - ::glVertex3f( ix+is, iy-is, iz-is ) ; - ::glVertex3f( ix-is, iy+is, iz-is ) ; - ::glVertex3f( ix+is, iy+is, iz-is ) ; - ::glVertex3f( ix-is, iy-is, iz+is ) ; - ::glVertex3f( ix+is, iy-is, iz+is ) ; - ::glVertex3f( ix-is, iy+is, iz+is ) ; - ::glVertex3f( ix+is, iy+is, iz+is ) ; - } - - /// Draws the cube wire with opengl - void draw_wire ( real fact = 0.9 ) const - { - const float ix = (const float) x() ; - const float iy = (const float) y() ; - const float iz = (const float) z() ; - const float is = (const float) (fact*sz()) ; - - ::glVertex3f( ix-is, iy-is, iz-is ) ; - ::glVertex3f( ix-is, iy+is, iz-is ) ; - - ::glVertex3f( ix-is, iy-is, iz-is ) ; - ::glVertex3f( ix+is, iy-is, iz-is ) ; - - ::glVertex3f( ix+is, iy-is, iz-is ) ; - ::glVertex3f( ix+is, iy+is, iz-is ) ; - - ::glVertex3f( ix-is, iy+is, iz-is ) ; - ::glVertex3f( ix+is, iy+is, iz-is ) ; - - - ::glVertex3f( ix-is, iy-is, iz+is ) ; - ::glVertex3f( ix-is, iy+is, iz+is ) ; - - ::glVertex3f( ix-is, iy-is, iz+is ) ; - ::glVertex3f( ix+is, iy-is, iz+is ) ; - - ::glVertex3f( ix+is, iy-is, iz+is ) ; - ::glVertex3f( ix+is, iy+is, iz+is ) ; - - ::glVertex3f( ix-is, iy+is, iz+is ) ; - ::glVertex3f( ix+is, iy+is, iz+is ) ; - - - ::glVertex3f( ix-is, iy-is, iz-is ) ; - ::glVertex3f( ix-is, iy-is, iz+is ) ; - - ::glVertex3f( ix+is, iy-is, iz-is ) ; - ::glVertex3f( ix+is, iy-is, iz+is ) ; - - ::glVertex3f( ix-is, iy+is, iz-is ) ; - ::glVertex3f( ix-is, iy+is, iz+is ) ; - - ::glVertex3f( ix+is, iy+is, iz-is ) ; - ::glVertex3f( ix+is, iy+is, iz+is ) ; - } - - - - /// Draws the cube wire with opengl - void draw_fill ( real fact = 0.9 ) const - { - const float ix = (const float) x() ; - const float iy = (const float) y() ; - const float iz = (const float) z() ; - const float is = (const float) (fact*sz()) ; - - ::glNormal3f(0,0,-1); - ::glVertex3f( ix-is, iy-is, iz-is ) ; - ::glVertex3f( ix-is, iy+is, iz-is ) ; - ::glVertex3f( ix+is, iy+is, iz-is ) ; - ::glVertex3f( ix+is, iy-is, iz-is ) ; - - ::glNormal3f(0,0,1); - ::glVertex3f( ix-is, iy-is, iz+is ) ; - ::glVertex3f( ix-is, iy+is, iz+is ) ; - ::glVertex3f( ix+is, iy+is, iz+is ) ; - ::glVertex3f( ix+is, iy-is, iz+is ) ; - - ::glNormal3f(-1,0,0); - ::glVertex3f( ix-is, iy-is, iz-is ) ; - ::glVertex3f( ix-is, iy+is, iz-is ) ; - ::glVertex3f( ix-is, iy+is, iz+is ) ; - ::glVertex3f( ix-is, iy-is, iz+is ) ; - - ::glNormal3f(1,0,0); - ::glVertex3f( ix+is, iy-is, iz-is ) ; - ::glVertex3f( ix+is, iy+is, iz-is ) ; - ::glVertex3f( ix+is, iy+is, iz+is ) ; - ::glVertex3f( ix+is, iy-is, iz+is ) ; - - ::glNormal3f(0,-1,0); - ::glVertex3f( ix-is, iy-is, iz-is ) ; - ::glVertex3f( ix-is, iy-is, iz+is ) ; - ::glVertex3f( ix+is, iy-is, iz+is ) ; - ::glVertex3f( ix+is, iy-is, iz-is ) ; - - ::glNormal3f(0,1,0); - ::glVertex3f( ix-is, iy+is, iz-is ) ; - ::glVertex3f( ix-is, iy+is, iz+is ) ; - ::glVertex3f( ix+is, iy+is, iz+is ) ; - ::glVertex3f( ix+is, iy+is, iz-is ) ; - } -}; -//_____________________________________________________________________________ - -// Invalid cube -extern Cube C_INV ; - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/data_access.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/data_access.cpp deleted file mode 100644 index a536fda18c..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/data_access.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/** - * @file data_access.cpp - * \author Thomas Lewiner - * \author Math Dept, PUC-Rio - * \author Matmidia Labs - * \date 14/02/2006 - * - * @brief data accesss - */ -//________________________________________________ - - - -#ifndef WIN32 -#pragma implementation -#endif // WIN32 - -#include "data_access.h" - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// data_func - -//_____________________________________________________________________________ -// crossing data access: parser -void data_func::parse() -//----------------------------------------------------------------------------- -{ - if( _formula.empty() ) - return ; - std::string vars("x,y,z") ; - int i = _parser.Parse( _formula, vars ) ; - if( _parser.GetParseErrorType() != FunctionParser::FP_NO_ERROR ) - printf( "%s\n%s\n% *d\n", _parser.ErrorMsg(), _formula.c_str(), i, 1 ) ; - else - _parser.Optimize() ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// crossing data access -bool data_func::need_refine( const Cube &c ) -//----------------------------------------------------------------------------- -{ - if( _parser.GetParseErrorType() != FunctionParser::FP_NO_ERROR ) return false ; - int l = c.lv() ; - if( l < 2 ) return true ; - if( l >= _max_level ) return false ; - - real cx = c.cx() ; - real cy = c.cy() ; - real cz = c.cz() ; - _v[X] = cx ; - _v[Y] = cy ; - _v[Z] = cz ; - - real ref_val = _parser.Eval(_v) - _iso_val ; - if( fabs(ref_val) < R_EPSILON ) return true ; - - real sz = c.sz() ; - for( _v[X] = cx-sz ; _v[X] <= cx+sz ; _v[X] += sz ) - { - for( _v[Y] = cy-sz ; _v[Y] <= cy+sz ; _v[Y] += sz ) - { - for( _v[Z] = cz-sz ; _v[Z] <= cz+sz ; _v[Z] += sz ) - { - real val = _parser.Eval(_v) - _iso_val ; - if( ref_val * val < 0 ) return true ; - } - } - } - - return false ; -} -//_____________________________________________________________________________ - - -#ifndef BISSEC_ITER -#define BISSEC_ITER 3 -#endif // BISSEC_ITER - -//_____________________________________________________________________________ -// interpolation function -void data_func::interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p ) -//----------------------------------------------------------------------------- -{ - real u ; - Point qi = pi ; - Point qj = pj ; - for( int i = 0 ; i < BISSEC_ITER ; ++i ) - { - u = ( ci ) / ( ci - cj ) ; - p = ((1-u)*qi) + (u*qj) ; - - real c = value_at(p) ; - if( c*ci < 0 ) - { - qj = p ; - cj = c ; - } - else if( c*cj < 0 ) - { - qi = p ; - ci = c ; - } - else break ; - } - u = ( ci ) / ( ci - cj ) ; - p = ((1-u)*qi) + (u*qj) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// data_file - - -#include -#include -#include - -//_____________________________________________________________________________ -// data data access: load file -bool data_file::load_data( const char *fn ) -//----------------------------------------------------------------------------- -{ - errno = 0; - gzFile isofile = gzopen( fn, "rb" ) ; - if( !isofile ) - { - printf( "data_file::load_data couldn't open file %s: %s\n", fn, strerror (errno)); - return false ; - } - - // read size - unsigned char buf[sizeof(float)] ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - _size_x = * (int*)buf ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - _size_y = * (int*)buf ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - _size_z = * (int*)buf ; - - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - float xmin = * (float*)buf ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - float xmax = * (float*)buf ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - float ymin = * (float*)buf ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - float ymax = * (float*)buf ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - float zmin = * (float*)buf ; - if( gzread( isofile, buf, sizeof(float) ) < 1 ) return false ; - float zmax = * (float*)buf ; - - // allocate data - delete [] _data ; - _size_yz = _size_z * _size_y ; - uint total_size = _size_x * _size_yz ; - if( total_size == 0 ) return false ; - - // cube fitting - _max_size = _size_x ; - if( _max_size < _size_y ) _max_size = _size_y ; - if( _max_size < _size_z ) _max_size = _size_z ; - Level p = (Level)floor( log(_max_size)/log(2) ) ; - if( _max_size != (1< max_field ) max_field = v ; - } - - gzclose( isofile ) ; - - printf( "data %s: %dx%dx%d, field originally in [ %f , %f ]\n", fn, (int)_size_x, (int)_size_y, (int)_size_z, min_field, max_field ) ; - - // rescale data in [-1.1] - float v_scale = 2.0 / (max_field - min_field) ; - data_ptr = _data ; - for( uint i = 0 ; i < total_size ; ++i, ++data_ptr ) - { - *data_ptr = v_scale * ( (*data_ptr) - min_field ) - 1.0 ; - } - - // cube scaling - _sx = (xmax - xmin)/_size_x ; - _sy = (ymax - ymin)/_size_y ; - _sz = (zmax - zmin)/_size_z ; - float s = _sx ; - if( s < _sy ) s = _sy ; - if( s < _sz ) s = _sz ; - _sx /= s ; - _sy /= s ; - _sz /= s ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// data data access -bool data_file::need_refine( const Cube &c ) -//----------------------------------------------------------------------------- -{ - int l = c.lv() ; - if( l < 2 ) return true ; - if( l >= _max_level ) return false ; - - // ajustar se o dado nao for cubico! - real sz = c.sz() ; - uint i = floor( (c.cx()-sz) * _max_size ) ; - uint iM = ceil ( (c.cx()+sz) * _max_size ) ; - uint j = floor( (c.cy()-sz) * _max_size ) ; - uint jM = ceil ( (c.cy()+sz) * _max_size ) ; - uint k = floor( (c.cz()-sz) * _max_size ) ; - uint kM = ceil ( (c.cz()+sz) * _max_size ) ; - - if( iM >= _size_x ) iM = _size_x-1 ; - if( jM >= _size_y ) jM = _size_y-1 ; - if( kM >= _size_z ) kM = _size_z-1 ; - - float iso_min = get_data(iM,jM,kM) ; - float iso_max = iso_min ; - for( ; i <= iM ; ++i ) - { - for( ; j <= jM ; ++j ) - { - for( ; k <= kM ; ++k ) - { - float iso = get_data(i,j,k) ; - if( iso_min > iso ) iso_min = iso ; - if( iso_max < iso ) iso_max = iso ; - - if( iso_min*iso_max < 0 ) return true ; - } - } - } - - return false ; -} -//_____________________________________________________________________________ - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/data_access.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/data_access.h deleted file mode 100644 index 2574333e23..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/data_access.h +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @file data_access.h - * \author Thomas Lewiner - * \author Math Dept, PUC-Rio - * \author Matmidia Labs - * \date 14/02/2006 - * - * @brief data accesss - */ -//________________________________________________ - - -#pragma once - -#ifndef WIN32 -#pragma interface -#endif // WIN32 - -#include -#include -#include "cube.h" - - -//_____________________________________________________________________________ -/// data access abstract class -class data_access -//_____________________________________________________________________________ -{ - public : - Level _max_level; ///< maximal level of a cell - real _iso_val; ///< iso value - float _sx ; ///< grid x proportion - float _sy ; ///< grid y proportion - float _sz ; ///< grid z proportion - - - public : - /// constructor - data_access( Level max_level_ = 4, real iso_val_ = 0.0 ) : _max_level(max_level_), _iso_val(iso_val_), _sx(1.0f), _sy(1.0f), _sz(1.0f) {} - /// destructor - virtual ~data_access() {} - /// test function - virtual bool need_refine( const Cube &c ) = 0 ; - /// data function - virtual real value_at ( const Cube &c ) = 0 ; - /// interpolation function - virtual void interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p ) - { - real u = ( ci ) / ( ci - cj ) ; - p = ((1-u)*pi) + (u*pj) ; - } -} ; -//----------------------------------------------------------------------------- - - - -// may be overridden by the preprocessor -#ifndef RAND_THRES -# define RAND_THRES 0.2 -#endif // RAND_THRES - -//_____________________________________________________________________________ -/// basic data access -class data_rand : public data_access -//----------------------------------------------------------------------------- -{ -public: - /// test function - bool need_refine( const Cube &c ) - { - int l = c.lv() ; - if( l < 2 ) return true ; - if( l >= _max_level ) return false ; - return value_at(c) > RAND_THRES ; - } - - /// data function - real value_at( const Cube &c ) { return ( (real)rand() ) / ( RAND_MAX >> 1 ) - 1.0 ; } - - /// interpolation function - void interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p ) - { - real u = ( (real)rand() ) / ( RAND_MAX ) ; - p = ((1-u)*pi) + (u*pj) ; - } - - //----------------------------------------------------------------------------- - // Basics -public: - /// default constructor - data_rand( Level max_level_ ) : data_access(max_level_) {} - /// destructor - virtual ~data_rand() {} -} ; -//_____________________________________________________________________________ - - - -#include "fptypes.h" -#include "fparser.h" - -//_____________________________________________________________________________ -/// function crossing data access -class data_func : public data_access -//----------------------------------------------------------------------------- -{ -public: - /// implicit function - std::string _formula ; - -protected: - double _v[3] ; - FunctionParser _parser ; - -protected: - void parse() ; - -public: - /// test function - bool need_refine( const Cube &c ) ; - - /// data function - real value_at( const Cube &c ) - { - if( _parser.GetParseErrorType() != FunctionParser::FP_NO_ERROR ) return false ; - _v[X] = c.cx() ; - _v[Y] = c.cy() ; - _v[Z] = c.cz() ; - real v = _parser.Eval(_v) - _iso_val ; - if( _parser.EvalError() ) return -1.0 ; - return v ; - } - - /// interpolation function - void interpolate( real ci, real cj, const Point &pi, const Point &pj, Point &p ) ; - - //----------------------------------------------------------------------------- - // Basics -public: - /// default constructor - data_func( Level max_level_, real iso_val_, const std::string &formula_ ) : data_access(max_level_,iso_val_), _formula(formula_) { parse() ; } - /// destructor - virtual ~data_func() {} -} ; -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -/// iso file data access -class data_file : public data_access -//----------------------------------------------------------------------------- -{ -public: - uint _size_x ; ///< width of the grid - uint _size_y ; ///< depth of the grid - uint _size_z ; ///< height of the grid - -protected: - float *_data ; /**< implicit function values sampled on the grid */ - uint _size_yz ; /**< k skip size */ - uint _max_size ; /**< bigger side to fit into the cube */ - - -public: - bool load_data ( const char *fn ) ; - bool has_data ( uint i, uint j, uint k ) { return (i < _size_x) && (j < _size_y) && (k < _size_z) ; } - float get_data ( uint i, uint j, uint k ) { return _data[ k + j*_size_z + i*_size_yz] - _iso_val ; } - - /// test function - bool need_refine( const Cube &c ) ; - /// data function - real value_at( const Cube &c ) - { - uint i = (uint)(c.cx()*_max_size) ; - uint j = (uint)(c.cy()*_max_size) ; - uint k = (uint)(c.cz()*_max_size) ; - if( has_data(i,j,k) ) return (real)get_data(i,j,k) ; - return -1.0 ; - } - // linear interpolation: no specification - - //----------------------------------------------------------------------------- - // Basics -public: - /// default constructor - data_file( Level max_level_, real iso_val_, const char *fn ) : data_access(max_level_,iso_val_), _data((float*)NULL) { load_data( fn ) ; } - /// destructor - virtual ~data_file() {} -} ; -//_____________________________________________________________________________ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fp_identifier_parser.inc b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fp_identifier_parser.inc deleted file mode 100644 index 723c80d74e..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fp_identifier_parser.inc +++ /dev/null @@ -1,292 +0,0 @@ - unsigned nameLength = 0; - const unsigned maximumNameLength = 0x80000000U-8; - /* - Due to the manner the identifier lengths are returned from - the readOpcode() function, the maximum supported length for - identifiers is 0x7FFFFFFF bytes. We minus 8 here to add some - buffer, because of the multibyteness of UTF-8. - Function names are limited to 0xFFFF bytes instead, but because - function names that long just are not defined, the point is moot. - */ - const unsigned char* const uptr = (const unsigned char*) input; - typedef signed char schar; - while(likely(nameLength < maximumNameLength)) - { - unsigned char byte = uptr[nameLength+0]; - /* Handle the common case of A-Za-z first */ - if(byte >= 0x40) - { - if(byte < 0x80) // 0x40..0x7F - most common case - { - // Valid characters in 40..7F: A-Za-z_ - // Valid bitmask for 40..5F: 01111111111111111111111111100001 - // Valid bitmask for 60..7F: 01111111111111111111111111100000 - if(sizeof(unsigned long) == 8) - { - const unsigned n = sizeof(unsigned long)*8-32; - // ^ avoids compiler warning when not 64-bit - unsigned long masklow6bits = 1UL << (byte & 0x3F); - if(masklow6bits & ~((1UL << 0) | (0x0FUL << (0x1B )) - | (1UL << n) | (0x1FUL << (0x1B+n)))) - { ++nameLength; continue; } - } - else - { - unsigned masklow5bits = 1 << (byte & 0x1F); - if((masklow5bits & ~(1 | (0x1F << 0x1B))) || byte == '_') - { ++nameLength; continue; } - } - break; - } - if(byte < 0xF0) - { - if(byte < 0xE0) - { - if(byte < 0xC2) break; // 0x80..0xC1 - if(byte == 0xC2 && uptr[nameLength+1]==0xA0) break; // skip nbsp - // C2-DF - next common case when >= 0x40 - // Valid sequence: C2-DF 80-BF - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - nameLength += 2; - continue; - } - if(byte == 0xE0) // E0 - { - // Valid sequence: E0 A0-BF 80-BF - if((unsigned char)(uptr[nameLength+1] - 0xA0) > (0xBF-0xA0)) break; - } - else - { - if(byte == 0xED) break; // ED is invalid - // Valid sequence: E1-EC 80-BF 80-BF - // And: EE-EF 80-BF 80-BF - if(byte == 0xE2) - { - // break on various space characters - if(uptr[nameLength+1] == 0x80 - && (schar(uptr[nameLength+2]) <= schar(0x8B) - || (uptr[nameLength+2] == 0xAF))) break; - if(uptr[nameLength+1] == 0x81 - && uptr[nameLength+2] == 0x9F) break; - } else - if(byte == 0xE3 && uptr[nameLength+1] == 0x80 - && uptr[nameLength+2] == 0x80) break; // this too - - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - } - if(schar(uptr[nameLength+2]) > schar(0xBF)) break; - nameLength += 3; - continue; - } - if(byte == 0xF0) // F0 - { - // Valid sequence: F0 90-BF 80-BF 80-BF - if((unsigned char)(uptr[nameLength+1] - 0x90) > (0xBF-0x90)) break; - } - else - { - if(byte > 0xF4) break; // F5-FF are invalid - if(byte == 0xF4) // F4 - { - // Valid sequence: F4 80-8F - if(schar(uptr[nameLength+1]) > schar(0x8F)) break; - } - else - { - // F1-F3 - // Valid sequence: F1-F3 80-BF 80-BF 80-BF - if(schar(uptr[nameLength+1]) > schar(0xBF)) break; - } - } - if(schar(uptr[nameLength+2]) > schar(0xBF)) break; - if(schar(uptr[nameLength+3]) > schar(0xBF)) break; - nameLength += 4; - continue; - } - if(nameLength > 0) - { - if(sizeof(unsigned long) == 8) - { - // Valid bitmask for 00..1F: 00000000000000000000000000000000 - // Valid bitmask for 20..3F: 00000000000000001111111111000000 - const unsigned n = sizeof(unsigned long)*8-32; - // ^ avoids compiler warning when not 64-bit - unsigned long masklow6bits = 1UL << byte; - if(masklow6bits & (((1UL << 10)-1UL) << (16+n))) - { ++nameLength; continue; } - } - else - { - if(byte >= '0' && byte <= '9') - { ++nameLength; continue; } - } - } - break; - } - - /* This function generated with make_function_name_parser.cc */ - switch(nameLength) - { - case 2: - /* prefix */if('i' == uptr[0] - && 'f' == uptr[1]) return Functions[cIf].enabled() ? (cIf<<16) | 0x80000002U : 2; - return 2; - case 3: - /* prefix */switch(uptr[0]) { - case 'a': - /* prefix a */if('b' == uptr[1] - && 's' == uptr[2]) return Functions[cAbs].enabled() ? (cAbs<<16) | 0x80000003U : 3; - return 3; - case 'c': - /* prefix c */switch(uptr[1]) { - case 'o': - /* prefix co */switch(uptr[2]) { - case 's': - /* prefix cos */return Functions[cCos].enabled() ? (cCos<<16) | 0x80000003U : 3; - case 't': - /* prefix cot */return Functions[cCot].enabled() ? (cCot<<16) | 0x80000003U : 3; - default: return 3; } - case 's': - /* prefix cs */if('c' == uptr[2]) return Functions[cCsc].enabled() ? (cCsc<<16) | 0x80000003U : 3; - return 3; - default: return 3; } - case 'e': - /* prefix e */if('x' == uptr[1] - && 'p' == uptr[2]) return Functions[cExp].enabled() ? (cExp<<16) | 0x80000003U : 3; - return 3; - case 'i': - /* prefix i */if('n' == uptr[1] - && 't' == uptr[2]) return Functions[cInt].enabled() ? (cInt<<16) | 0x80000003U : 3; - return 3; - case 'l': - /* prefix l */if('o' == uptr[1] - && 'g' == uptr[2]) return Functions[cLog].enabled() ? (cLog<<16) | 0x80000003U : 3; - return 3; - case 'm': - /* prefix m */switch(uptr[1]) { - case 'a': - /* prefix ma */if('x' == uptr[2]) return Functions[cMax].enabled() ? (cMax<<16) | 0x80000003U : 3; - return 3; - case 'i': - /* prefix mi */if('n' == uptr[2]) return Functions[cMin].enabled() ? (cMin<<16) | 0x80000003U : 3; - return 3; - default: return 3; } - case 'p': - /* prefix p */if('o' == uptr[1] - && 'w' == uptr[2]) return Functions[cPow].enabled() ? (cPow<<16) | 0x80000003U : 3; - return 3; - case 's': - /* prefix s */switch(uptr[1]) { - case 'e': - /* prefix se */if('c' == uptr[2]) return Functions[cSec].enabled() ? (cSec<<16) | 0x80000003U : 3; - return 3; - case 'i': - /* prefix si */if('n' == uptr[2]) return Functions[cSin].enabled() ? (cSin<<16) | 0x80000003U : 3; - return 3; - default: return 3; } - case 't': - /* prefix t */if('a' == uptr[1] - && 'n' == uptr[2]) return Functions[cTan].enabled() ? (cTan<<16) | 0x80000003U : 3; - return 3; - default: return 3; } - case 4: - /* prefix */switch(uptr[0]) { - case 'a': - /* prefix a */switch(uptr[1]) { - case 'c': - /* prefix ac */if('o' == uptr[2] - && 's' == uptr[3]) return Functions[cAcos].enabled() ? (cAcos<<16) | 0x80000004U : 4; - return 4; - case 's': - /* prefix as */if('i' == uptr[2] - && 'n' == uptr[3]) return Functions[cAsin].enabled() ? (cAsin<<16) | 0x80000004U : 4; - return 4; - case 't': - /* prefix at */if('a' == uptr[2] - && 'n' == uptr[3]) return Functions[cAtan].enabled() ? (cAtan<<16) | 0x80000004U : 4; - return 4; - default: return 4; } - case 'c': - /* prefix c */switch(uptr[1]) { - case 'b': - /* prefix cb */if('r' == uptr[2] - && 't' == uptr[3]) return Functions[cCbrt].enabled() ? (cCbrt<<16) | 0x80000004U : 4; - return 4; - case 'e': - /* prefix ce */if('i' == uptr[2] - && 'l' == uptr[3]) return Functions[cCeil].enabled() ? (cCeil<<16) | 0x80000004U : 4; - return 4; - case 'o': - /* prefix co */if('s' == uptr[2] - && 'h' == uptr[3]) return Functions[cCosh].enabled() ? (cCosh<<16) | 0x80000004U : 4; - return 4; - default: return 4; } - case 'e': - /* prefix e */switch(uptr[1]) { - case 'v': - /* prefix ev */if('a' == uptr[2] - && 'l' == uptr[3]) return Functions[cEval].enabled() ? (cEval<<16) | 0x80000004U : 4; - return 4; - case 'x': - /* prefix ex */if('p' == uptr[2] - && '2' == uptr[3]) return Functions[cExp2].enabled() ? (cExp2<<16) | 0x80000004U : 4; - return 4; - default: return 4; } - case 'l': - /* prefix l */{static const char tmp[3] = {'o','g','2'}; - if(std::memcmp(uptr+1, tmp, 3) == 0) return Functions[cLog2].enabled() ? (cLog2<<16) | 0x80000004U : 4; - return 4; } - case 's': - /* prefix s */switch(uptr[1]) { - case 'i': - /* prefix si */if('n' == uptr[2] - && 'h' == uptr[3]) return Functions[cSinh].enabled() ? (cSinh<<16) | 0x80000004U : 4; - return 4; - case 'q': - /* prefix sq */if('r' == uptr[2] - && 't' == uptr[3]) return Functions[cSqrt].enabled() ? (cSqrt<<16) | 0x80000004U : 4; - return 4; - default: return 4; } - case 't': - /* prefix t */{static const char tmp[3] = {'a','n','h'}; - if(std::memcmp(uptr+1, tmp, 3) == 0) return Functions[cTanh].enabled() ? (cTanh<<16) | 0x80000004U : 4; - return 4; } - default: return 4; } - case 5: - /* prefix */switch(uptr[0]) { - case 'a': - /* prefix a */switch(uptr[1]) { - case 'c': - /* prefix ac */{static const char tmp[3] = {'o','s','h'}; - if(std::memcmp(uptr+2, tmp, 3) == 0) return Functions[cAcosh].enabled() ? (cAcosh<<16) | 0x80000005U : 5; - return 5; } - case 's': - /* prefix as */{static const char tmp[3] = {'i','n','h'}; - if(std::memcmp(uptr+2, tmp, 3) == 0) return Functions[cAsinh].enabled() ? (cAsinh<<16) | 0x80000005U : 5; - return 5; } - case 't': - /* prefix at */if('a' == uptr[2]) { - /* prefix ata */if('n' == uptr[3]) { - /* prefix atan */switch(uptr[4]) { - case '2': - /* prefix atan2 */return Functions[cAtan2].enabled() ? (cAtan2<<16) | 0x80000005U : 5; - case 'h': - /* prefix atanh */return Functions[cAtanh].enabled() ? (cAtanh<<16) | 0x80000005U : 5; - default: return 5; } - }return 5;}return 5;default: return 5; } - case 'f': - /* prefix f */{static const char tmp[4] = {'l','o','o','r'}; - if(std::memcmp(uptr+1, tmp, 4) == 0) return Functions[cFloor].enabled() ? (cFloor<<16) | 0x80000005U : 5; - return 5; } - case 'l': - /* prefix l */{static const char tmp[4] = {'o','g','1','0'}; - if(std::memcmp(uptr+1, tmp, 4) == 0) return Functions[cLog10].enabled() ? (cLog10<<16) | 0x80000005U : 5; - return 5; } - case 't': - /* prefix t */{static const char tmp[4] = {'r','u','n','c'}; - if(std::memcmp(uptr+1, tmp, 4) == 0) return Functions[cTrunc].enabled() ? (cTrunc<<16) | 0x80000005U : 5; - return 5; } - default: return 5; } - default: break; - } - return nameLength; diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fp_opcode_add.inc b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fp_opcode_add.inc deleted file mode 100644 index 47e29382ff..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fp_opcode_add.inc +++ /dev/null @@ -1,4279 +0,0 @@ -/* Function Parser for C++ v4.0.3 - - Note: This file contains generated code and is thus not - intended to be to be modified by hand. It was generated by - fpoptimizer/bytecoderules_parser which is available in the - development package. - - Note: You don't need to add this file to your project. It's - enough for it to be in the same directory as fparser.cc. This - file is internally #included by fparser.cc. -*/ - -#define FP_TRACE_OPCODENAME(op) \ - (op < VarBegin \ - ? FP_GetOpcodeName(OPCODE(op)) \ - : findName(data->namePtrs,op,NameData::VARIABLE)) -#define FP_TRACE_BYTECODE_OPTIMIZATION(srcline,from,to,with) \ - /*std::cout << "Changing \"" from "\"\t(line " #srcline ")\n" \ - " into \"" to "\"\n" with*/ - - static unsigned DummyOpList[1] = {cNop}; - /* DummyOpList is needed to prevent crash when 1+x - * is changed into x+1 and the bytecode containing just "x" - * is tested against the rule which changes "x x" into "x cDup". - */ - unsigned* ByteCodePtr; - Value_t* ImmedPtr; - - #define FP_ReDefinePointers() \ - ByteCodePtr = !data->ByteCode.empty() ? &data->ByteCode[0] + data->ByteCode.size() - 1 : &DummyOpList[0]; \ - ImmedPtr = !data->Immed.empty() ? &data->Immed[0] + data->Immed.size() - 1 : 0; - FP_ReDefinePointers(); - -#if(!FP_FLOAT_VERSION) - Value_t x; - unsigned A; - Value_t y; - unsigned B; - unsigned C; - unsigned D; - switch(opcode) - { - TailCall_cAbs: - case cAbs: - switch(ByteCodePtr[0]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(189,"cNeg cAbs", "cAbs", ""); - /* opcode = cAbs; */ // redundant, matches cAbs @ 0 - goto Laa; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(40, - "x cAbs", - "[fp_abs(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lab; - default: - A = ByteCodePtr[0]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(244, - "A[IsNeverNegativeValueOpcode(A)] cAbs", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[0] = A; */ // redundant, matches A @ 1 - return; - } - } - goto Default0; - TailCall_cAdd: - case cAdd: - switch(ByteCodePtr[0]) - { - case cDup: - if(ByteCodePtr[-1] == cAdd) - { - if(ByteCodePtr[-2] == cDup) - { - FP_TRACE_BYTECODE_OPTIMIZATION(108,"cDup cAdd cDup cAdd", "[Value_t(4)] cMul", ""); - goto Lac; - } - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(196,"cNeg cAdd", "cSub", ""); - goto Lad; - case cImmed: - x = ImmedPtr[0]; - switch(ByteCodePtr[-1]) - { - case cAdd: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(142, - "y cAdd x cAdd", - "[y+x] cAdd", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cAdd; */ // redundant, matches cAdd @ 0 - goto Lae; - } - break; - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(76, - "y x cAdd", - "[y+x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Laf; - } - if(x==Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(75, - "x[x==Value_t(0)] cAdd", - "", - " with x = " << x << "\n"); - goto Lag; - } - break; - } - goto Default0; - TailCall_cAnd: - case cAnd: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(131, - "y x cAnd", - "[truthValue(x)&&truthValue(y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lah; - } - } - goto Default0; - TailCall_cDiv: - case cDiv: - switch(ByteCodePtr[0]) - { - case cDup: - FP_TRACE_BYTECODE_OPTIMIZATION(121,"cDup cDiv", "[Value_t(0)] cMul [Value_t(1)] cAdd", ""); - goto Lai; - case cImmed: - x = ImmedPtr[0]; - if(x!=Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(139, - "cNeg x[x!=Value_t(0)] cDiv", - "[-x] cDiv", - " with x = " << x << "\n"); - /* opcode = cDiv; */ // redundant, matches cDiv @ 0 - goto Laj; - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(73, - "y x[x!=Value_t(0)] cDiv", - "[y/x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lak; - } - } - if(x==Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(72, - "x[x==Value_t(1)] cDiv", - "", - " with x = " << x << "\n"); - goto Lag; - } - break; - } - goto Default0; - TailCall_cEqual: - case cEqual: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(1)) - { - A = ByteCodePtr[-1]; - if(IsLogicalOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(272, - "A[IsLogicalOpcode(A)] x[x==Value_t(1)] cEqual", - "A", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lag; - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(129, - "y x cEqual", - "[fp_equal(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lal; - } - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(208, - "cAbs x[x==Value_t(0)] cEqual", - "[x] cEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cEqual; */ // redundant, matches cEqual @ 0 - goto Lam; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(210, - "cSqr x[x==Value_t(0)] cEqual", - "[x] cEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cEqual; */ // redundant, matches cEqual @ 0 - goto Lam; - } - FP_TRACE_BYTECODE_OPTIMIZATION(262, - "x[x==Value_t(0)] cEqual", - "cNot", - " with x = " << x << "\n"); - goto Lan; - } - } - goto Default0; - TailCall_cGreater: - case cGreater: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(264, - "cAbs x[x==Value_t(0)] cGreater", - "cNotNot", - " with x = " << x << "\n"); - goto Lao; - default: - A = ByteCodePtr[-1]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(268, - "A[IsNeverNegativeValueOpcode(A)] x[x==Value_t(0)] cGreater", - "A cNotNot", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lap; - } - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(127, - "y x cGreater", - "[fp_less(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lba; - } - } - goto Default0; - TailCall_cGreaterOrEq: - case cGreaterOrEq: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(1)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(265, - "cAbs x[x==Value_t(1)] cGreaterOrEq", - "cNotNot", - " with x = " << x << "\n"); - goto Lao; - default: - A = ByteCodePtr[-1]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(269, - "A[IsNeverNegativeValueOpcode(A)] x[x==Value_t(1)] cGreaterOrEq", - "A cNotNot", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lap; - } - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(128, - "y x cGreaterOrEq", - "[fp_lessOrEq(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lbb; - } - } - goto Default0; - TailCall_cInv: - case cInv: - switch(ByteCodePtr[0]) - { - case cInv: - FP_TRACE_BYTECODE_OPTIMIZATION(190,"cInv cInv", "", ""); - goto Lbc; - case cSqrt: - FP_TRACE_BYTECODE_OPTIMIZATION(67,"cSqrt cInv", "cRSqrt", ""); - goto Lbd; - case cImmed: - x = ImmedPtr[0]; - if(x!=Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(69, - "x[x!=Value_t(0)] cInv", - "[Value_t(1)/x]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lbe; - } - break; - } - goto Default0; - TailCall_cLess: - case cLess: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(1)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(266, - "cAbs x[x==Value_t(1)] cLess", - "cNot", - " with x = " << x << "\n"); - goto Lbf; - default: - A = ByteCodePtr[-1]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(270, - "A[IsNeverNegativeValueOpcode(A)] x[x==Value_t(1)] cLess", - "A cNot", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lan; - } - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(125, - "y x cLess", - "[fp_less(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lbg; - } - } - goto Default0; - TailCall_cLessOrEq: - case cLessOrEq: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(267, - "cAbs x[x==Value_t(0)] cLessOrEq", - "cNot", - " with x = " << x << "\n"); - goto Lbf; - default: - A = ByteCodePtr[-1]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(271, - "A[IsNeverNegativeValueOpcode(A)] x[x==Value_t(0)] cLessOrEq", - "A cNot", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lan; - } - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(126, - "y x cLessOrEq", - "[fp_lessOrEq(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lbh; - } - } - goto Default0; - TailCall_cMax: - case cMax: - switch(ByteCodePtr[0]) - { - case cDup: - FP_TRACE_BYTECODE_OPTIMIZATION(111,"cDup cMax", "", ""); - goto Lbc; - case cImmed: - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(82, - "y x cMax", - "[Max(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lbi; - } - break; - default: - A = ByteCodePtr[0]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-1]) - { - case cDup: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(113, - "B[B==A] cDup A[A>=VarBegin] cMax", - "B cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cDup; */ // redundant, matches cDup @ 2 - goto Lbc; - } - break; - case cMax: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(115, - "B[B==A] cMax A[A>=VarBegin] cMax", - "B cMax", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cMax; */ // redundant, matches cMax @ 2 - goto Lbc; - } - break; - } - } - } - goto Default0; - TailCall_cMin: - case cMin: - switch(ByteCodePtr[0]) - { - case cDup: - FP_TRACE_BYTECODE_OPTIMIZATION(110,"cDup cMin", "", ""); - goto Lbc; - case cImmed: - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(81, - "y x cMin", - "[Min(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lbj; - } - break; - default: - A = ByteCodePtr[0]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-1]) - { - case cDup: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(112, - "B[B==A] cDup A[A>=VarBegin] cMin", - "B cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cDup; */ // redundant, matches cDup @ 2 - goto Lbc; - } - break; - case cMin: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(114, - "B[B==A] cMin A[A>=VarBegin] cMin", - "B cMin", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cMin; */ // redundant, matches cMin @ 2 - goto Lbc; - } - break; - } - } - } - goto Default0; - TailCall_cMod: - case cMod: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x!=Value_t(0)) - { - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(74, - "y x[x!=Value_t(0)] cMod", - "[fp_mod(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lbk; - } - } - } - goto Default0; - TailCall_cMul: - case cMul: - switch(ByteCodePtr[0]) - { - case cDup: - FP_TRACE_BYTECODE_OPTIMIZATION(338,"cDup cMul", "cSqr", ""); - goto Lbl; - case cInv: - FP_TRACE_BYTECODE_OPTIMIZATION(195,"cInv cMul", "cDiv", ""); - goto Lbm; - case cNeg: - A = ByteCodePtr[-1]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-2]) - { - case cMul: - B = ByteCodePtr[-3]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(330, - "B[B==A] cMul A[A>=VarBegin] cNeg cMul", - "B cSqr cMul cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-3] = B; */ // redundant, matches B @ 4 - goto Lbn; - } - goto Default1; - default: Default1:; - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(324, - "B[B==A] A[A>=VarBegin] cNeg cMul", - "B cSqr cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - goto Lbo; - } - } - } - goto Default2; - case cImmed: - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cMul: - A = ByteCodePtr[-2]; - if(A>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(94, - "A[A>=VarBegin] cMul x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lbp; - } - goto Default3; - default: Default3:; - A = ByteCodePtr[-1]; - if(IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)) - { - switch(ByteCodePtr[-2]) - { - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(93, - "y A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lca; - default: - B = ByteCodePtr[-2]; - if(IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)) - { - switch(ByteCodePtr[-3]) - { - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(97, - "y B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", y = " << y - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lcb; - default: - C = ByteCodePtr[-3]; - if(C>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(95, - "C[C>=VarBegin] B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lcc; - } - if(IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(96, - "C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "B A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lcd; - } - } - } - if(B>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(91, - "B[B>=VarBegin] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lbp; - } - if(IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(92, - "B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lce; - } - } - } - if(A>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(89, - "A[A>=VarBegin] x[x==Value_t(0)] cMul", - "[x]", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - goto Lcf; - } - if(IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(90, - "A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lcg; - } - } - } - switch(ByteCodePtr[-1]) - { - case cAdd: - if(ByteCodePtr[-2] == cDup) - { - if(x+x==Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(148, - "cDup[x+x==Value_t(1)] cAdd x cMul", - "", - " with x = " << x << "\n"); - goto Lch; - } - FP_TRACE_BYTECODE_OPTIMIZATION(149, - "cDup cAdd x cMul", - "[x+x] cMul", - " with x = " << x << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lci; - } - break; - case cMul: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - if(y*x==Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(146, - "y[y*x==Value_t(1)] cMul x cMul", - "", - " with x = " << x - << ", y = " << y - << "\n"); - goto Lcj; - } - FP_TRACE_BYTECODE_OPTIMIZATION(147, - "y cMul x cMul", - "[y*x] cMul", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lck; - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(136, - "cNeg x cMul", - "[-x] cMul", - " with x = " << x << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lcl; - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(71, - "y x cMul", - "[y*x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lcm; - } - if(x==Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(70, - "x[x==Value_t(1)] cMul", - "", - " with x = " << x << "\n"); - goto Lag; - } - if(x==Value_t(2)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(100, - "x[x==Value_t(2)] cMul", - "cDup cAdd", - " with x = " << x << "\n"); - goto Lcn; - } - if(x==Value_t(-1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(138, - "x[x==Value_t(-1)] cMul", - "cNeg", - " with x = " << x << "\n"); - goto Lco; - } - break; - default: Default2:; - A = ByteCodePtr[0]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-1]) - { - case cMul: - switch(ByteCodePtr[-2]) - { - case cNeg: - B = ByteCodePtr[-3]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(327, - "B[B==A] cNeg cMul A[A>=VarBegin] cMul", - "B cSqr cMul cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-3] = B; */ // redundant, matches B @ 4 - goto Lbn; - } - goto Default4; - default: Default4:; - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(318, - "B[B==A] cMul A[A>=VarBegin] cMul", - "B cSqr cMul", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lcp; - } - } - goto Default5; - case cNeg: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(321, - "B[B==A] cNeg A[A>=VarBegin] cMul", - "B cSqr cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - goto Lbo; - } - goto Default5; - default: Default5:; - B = ByteCodePtr[-1]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(315, - "B[B==A] A[A>=VarBegin] cMul", - "B cSqr", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-1] = B; */ // redundant, matches B @ 2 - goto Lbl; - } - } - } - if(IsUnaryOpcode(A)) - { - B = ByteCodePtr[-1]; - if(B>=VarBegin) - { - if(ByteCodePtr[-2] == cMul) - { - C = ByteCodePtr[-3]; - if(C==A) - { - D = ByteCodePtr[-4]; - if(D==B) - { - FP_TRACE_BYTECODE_OPTIMIZATION(337, - "D[D==B] C[C==A] cMul B[B>=VarBegin] A[IsUnaryOpcode(A)] cMul", - "D C cSqr cMul", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << ", D = " << FP_TRACE_OPCODENAME(D) - << "\n"); - /* ByteCodePtr[-4] = D; */ // redundant, matches D @ 5 - /* ByteCodePtr[-3] = C; */ // redundant, matches C @ 4 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lda; - } - } - } - } - } - } - goto Default0; - TailCall_cNEqual: - case cNEqual: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(1)) - { - A = ByteCodePtr[-1]; - if(IsLogicalOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(273, - "A[IsLogicalOpcode(A)] x[x==Value_t(1)] cNEqual", - "A cNot", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lan; - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(130, - "y x cNEqual", - "[fp_nequal(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Ldb; - } - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(209, - "cAbs x[x==Value_t(0)] cNEqual", - "[x] cNEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cNEqual; */ // redundant, matches cNEqual @ 0 - goto Ldc; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(211, - "cSqr x[x==Value_t(0)] cNEqual", - "[x] cNEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cNEqual; */ // redundant, matches cNEqual @ 0 - goto Ldc; - } - FP_TRACE_BYTECODE_OPTIMIZATION(263, - "x[x==Value_t(0)] cNEqual", - "cNotNot", - " with x = " << x << "\n"); - goto Lap; - } - } - goto Default0; - TailCall_cNeg: - case cNeg: - switch(ByteCodePtr[0]) - { - case cMul: - if(ByteCodePtr[-1] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(137, - "x cMul cNeg", - "[-x] cMul", - " with x = " << x << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches x @ 2 - goto Ldd; - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(191,"cNeg cNeg", "", ""); - goto Lbc; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(68, - "x cNeg", - "[-x]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lde; - } - goto Default0; - TailCall_cNot: - case cNot: - switch(ByteCodePtr[0]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(235,"cAbs cNot", "cNot", ""); - /* opcode = cNot; */ // redundant, matches cNot @ 0 - goto Ldf; - case cAbsNot: - A = ByteCodePtr[-1]; - if(IsLogicalOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(240, - "A[IsLogicalOpcode(A)] cAbsNot cNot", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lbc; - } - if(A!=cImmed) - { - FP_TRACE_BYTECODE_OPTIMIZATION(241, - "A[A!=cImmed] cAbsNot cNot", - "A cAbsNotNot", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Ldg; - } - goto Default6; - case cAbsNotNot: - FP_TRACE_BYTECODE_OPTIMIZATION(238,"cAbsNotNot cNot", "cAbsNot", ""); - goto Ldh; - case cEqual: - FP_TRACE_BYTECODE_OPTIMIZATION(205,"cEqual cNot", "cNEqual", ""); - goto Ldi; - case cGreater: - FP_TRACE_BYTECODE_OPTIMIZATION(203,"cGreater cNot", "cLessOrEq", ""); - goto Ldj; - case cGreaterOrEq: - FP_TRACE_BYTECODE_OPTIMIZATION(204,"cGreaterOrEq cNot", "cLess", ""); - goto Ldk; - case cLess: - FP_TRACE_BYTECODE_OPTIMIZATION(201,"cLess cNot", "cGreaterOrEq", ""); - goto Ldl; - case cLessOrEq: - FP_TRACE_BYTECODE_OPTIMIZATION(202,"cLessOrEq cNot", "cGreater", ""); - goto Ldm; - case cNEqual: - FP_TRACE_BYTECODE_OPTIMIZATION(206,"cNEqual cNot", "cEqual", ""); - goto Ldn; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(234,"cNeg cNot", "cNot", ""); - /* opcode = cNot; */ // redundant, matches cNot @ 0 - goto Ldf; - case cNot: - FP_TRACE_BYTECODE_OPTIMIZATION(236,"cNot cNot", "cNotNot", ""); - goto Ldo; - case cNotNot: - FP_TRACE_BYTECODE_OPTIMIZATION(237,"cNotNot cNot", "cNot", ""); - /* opcode = cNot; */ // redundant, matches cNot @ 0 - goto Ldf; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(85, - "x cNot", - "[!truthValue(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ldp; - default: Default6:; - A = ByteCodePtr[0]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(242, - "A[IsNeverNegativeValueOpcode(A)] cNot", - "A cAbsNot", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[0] = A; */ // redundant, matches A @ 1 - goto Lea; - } - } - goto Default0; - TailCall_cOr: - case cOr: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(132, - "y x cOr", - "[truthValue(x)||truthValue(y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Leb; - } - } - goto Default0; - TailCall_cSqr: - case cSqr: - switch(ByteCodePtr[0]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(333,"cAbs cSqr", "cSqr", ""); - /* opcode = cSqr; */ // redundant, matches cSqr @ 0 - goto Lec; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(332,"cNeg cSqr", "cSqr", ""); - /* opcode = cSqr; */ // redundant, matches cSqr @ 0 - goto Lec; - } - goto Default0; - TailCall_cSub: - case cSub: - switch(ByteCodePtr[0]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(197,"cNeg cSub", "cAdd", ""); - goto Led; - case cImmed: - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(77, - "x[x==Value_t(0)] cSub", - "", - " with x = " << x << "\n"); - goto Lag; - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(78, - "y x cSub", - "[y-x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lee; - } - FP_TRACE_BYTECODE_OPTIMIZATION(160, - "x cSub", - "[-x] cAdd", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lef; - } - goto Default0; - default: Default0:; - A = opcode; - if(IsComparisonOpcode(A)) - { - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - switch(ByteCodePtr[-1]) - { - case cAdd: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(213, - "y cAdd x A[IsComparisonOpcode(A)]", - "[x-y] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - goto Leg; - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(214, - "cNeg x A[IsComparisonOpcode(A)]", - "[-x] {OppositeComparisonOpcode(A)}", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << "\n"); - goto Leh; - } - } - } - if(A>=VarBegin) - { - B = ByteCodePtr[0]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(335, - "B[B==A] A[A>=VarBegin]", - "B cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[0] = B; */ // redundant, matches B @ 1 - goto Lei; - } - } - if(IsUnaryOpcode(A)) - { - B = ByteCodePtr[0]; - if(B>=VarBegin) - { - C = ByteCodePtr[-1]; - if(C==A) - { - D = ByteCodePtr[-2]; - if(D==B) - { - FP_TRACE_BYTECODE_OPTIMIZATION(336, - "D[D==B] C[C==A] B[B>=VarBegin] A[IsUnaryOpcode(A)]", - "D C cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << ", D = " << FP_TRACE_OPCODENAME(D) - << "\n"); - /* ByteCodePtr[-2] = D; */ // redundant, matches D @ 3 - /* ByteCodePtr[-1] = C; */ // redundant, matches C @ 2 - goto Lej; - } - } - } - } - } - goto Lek; -Laa: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - goto TailCall_cAbs; -Lab: ImmedPtr[0] = fp_abs(x); return; -Lac: data->Immed.push_back(Value_t(4)); - ByteCodePtr[-2] = cImmed; - ByteCodePtr -= 2; - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - opcode = cMul; -Lel: FP_ReDefinePointers(); -Lem: goto TailCall_cMul; -Lad: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cSub; - goto TailCall_cSub; -Lae: ImmedPtr[-1] = y+x; - data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); -Len: FP_ReDefinePointers(); -Leo: goto TailCall_cAdd; -Laf: ImmedPtr[-1] = y+x; -Lag: data->Immed.pop_back(); -Lbc: data->ByteCode.pop_back(); return; -Lah: ImmedPtr[-1] = truthValue(x)&&truthValue(y); goto Lag; -Lai: data->Immed.push_back(Value_t(0)); - ByteCodePtr[0] = cImmed; - AddFunctionOpcode(cMul); - data->Immed.push_back(Value_t(1)); - data->ByteCode.push_back(cImmed); - opcode = cAdd; goto Len; -Laj: ImmedPtr[0] = -x; - ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Lep: goto TailCall_cDiv; -Lak: ImmedPtr[-1] = y/x; goto Lag; -Lal: ImmedPtr[-1] = fp_equal(y,x); goto Lag; -Lam: ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Lfa: goto TailCall_cEqual; -Lan: data->Immed.pop_back(); -Lfb: data->ByteCode.pop_back(); - opcode = cNot; - FP_ReDefinePointers(); -Lfc: goto TailCall_cNot; -Lao: data->Immed.pop_back(); - data->ByteCode.pop_back(); -Ldo: data->ByteCode.pop_back(); - AddFunctionOpcode(cNotNot); return; -Lap: data->Immed.pop_back(); goto Ldo; -Lba: ImmedPtr[-1] = fp_less(x,y); goto Lag; -Lbb: ImmedPtr[-1] = fp_lessOrEq(x,y); goto Lag; -Lbd: data->ByteCode.pop_back(); - AddFunctionOpcode(cRSqrt); return; -Lbe: ImmedPtr[0] = Value_t(1)/x; return; -Lbf: data->Immed.pop_back(); - data->ByteCode.pop_back(); goto Lfb; -Lbg: ImmedPtr[-1] = fp_less(y,x); goto Lag; -Lbh: ImmedPtr[-1] = fp_lessOrEq(y,x); goto Lag; -Lbi: ImmedPtr[-1] = Max(x,y); goto Lag; -Lbj: ImmedPtr[-1] = Min(x,y); goto Lag; -Lbk: ImmedPtr[-1] = fp_mod(y,x); goto Lag; -Lbl: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cSqr; -Lfd: goto TailCall_cSqr; -Lbm: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cDiv; goto Lep; -Lbn: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); - AddFunctionOpcode(cMul); -Lfe: opcode = cNeg; - FP_ReDefinePointers(); - goto TailCall_cNeg; -Lbo: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); goto Lfe; -Lbp: ByteCodePtr[-2] = cImmed; - ByteCodePtr -= 2; - data->ByteCode.pop_back(); -Lff: data->ByteCode.pop_back(); goto Lem; -Lca: ImmedPtr[-1] = x; -Lfg: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); goto Lel; -Lcb: data->Immed.pop_back(); -Lcc: data->Immed.pop_back(); - data->ByteCode.pop_back(); -Lfh: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); -Lfi: AddFunctionOpcode(A); - data->Immed.push_back(x); - data->ByteCode.push_back(cImmed); goto Lel; -Lcd: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(B); goto Lfi; -Lce: data->Immed.pop_back(); goto Lfh; -Lcf: ByteCodePtr[-1] = cImmed; goto Lbc; -Lcg: ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; goto Lff; -Lch: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); goto Lbc; -Lci: ImmedPtr[0] = x+x; goto Lbp; -Lcj: data->Immed.pop_back(); goto Lch; -Lck: ImmedPtr[-1] = y*x; goto Lfg; -Lcl: ImmedPtr[0] = -x; goto Lcg; -Lcm: ImmedPtr[-1] = y*x; goto Lag; -Lcn: ByteCodePtr[0] = cDup; - ImmedPtr -= 1; - data->Immed.pop_back(); -Lfj: opcode = cAdd; goto Leo; -Lco: data->Immed.pop_back(); - data->ByteCode.pop_back(); goto Lfe; -Lcp: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); goto Lel; -Lda: data->ByteCode.pop_back(); goto Lcp; -Ldb: ImmedPtr[-1] = fp_nequal(y,x); goto Lag; -Ldc: ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Lfk: goto TailCall_cNEqual; -Ldd: ImmedPtr[0] = -x; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cMul; goto Lem; -Lde: ImmedPtr[0] = -x; return; -Ldf: ByteCodePtr -= 1; - data->ByteCode.pop_back(); goto Lfc; -Ldg: data->ByteCode.pop_back(); - AddFunctionOpcode(cAbsNotNot); return; -Ldh: data->ByteCode.pop_back(); -Lea: AddFunctionOpcode(cAbsNot); return; -Ldi: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cNEqual; goto Lfk; -Ldj: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cLessOrEq; - goto TailCall_cLessOrEq; -Ldk: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cLess; - goto TailCall_cLess; -Ldl: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cGreaterOrEq; - goto TailCall_cGreaterOrEq; -Ldm: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cGreater; - goto TailCall_cGreater; -Ldn: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cEqual; goto Lfa; -Ldp: ImmedPtr[0] = !truthValue(x); return; -Leb: ImmedPtr[-1] = truthValue(x)||truthValue(y); goto Lag; -Lec: ByteCodePtr -= 1; - data->ByteCode.pop_back(); goto Lfd; -Led: ByteCodePtr -= 1; - data->ByteCode.pop_back(); goto Lfj; -Lee: ImmedPtr[-1] = y-x; goto Lag; -Lef: ImmedPtr[0] = -x; goto Lfj; -Leg: ImmedPtr[-1] = x-y; - data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(A); return; -Leh: ImmedPtr[0] = -x; - ByteCodePtr[-1] = cImmed; - data->ByteCode.pop_back(); - AddFunctionOpcode(OppositeComparisonOpcode(A)); return; -Lei: data->ByteCode.push_back(cDup); return; -Lej: ByteCodePtr[0] = cDup; return; -Lek: data->ByteCode.push_back(opcode); return; -return; -// This list of dummy gotos is here to inhibit -// compiler warnings on unused labels -goto TailCall_cAnd;goto TailCall_cInv;goto TailCall_cMax; -goto TailCall_cMin;goto TailCall_cMod;goto TailCall_cNeg; -goto TailCall_cOr;goto TailCall_cSub; -#endif - -#if(FP_FLOAT_VERSION) - Value_t x; - unsigned A; - Value_t y; - unsigned B; - unsigned C; - unsigned D; - switch(opcode) - { - TailCall_cAbs: - case cAbs: - switch(ByteCodePtr[0]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(189,"cNeg cAbs", "cAbs", ""); - /* opcode = cAbs; */ // redundant, matches cAbs @ 0 - goto Laa; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(40, - "x cAbs", - "[fp_abs(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lab; - default: - A = ByteCodePtr[0]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(244, - "A[IsNeverNegativeValueOpcode(A)] cAbs", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[0] = A; */ // redundant, matches A @ 1 - return; - } - } - goto Default0; - TailCall_cAcos: - case cAcos: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x>=Value_t(-1)&&x<=Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(44, - "x[x>=Value_t(-1)&&x<=Value_t(1)] cAcos", - "[fp_acos(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lac; - } - } - goto Default0; - TailCall_cAcosh: - case cAcosh: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x>=Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(41, - "x[x>=Value_t(1)] cAcosh", - "[fp_acosh(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lad; - } - } - goto Default0; - TailCall_cAdd: - case cAdd: - switch(ByteCodePtr[0]) - { - case cDup: - if(ByteCodePtr[-1] == cAdd) - { - if(ByteCodePtr[-2] == cDup) - { - FP_TRACE_BYTECODE_OPTIMIZATION(108,"cDup cAdd cDup cAdd", "[Value_t(4)] cMul", ""); - goto Lae; - } - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(196,"cNeg cAdd", "cSub", ""); - goto Laf; - case cImmed: - x = ImmedPtr[0]; - switch(ByteCodePtr[-1]) - { - case cAdd: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(142, - "y cAdd x cAdd", - "[y+x] cAdd", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cAdd; */ // redundant, matches cAdd @ 0 - goto Lag; - } - break; - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(76, - "y x cAdd", - "[y+x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lah; - } - if(x==Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(75, - "x[x==Value_t(0)] cAdd", - "", - " with x = " << x << "\n"); - goto Lai; - } - break; - } - goto Default0; - TailCall_cAnd: - case cAnd: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(131, - "y x cAnd", - "[truthValue(x)&&truthValue(y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Laj; - } - } - goto Default0; - TailCall_cAsin: - case cAsin: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x>=Value_t(-1)&&x<=Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(45, - "x[x>=Value_t(-1)&&x<=Value_t(1)] cAsin", - "[fp_asin(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lak; - } - } - goto Default0; - TailCall_cAsinh: - case cAsinh: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(42, - "x cAsinh", - "[fp_asinh(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lal; - } - goto Default0; - TailCall_cAtan: - case cAtan: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(46, - "x cAtan", - "[fp_atan(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lam; - } - goto Default0; - TailCall_cAtan2: - case cAtan2: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(83, - "y x cAtan2", - "[fp_atan2(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lan; - } - } - goto Default0; - TailCall_cAtanh: - case cAtanh: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x>Value_t(-1)&&xValue_t(-1)&&x()) - { - FP_TRACE_BYTECODE_OPTIMIZATION(151, - "y[(y/x)==GetRadiansToDegreesFactor()] cMul x[x!=Value_t(0)] cDiv", - "cDeg", - " with x = " << x - << ", y = " << y - << "\n"); - goto Lce; - } - if((y/x)==GetDegreesToRadiansFactor()) - { - FP_TRACE_BYTECODE_OPTIMIZATION(152, - "y[(y/x)==GetDegreesToRadiansFactor()] cMul x[x!=Value_t(0)] cDiv", - "cRad", - " with x = " << x - << ", y = " << y - << "\n"); - goto Lcf; - } - FP_TRACE_BYTECODE_OPTIMIZATION(153, - "y cMul x[x!=Value_t(0)] cDiv", - "[y/x] cMul", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - goto Lcg; - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(139, - "cNeg x[x!=Value_t(0)] cDiv", - "[-x] cDiv", - " with x = " << x << "\n"); - /* opcode = cDiv; */ // redundant, matches cDiv @ 0 - goto Lch; - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(73, - "y x[x!=Value_t(0)] cDiv", - "[y/x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lci; - } - FP_TRACE_BYTECODE_OPTIMIZATION(155, - "x[x!=Value_t(0)] cDiv", - "[Value_t(1)/x] cMul", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lcj; - } - break; - } - goto Default0; - TailCall_cEqual: - case cEqual: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(208, - "cAbs x[x==Value_t(0)] cEqual", - "[x] cEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cEqual; */ // redundant, matches cEqual @ 0 - goto Lck; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(210, - "cSqr x[x==Value_t(0)] cEqual", - "[x] cEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cEqual; */ // redundant, matches cEqual @ 0 - goto Lck; - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(129, - "y x cEqual", - "[fp_equal(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lcl; - } - } - goto Default0; - TailCall_cExp: - case cExp: - switch(ByteCodePtr[0]) - { - case cAdd: - if(ByteCodePtr[-1] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(255, - "x cAdd cExp", - "cExp [fp_exp(x)] cMul", - " with x = " << x << "\n"); - goto Lcm; - } - break; - case cLog: - A = ByteCodePtr[-1]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(175, - "A[IsNeverNegativeValueOpcode(A)] cLog cExp", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lbf; - } - break; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(51, - "x cExp", - "[fp_exp(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lcn; - } - goto Default0; - TailCall_cExp2: - case cExp2: - switch(ByteCodePtr[0]) - { - case cAdd: - if(ByteCodePtr[-1] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(256, - "x cAdd cExp2", - "cExp2 [fp_exp2(x)] cMul", - " with x = " << x << "\n"); - goto Lco; - } - break; - case cLog2: - A = ByteCodePtr[-1]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(176, - "A[IsNeverNegativeValueOpcode(A)] cLog2 cExp2", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lbf; - } - break; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(52, - "x cExp2", - "[fp_exp2(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lcp; - } - FP_TRACE_BYTECODE_OPTIMIZATION(341,"cExp2", "[DO_STACKPLUS1] [fp_log(Value_t(2))] cMul cExp", ""); - incStackPtr(); - --StackPtr; - goto Lda; - TailCall_cFloor: - case cFloor: - switch(ByteCodePtr[0]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(252,"cNeg cFloor", "cCeil cNeg", ""); - goto Ldb; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(53, - "x cFloor", - "[fp_floor(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ldc; - default: - A = ByteCodePtr[0]; - if(IsAlwaysIntegerOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(246, - "A[IsAlwaysIntegerOpcode(A)] cFloor", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[0] = A; */ // redundant, matches A @ 1 - return; - } - } - goto Default0; - TailCall_cGreater: - case cGreater: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(127, - "y x cGreater", - "[fp_less(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Ldd; - } - } - goto Default0; - TailCall_cGreaterOrEq: - case cGreaterOrEq: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x!=Value_t(0)) - { - if(ByteCodePtr[-1] == cAbs) - { - FP_TRACE_BYTECODE_OPTIMIZATION(276, - "cAbs x[x!=Value_t(0)] cGreaterOrEq", - "[Value_t(0.5)/x] cMul cNotNot", - " with x = " << x << "\n"); - goto Lde; - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(128, - "y x cGreaterOrEq", - "[fp_lessOrEq(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Ldf; - } - } - goto Default0; - TailCall_cInt: - case cInt: - switch(ByteCodePtr[0]) - { - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(54, - "x cInt", - "[fp_int(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ldg; - default: - A = ByteCodePtr[0]; - if(IsAlwaysIntegerOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(248, - "A[IsAlwaysIntegerOpcode(A)] cInt", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[0] = A; */ // redundant, matches A @ 1 - return; - } - } - goto Default0; - TailCall_cInv: - case cInv: - switch(ByteCodePtr[0]) - { - case cCos: - FP_TRACE_BYTECODE_OPTIMIZATION(304,"cCos cInv", "cSec", ""); - goto Ldh; - case cCot: - FP_TRACE_BYTECODE_OPTIMIZATION(308,"cCot cInv", "cTan", ""); - goto Ldi; - case cCsc: - FP_TRACE_BYTECODE_OPTIMIZATION(306,"cCsc cInv", "cSin", ""); - goto Ldj; - case cInv: - FP_TRACE_BYTECODE_OPTIMIZATION(190,"cInv cInv", "", ""); - goto Lbf; - case cPow: - FP_TRACE_BYTECODE_OPTIMIZATION(192,"cPow cInv", "cNeg cPow", ""); - goto Ldk; - case cSec: - FP_TRACE_BYTECODE_OPTIMIZATION(307,"cSec cInv", "cCos", ""); - goto Ldl; - case cSin: - FP_TRACE_BYTECODE_OPTIMIZATION(303,"cSin cInv", "cCsc", ""); - goto Ldm; - case cSqrt: - FP_TRACE_BYTECODE_OPTIMIZATION(67,"cSqrt cInv", "cRSqrt", ""); - goto Ldn; - case cTan: - FP_TRACE_BYTECODE_OPTIMIZATION(305,"cTan cInv", "cCot", ""); - goto Ldo; - case cImmed: - x = ImmedPtr[0]; - if(x!=Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(69, - "x[x!=Value_t(0)] cInv", - "[Value_t(1)/x]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ldp; - } - break; - } - goto Default0; - TailCall_cLess: - case cLess: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x!=Value_t(0)) - { - if(ByteCodePtr[-1] == cAbs) - { - FP_TRACE_BYTECODE_OPTIMIZATION(275, - "cAbs x[x!=Value_t(0)] cLess", - "[Value_t(0.5)/x] cMul cNot", - " with x = " << x << "\n"); - goto Lea; - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(125, - "y x cLess", - "[fp_less(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Leb; - } - } - goto Default0; - TailCall_cLessOrEq: - case cLessOrEq: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(126, - "y x cLessOrEq", - "[fp_lessOrEq(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lec; - } - } - goto Default0; - TailCall_cLog: - case cLog: - switch(ByteCodePtr[0]) - { - case cExp: - FP_TRACE_BYTECODE_OPTIMIZATION(178,"cExp cLog", "", ""); - goto Lbf; - case cMul: - if(ByteCodePtr[-1] == cImmed) - { - x = ImmedPtr[0]; - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(353, - "x[x>Value_t(0)] cMul cLog", - "cLog [fp_log(x)] cAdd", - " with x = " << x << "\n"); - goto Led; - } - } - break; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(103,"cSqr cLog", "cAbs cLog cDup cAdd", ""); - goto Lee; - case cImmed: - x = ImmedPtr[0]; - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(55, - "x[x>Value_t(0)] cLog", - "[fp_log(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lef; - } - break; - } - goto Default0; - TailCall_cLog10: - case cLog10: - switch(ByteCodePtr[0]) - { - case cExp: - FP_TRACE_BYTECODE_OPTIMIZATION(343,"cExp cLog10", "[DO_STACKPLUS1] [fp_log10(const_e())] cMul", ""); - incStackPtr(); - --StackPtr; - goto Leg; - case cMul: - if(ByteCodePtr[-1] == cImmed) - { - x = ImmedPtr[0]; - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(354, - "x[x>Value_t(0)] cMul cLog10", - "cLog10 [fp_log10(x)] cAdd", - " with x = " << x << "\n"); - goto Leh; - } - } - break; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(105,"cSqr cLog10", "cAbs cLog10 cDup cAdd", ""); - goto Lei; - case cImmed: - x = ImmedPtr[0]; - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(56, - "x[x>Value_t(0)] cLog10", - "[fp_log10(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lej; - } - break; - } - goto Default0; - TailCall_cLog2: - case cLog2: - switch(ByteCodePtr[0]) - { - case cExp: - FP_TRACE_BYTECODE_OPTIMIZATION(342,"cExp cLog2", "[DO_STACKPLUS1] [fp_log2(const_e())] cMul", ""); - incStackPtr(); - --StackPtr; - goto Lek; - case cExp2: - FP_TRACE_BYTECODE_OPTIMIZATION(179,"cExp2 cLog2", "", ""); - goto Lbf; - case cMul: - if(ByteCodePtr[-1] == cImmed) - { - x = ImmedPtr[0]; - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(352, - "x[x>Value_t(0)] cMul cLog2", - "cLog2 [fp_log2(x)] cAdd", - " with x = " << x << "\n"); - goto Lel; - } - } - break; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(104,"cSqr cLog2", "cAbs cLog2 cDup cAdd", ""); - goto Lem; - case cImmed: - x = ImmedPtr[0]; - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(57, - "x[x>Value_t(0)] cLog2", - "[fp_log2(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Len; - } - break; - } - goto Default0; - TailCall_cMax: - case cMax: - switch(ByteCodePtr[0]) - { - case cDup: - FP_TRACE_BYTECODE_OPTIMIZATION(111,"cDup cMax", "", ""); - goto Lbf; - case cImmed: - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(82, - "y x cMax", - "[Max(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Leo; - } - break; - default: - A = ByteCodePtr[0]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-1]) - { - case cDup: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(113, - "B[B==A] cDup A[A>=VarBegin] cMax", - "B cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cDup; */ // redundant, matches cDup @ 2 - goto Lbf; - } - break; - case cMax: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(115, - "B[B==A] cMax A[A>=VarBegin] cMax", - "B cMax", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cMax; */ // redundant, matches cMax @ 2 - goto Lbf; - } - break; - } - } - } - goto Default0; - TailCall_cMin: - case cMin: - switch(ByteCodePtr[0]) - { - case cDup: - FP_TRACE_BYTECODE_OPTIMIZATION(110,"cDup cMin", "", ""); - goto Lbf; - case cImmed: - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(81, - "y x cMin", - "[Min(x,y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lep; - } - break; - default: - A = ByteCodePtr[0]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-1]) - { - case cDup: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(112, - "B[B==A] cDup A[A>=VarBegin] cMin", - "B cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cDup; */ // redundant, matches cDup @ 2 - goto Lbf; - } - break; - case cMin: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(114, - "B[B==A] cMin A[A>=VarBegin] cMin", - "B cMin", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* ByteCodePtr[-1] = cMin; */ // redundant, matches cMin @ 2 - goto Lbf; - } - break; - } - } - } - goto Default0; - TailCall_cMod: - case cMod: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x!=Value_t(0)) - { - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(74, - "y x[x!=Value_t(0)] cMod", - "[fp_mod(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lfa; - } - } - } - goto Default0; - TailCall_cMul: - case cMul: - switch(ByteCodePtr[0]) - { - case cDup: - FP_TRACE_BYTECODE_OPTIMIZATION(338,"cDup cMul", "cSqr", ""); - goto Lfb; - case cInv: - FP_TRACE_BYTECODE_OPTIMIZATION(195,"cInv cMul", "cDiv", ""); - goto Lfc; - case cNeg: - A = ByteCodePtr[-1]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-2]) - { - case cMul: - B = ByteCodePtr[-3]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(330, - "B[B==A] cMul A[A>=VarBegin] cNeg cMul", - "B cSqr cMul cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-3] = B; */ // redundant, matches B @ 4 - goto Lfd; - } - goto Default1; - default: Default1:; - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(324, - "B[B==A] A[A>=VarBegin] cNeg cMul", - "B cSqr cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - goto Lfe; - } - } - } - goto Default2; - case cImmed: - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cMul: - A = ByteCodePtr[-2]; - if(A>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(94, - "A[A>=VarBegin] cMul x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lff; - } - goto Default3; - default: Default3:; - A = ByteCodePtr[-1]; - if(IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)) - { - switch(ByteCodePtr[-2]) - { - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(93, - "y A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfg; - default: - B = ByteCodePtr[-2]; - if(IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)) - { - switch(ByteCodePtr[-3]) - { - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(97, - "y B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", y = " << y - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfh; - default: - C = ByteCodePtr[-3]; - if(C>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(95, - "C[C>=VarBegin] B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfi; - } - if(IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(96, - "C[IsUnaryOpcode(C)&&!HasInvalidRangesOpcode(C)] B[IsBinaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "B A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfj; - } - } - } - if(B>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(91, - "B[B>=VarBegin] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lff; - } - if(IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(92, - "B[IsUnaryOpcode(B)&&!HasInvalidRangesOpcode(B)] A[IsBinaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "A [x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfk; - } - } - } - if(A>=VarBegin) - { - FP_TRACE_BYTECODE_OPTIMIZATION(89, - "A[A>=VarBegin] x[x==Value_t(0)] cMul", - "[x]", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - goto Lfl; - } - if(IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(90, - "A[IsUnaryOpcode(A)&&!HasInvalidRangesOpcode(A)] x[x==Value_t(0)] cMul", - "[x] cMul", - " with x = " << x - << ", A = " << FP_TRACE_OPCODENAME(A) - << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfm; - } - } - } - switch(ByteCodePtr[-1]) - { - case cAdd: - if(ByteCodePtr[-2] == cDup) - { - if(x+x==Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(148, - "cDup[x+x==Value_t(1)] cAdd x cMul", - "", - " with x = " << x << "\n"); - goto Lfn; - } - FP_TRACE_BYTECODE_OPTIMIZATION(149, - "cDup cAdd x cMul", - "[x+x] cMul", - " with x = " << x << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfo; - } - break; - case cDeg: - FP_TRACE_BYTECODE_OPTIMIZATION(106, - "cDeg x cMul", - "[RadiansToDegrees(x)] cMul", - " with x = " << x << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lfp; - case cMul: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - if((y*x)==GetRadiansToDegreesFactor()) - { - FP_TRACE_BYTECODE_OPTIMIZATION(144, - "y[(y*x)==GetRadiansToDegreesFactor()] cMul x cMul", - "cDeg", - " with x = " << x - << ", y = " << y - << "\n"); - goto Lce; - } - if((y*x)==GetDegreesToRadiansFactor()) - { - FP_TRACE_BYTECODE_OPTIMIZATION(145, - "y[(y*x)==GetDegreesToRadiansFactor()] cMul x cMul", - "cRad", - " with x = " << x - << ", y = " << y - << "\n"); - goto Lcf; - } - if(y*x==Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(146, - "y[y*x==Value_t(1)] cMul x cMul", - "", - " with x = " << x - << ", y = " << y - << "\n"); - goto Lga; - } - FP_TRACE_BYTECODE_OPTIMIZATION(147, - "y cMul x cMul", - "[y*x] cMul", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lgb; - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(136, - "cNeg x cMul", - "[-x] cMul", - " with x = " << x << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lgc; - case cRad: - FP_TRACE_BYTECODE_OPTIMIZATION(107, - "cRad x cMul", - "[DegreesToRadians(x)] cMul", - " with x = " << x << "\n"); - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lgd; - case cImmed: - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(71, - "y x cMul", - "[y*x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lge; - } - if(x==Value_t(1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(70, - "x[x==Value_t(1)] cMul", - "", - " with x = " << x << "\n"); - goto Lai; - } - if(x==Value_t(2)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(100, - "x[x==Value_t(2)] cMul", - "cDup cAdd", - " with x = " << x << "\n"); - goto Lgf; - } - if(x==GetRadiansToDegreesFactor()) - { - FP_TRACE_BYTECODE_OPTIMIZATION(101, - "x[x==GetRadiansToDegreesFactor()] cMul", - "cDeg", - " with x = " << x << "\n"); - goto Lgg; - } - if(x==GetDegreesToRadiansFactor()) - { - FP_TRACE_BYTECODE_OPTIMIZATION(102, - "x[x==GetDegreesToRadiansFactor()] cMul", - "cRad", - " with x = " << x << "\n"); - goto Lgh; - } - if(x==Value_t(-1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(138, - "x[x==Value_t(-1)] cMul", - "cNeg", - " with x = " << x << "\n"); - goto Lgi; - } - break; - default: Default2:; - A = ByteCodePtr[0]; - if(A>=VarBegin) - { - switch(ByteCodePtr[-1]) - { - case cMul: - switch(ByteCodePtr[-2]) - { - case cNeg: - B = ByteCodePtr[-3]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(327, - "B[B==A] cNeg cMul A[A>=VarBegin] cMul", - "B cSqr cMul cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-3] = B; */ // redundant, matches B @ 4 - goto Lfd; - } - goto Default4; - default: Default4:; - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(318, - "B[B==A] cMul A[A>=VarBegin] cMul", - "B cSqr cMul", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lgj; - } - } - goto Default5; - case cNeg: - B = ByteCodePtr[-2]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(321, - "B[B==A] cNeg A[A>=VarBegin] cMul", - "B cSqr cNeg", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - goto Lfe; - } - goto Default5; - default: Default5:; - B = ByteCodePtr[-1]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(315, - "B[B==A] A[A>=VarBegin] cMul", - "B cSqr", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-1] = B; */ // redundant, matches B @ 2 - goto Lfb; - } - } - } - if(IsUnaryOpcode(A)) - { - B = ByteCodePtr[-1]; - if(B>=VarBegin) - { - if(ByteCodePtr[-2] == cMul) - { - C = ByteCodePtr[-3]; - if(C==A) - { - D = ByteCodePtr[-4]; - if(D==B) - { - FP_TRACE_BYTECODE_OPTIMIZATION(337, - "D[D==B] C[C==A] cMul B[B>=VarBegin] A[IsUnaryOpcode(A)] cMul", - "D C cSqr cMul", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << ", D = " << FP_TRACE_OPCODENAME(D) - << "\n"); - /* ByteCodePtr[-4] = D; */ // redundant, matches D @ 5 - /* ByteCodePtr[-3] = C; */ // redundant, matches C @ 4 - /* opcode = cMul; */ // redundant, matches cMul @ 0 - goto Lgk; - } - } - } - } - } - } - goto Default0; - TailCall_cNEqual: - case cNEqual: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(209, - "cAbs x[x==Value_t(0)] cNEqual", - "[x] cNEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cNEqual; */ // redundant, matches cNEqual @ 0 - goto Lgl; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(211, - "cSqr x[x==Value_t(0)] cNEqual", - "[x] cNEqual", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cNEqual; */ // redundant, matches cNEqual @ 0 - goto Lgl; - } - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(130, - "y x cNEqual", - "[fp_nequal(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lgm; - } - } - goto Default0; - TailCall_cNeg: - case cNeg: - switch(ByteCodePtr[0]) - { - case cMul: - if(ByteCodePtr[-1] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(137, - "x cMul cNeg", - "[-x] cMul", - " with x = " << x << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches x @ 2 - goto Lgn; - } - break; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(191,"cNeg cNeg", "", ""); - goto Lbf; - case cSin: - if(ByteCodePtr[-1] == cMul) - { - if(ByteCodePtr[-2] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(289, - "x cMul cSin cNeg", - "[-x] cMul cSin", - " with x = " << x << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches x @ 3 - goto Lgo; - } - } - break; - case cSinh: - if(ByteCodePtr[-1] == cMul) - { - if(ByteCodePtr[-2] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(290, - "x cMul cSinh cNeg", - "[-x] cMul cSinh", - " with x = " << x << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches x @ 3 - goto Lgp; - } - } - break; - case cTan: - if(ByteCodePtr[-1] == cMul) - { - if(ByteCodePtr[-2] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(291, - "x cMul cTan cNeg", - "[-x] cMul cTan", - " with x = " << x << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches x @ 3 - goto Lha; - } - } - break; - case cTanh: - if(ByteCodePtr[-1] == cMul) - { - if(ByteCodePtr[-2] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(292, - "x cMul cTanh cNeg", - "[-x] cMul cTanh", - " with x = " << x << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches x @ 3 - goto Lhb; - } - } - break; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(68, - "x cNeg", - "[-x]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lhc; - } - goto Default0; - TailCall_cNot: - case cNot: - switch(ByteCodePtr[0]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(235,"cAbs cNot", "cNot", ""); - /* opcode = cNot; */ // redundant, matches cNot @ 0 - goto Lhd; - case cAbsNot: - A = ByteCodePtr[-1]; - if(IsLogicalOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(240, - "A[IsLogicalOpcode(A)] cAbsNot cNot", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lbf; - } - if(A!=cImmed) - { - FP_TRACE_BYTECODE_OPTIMIZATION(241, - "A[A!=cImmed] cAbsNot cNot", - "A cAbsNotNot", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lhe; - } - goto Default6; - case cAbsNotNot: - FP_TRACE_BYTECODE_OPTIMIZATION(238,"cAbsNotNot cNot", "cAbsNot", ""); - goto Lhf; - case cEqual: - FP_TRACE_BYTECODE_OPTIMIZATION(205,"cEqual cNot", "cNEqual", ""); - goto Lhg; - case cGreater: - FP_TRACE_BYTECODE_OPTIMIZATION(203,"cGreater cNot", "cLessOrEq", ""); - goto Lhh; - case cGreaterOrEq: - FP_TRACE_BYTECODE_OPTIMIZATION(204,"cGreaterOrEq cNot", "cLess", ""); - goto Lhi; - case cLess: - FP_TRACE_BYTECODE_OPTIMIZATION(201,"cLess cNot", "cGreaterOrEq", ""); - goto Lhj; - case cLessOrEq: - FP_TRACE_BYTECODE_OPTIMIZATION(202,"cLessOrEq cNot", "cGreater", ""); - goto Lhk; - case cNEqual: - FP_TRACE_BYTECODE_OPTIMIZATION(206,"cNEqual cNot", "cEqual", ""); - goto Lhl; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(234,"cNeg cNot", "cNot", ""); - /* opcode = cNot; */ // redundant, matches cNot @ 0 - goto Lhd; - case cNot: - FP_TRACE_BYTECODE_OPTIMIZATION(236,"cNot cNot", "cNotNot", ""); - goto Lhm; - case cNotNot: - FP_TRACE_BYTECODE_OPTIMIZATION(237,"cNotNot cNot", "cNot", ""); - /* opcode = cNot; */ // redundant, matches cNot @ 0 - goto Lhd; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(85, - "x cNot", - "[!truthValue(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lhn; - default: Default6:; - A = ByteCodePtr[0]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(242, - "A[IsNeverNegativeValueOpcode(A)] cNot", - "A cAbsNot", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[0] = A; */ // redundant, matches A @ 1 - goto Lho; - } - } - goto Default0; - TailCall_cOr: - case cOr: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(132, - "y x cOr", - "[truthValue(x)||truthValue(y)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lhp; - } - } - goto Default0; - TailCall_cPow: - case cPow: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - if(!isEvenInteger(x+x)) - { - if(ByteCodePtr[-1] == cSqr) - { - FP_TRACE_BYTECODE_OPTIMIZATION(14, - "cSqr x[!isEvenInteger(x+x)] cPow", - "cAbs [x+x] cPow", - " with x = " << x << "\n"); - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lia; - } - } - if(IsIntegerConst(x)) - { - switch(ByteCodePtr[-1]) - { - case cExp: - FP_TRACE_BYTECODE_OPTIMIZATION(35, - "cExp x[IsIntegerConst(x)] cPow", - "[x] cMul cExp", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - goto Lib; - case cExp2: - FP_TRACE_BYTECODE_OPTIMIZATION(36, - "cExp2 x[IsIntegerConst(x)] cPow", - "[x] cMul cExp2", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - goto Lic; - case cPow: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - if(!IsIntegerConst(y)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(34, - "y[!IsIntegerConst(y)] cPow x[IsIntegerConst(x)] cPow", - "[y*x] cPow", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lid; - } - } - FP_TRACE_BYTECODE_OPTIMIZATION(37, - "cPow x[IsIntegerConst(x)] cPow", - "[x] cMul cPow", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lie; - } - } - if(isEvenInteger(x)) - { - switch(ByteCodePtr[-1]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(278, - "cAbs x[isEvenInteger(x)] cPow", - "[x] cPow", - " with x = " << x << "\n"); - /* ImmedPtr[0] = x; */ // redundant, matches x @ 1 - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lif; - case cMul: - if(ByteCodePtr[-2] == cAbs) - { - FP_TRACE_BYTECODE_OPTIMIZATION(279, - "cAbs cMul x[isEvenInteger(x)] cPow", - "cMul [x] cPow", - " with x = " << x << "\n"); - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lig; - } - break; - } - } - - if(x==Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(123, - "x[x==Value_t(0)] cPow", - "[Value_t(0)] cMul [Value_t(1)] cAdd", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lih; - } - if(x==Value_t(0.5)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(167, - "x[x==Value_t(0.5)] cPow", - "cSqrt", - " with x = " << x << "\n"); - goto Lii; - } - if(x==Value_t(1)/Value_t(3)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(168, - "x[x==Value_t(1)/Value_t(3)] cPow", - "cCbrt", - " with x = " << x << "\n"); - goto Lij; - } - if(x==Value_t(1)/Value_t(-3)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(169, - "x[x==Value_t(1)/Value_t(-3)] cPow", - "cCbrt cInv", - " with x = " << x << "\n"); - goto Lik; - } - if(x==Value_t(-0.5)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(170, - "x[x==Value_t(-0.5)] cPow", - "cRSqrt", - " with x = " << x << "\n"); - goto Lil; - } - if(x==Value_t(-1)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(171, - "x[x==Value_t(-1)] cPow", - "cInv", - " with x = " << x << "\n"); - goto Lim; - } - switch(ByteCodePtr[-1]) - { - case cPow: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - - if(isEvenInteger(y)&&!isEvenInteger(x*y)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(13, - "y[isEvenInteger(y)&&!isEvenInteger(x*y)] cPow x cPow", - "cAbs [y*x] cPow", - " with x = " << x - << ", y = " << y - << "\n"); - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lin; - } - - FP_TRACE_BYTECODE_OPTIMIZATION(165, - "y cPow x cPow", - "[y*x] cPow", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lid; - } - break; - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(38, - "cSqr x cPow", - "[x+x] cPow", - " with x = " << x << "\n"); - /* opcode = cPow; */ // redundant, matches cPow @ 0 - goto Lio; - case cImmed: - y = ImmedPtr[-1]; - if(y!=Value_t(0)||x>=Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(84, - "y[y!=Value_t(0)||x>=Value_t(0)] x cPow", - "[fp_pow(y,x)]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Lip; - } - break; - } - FP_TRACE_BYTECODE_OPTIMIZATION(312, - "x cPow", - "[DO_POWI]", - " with x = " << x << "\n"); - if(TryCompilePowi(x)) - return; - } - goto Default0; - TailCall_cRad: - case cRad: - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(66, - "x cRad", - "[DegreesToRadians(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lja; - } - goto Default0; - TailCall_cSin: - case cSin: - switch(ByteCodePtr[0]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(285,"cNeg cSin", "cSin cNeg", ""); - goto Ljb; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(58, - "x cSin", - "[fp_sin(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ljc; - } - goto Default0; - TailCall_cSinh: - case cSinh: - switch(ByteCodePtr[0]) - { - case cAcosh: - FP_TRACE_BYTECODE_OPTIMIZATION(294,"cAcosh cSinh", "[DO_STACKPLUS1] cSqr [Value_t(-1)] cAdd cSqrt", ""); - incStackPtr(); - --StackPtr; - goto Ljd; - case cAsinh: - FP_TRACE_BYTECODE_OPTIMIZATION(184,"cAsinh cSinh", "", ""); - goto Lbf; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(286,"cNeg cSinh", "cSinh cNeg", ""); - goto Lje; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(59, - "x cSinh", - "[fp_sinh(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ljf; - } - goto Default0; - TailCall_cSqr: - case cSqr: - switch(ByteCodePtr[0]) - { - case cAbs: - FP_TRACE_BYTECODE_OPTIMIZATION(333,"cAbs cSqr", "cSqr", ""); - /* opcode = cSqr; */ // redundant, matches cSqr @ 0 - goto Ljg; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(332,"cNeg cSqr", "cSqr", ""); - /* opcode = cSqr; */ // redundant, matches cSqr @ 0 - goto Ljg; - case cSqrt: - A = ByteCodePtr[-1]; - if(IsNeverNegativeValueOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(173, - "A[IsNeverNegativeValueOpcode(A)] cSqrt cSqr", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[-1] = A; */ // redundant, matches A @ 2 - goto Lbf; - } - break; - } - goto Default0; - TailCall_cSqrt: - case cSqrt: - switch(ByteCodePtr[0]) - { - case cSqr: - FP_TRACE_BYTECODE_OPTIMIZATION(15,"cSqr cSqrt", "cAbs", ""); - goto Ljh; - case cImmed: - x = ImmedPtr[0]; - if(x>=Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(60, - "x[x>=Value_t(0)] cSqrt", - "[fp_sqrt(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lji; - } - break; - } - goto Default0; - TailCall_cSub: - case cSub: - switch(ByteCodePtr[0]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(197,"cNeg cSub", "cAdd", ""); - goto Ljj; - case cImmed: - x = ImmedPtr[0]; - if(x==Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(77, - "x[x==Value_t(0)] cSub", - "", - " with x = " << x << "\n"); - goto Lai; - } - if(ByteCodePtr[-1] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(78, - "y x cSub", - "[y-x]", - " with x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-1] = cImmed; */ // redundant, matches y @ 2 - goto Ljk; - } - FP_TRACE_BYTECODE_OPTIMIZATION(160, - "x cSub", - "[-x] cAdd", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ljl; - } - goto Default0; - TailCall_cTan: - case cTan: - switch(ByteCodePtr[0]) - { - case cAtan2: - FP_TRACE_BYTECODE_OPTIMIZATION(188,"cAtan2 cTan", "cDiv", ""); - goto Lfc; - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(287,"cNeg cTan", "cTan cNeg", ""); - goto Ljm; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(62, - "x cTan", - "[fp_tan(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ljn; - } - goto Default0; - TailCall_cTanh: - case cTanh: - switch(ByteCodePtr[0]) - { - case cNeg: - FP_TRACE_BYTECODE_OPTIMIZATION(288,"cNeg cTanh", "cTanh cNeg", ""); - goto Ljo; - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(63, - "x cTanh", - "[fp_tanh(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Ljp; - } - goto Default0; - TailCall_cTrunc: - case cTrunc: - switch(ByteCodePtr[0]) - { - case cImmed: - x = ImmedPtr[0]; - FP_TRACE_BYTECODE_OPTIMIZATION(64, - "x cTrunc", - "[fp_trunc(x)]", - " with x = " << x << "\n"); - /* ByteCodePtr[0] = cImmed; */ // redundant, matches x @ 1 - goto Lka; - default: - A = ByteCodePtr[0]; - if(IsAlwaysIntegerOpcode(A)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(245, - "A[IsAlwaysIntegerOpcode(A)] cTrunc", - "A", - " with A = " << FP_TRACE_OPCODENAME(A) << "\n"); - /* ByteCodePtr[0] = A; */ // redundant, matches A @ 1 - return; - } - } - goto Default0; - default: Default0:; - A = opcode; - if(IsComparisonOpcode(A)) - { - if(ByteCodePtr[0] == cImmed) - { - x = ImmedPtr[0]; - switch(ByteCodePtr[-1]) - { - case cAdd: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - FP_TRACE_BYTECODE_OPTIMIZATION(213, - "y cAdd x A[IsComparisonOpcode(A)]", - "[x-y] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - goto Lkb; - } - break; - case cAtan: - if(fp_abs(x)()*Value_t(0.5)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(229, - "cAtan[fp_abs(x)()*Value_t(0.5)] x A[IsComparisonOpcode(A)]", - "[fp_tan(x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << "\n"); - goto Lkc; - } - break; - case cExp: - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(219, - "cExp[x>Value_t(0)] x A[IsComparisonOpcode(A)]", - "[fp_log(x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << "\n"); - goto Lkd; - } - break; - case cExp2: - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(220, - "cExp2[x>Value_t(0)] x A[IsComparisonOpcode(A)]", - "[fp_log2(x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << "\n"); - goto Lke; - } - break; - case cLog: - B = ByteCodePtr[-2]; - if(IsNeverNegativeValueOpcode(B)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(222, - "B[IsNeverNegativeValueOpcode(B)] cLog x A[IsComparisonOpcode(A)]", - "B [fp_exp(x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - goto Lkf; - } - break; - case cLog10: - B = ByteCodePtr[-2]; - if(IsNeverNegativeValueOpcode(B)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(224, - "B[IsNeverNegativeValueOpcode(B)] cLog10 x A[IsComparisonOpcode(A)]", - "B [fp_pow(Value_t(10),x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - goto Lkg; - } - break; - case cLog2: - B = ByteCodePtr[-2]; - if(IsNeverNegativeValueOpcode(B)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(223, - "B[IsNeverNegativeValueOpcode(B)] cLog2 x A[IsComparisonOpcode(A)]", - "B [fp_exp2(x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[-2] = B; */ // redundant, matches B @ 3 - goto Lkh; - } - break; - case cMul: - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - if(y>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(215, - "y[y>Value_t(0)] cMul x A[IsComparisonOpcode(A)]", - "[x/y] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - goto Lki; - } - if(yValue_t(0)) - { - if(ByteCodePtr[-2] == cImmed) - { - y = ImmedPtr[-1]; - if(y>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(217, - "y[y>Value_t(0)] cPow[x>Value_t(0)] x A[IsComparisonOpcode(A)]", - "[fp_pow(x,1/y)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << ", y = " << y - << "\n"); - /* ByteCodePtr[-2] = cImmed; */ // redundant, matches y @ 3 - goto Lkl; - } - } - } - break; - case cSinh: - FP_TRACE_BYTECODE_OPTIMIZATION(230, - "cSinh x A[IsComparisonOpcode(A)]", - "[fp_asinh(x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << "\n"); - goto Lkm; - case cSqr: - if(x>Value_t(0)) - { - FP_TRACE_BYTECODE_OPTIMIZATION(218, - "cSqr[x>Value_t(0)] x A[IsComparisonOpcode(A)]", - "cAbs [fp_sqrt(x)] A", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", x = " << x - << "\n"); - goto Lkn; - } - break; - case cTanh: - if(fp_abs(x)=VarBegin) - { - B = ByteCodePtr[0]; - if(B==A) - { - FP_TRACE_BYTECODE_OPTIMIZATION(335, - "B[B==A] A[A>=VarBegin]", - "B cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << "\n"); - /* ByteCodePtr[0] = B; */ // redundant, matches B @ 1 - goto Lkp; - } - } - if(IsUnaryOpcode(A)) - { - B = ByteCodePtr[0]; - if(B>=VarBegin) - { - C = ByteCodePtr[-1]; - if(C==A) - { - D = ByteCodePtr[-2]; - if(D==B) - { - FP_TRACE_BYTECODE_OPTIMIZATION(336, - "D[D==B] C[C==A] B[B>=VarBegin] A[IsUnaryOpcode(A)]", - "D C cDup", - " with A = " << FP_TRACE_OPCODENAME(A) - << ", B = " << FP_TRACE_OPCODENAME(B) - << ", C = " << FP_TRACE_OPCODENAME(C) - << ", D = " << FP_TRACE_OPCODENAME(D) - << "\n"); - /* ByteCodePtr[-2] = D; */ // redundant, matches D @ 3 - /* ByteCodePtr[-1] = C; */ // redundant, matches C @ 2 - goto Lla; - } - } - } - } - } - goto Llb; -Laa: ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Llc: goto TailCall_cAbs; -Lab: ImmedPtr[0] = fp_abs(x); return; -Lac: ImmedPtr[0] = fp_acos(x); return; -Lad: ImmedPtr[0] = fp_acosh(x); return; -Lae: data->Immed.push_back(Value_t(4)); - ByteCodePtr[-2] = cImmed; - ByteCodePtr -= 2; -Lld: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); -Lle: opcode = cMul; -Llf: FP_ReDefinePointers(); -Llg: goto TailCall_cMul; -Laf: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cSub; - goto TailCall_cSub; -Lag: ImmedPtr[-1] = y+x; - data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); -Llh: FP_ReDefinePointers(); -Lli: goto TailCall_cAdd; -Lah: ImmedPtr[-1] = y+x; -Lai: data->Immed.pop_back(); -Lbf: data->ByteCode.pop_back(); return; -Laj: ImmedPtr[-1] = truthValue(x)&&truthValue(y); goto Lai; -Lak: ImmedPtr[0] = fp_asin(x); return; -Lal: ImmedPtr[0] = fp_asinh(x); return; -Lam: ImmedPtr[0] = fp_atan(x); return; -Lan: ImmedPtr[-1] = fp_atan2(y,x); goto Lai; -Lao: ImmedPtr[0] = fp_atanh(x); return; -Lap: ImmedPtr[0] = fp_cbrt(x); return; -Lba: data->ByteCode.pop_back(); - AddFunctionOpcode(cFloor); -Llj: opcode = cNeg; - FP_ReDefinePointers(); - goto TailCall_cNeg; -Lbb: ImmedPtr[0] = fp_ceil(x); return; -Lbc: ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Llk: goto TailCall_cCos; -Lbd: ImmedPtr[0] = fp_cos(x); return; -Lbe: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - goto TailCall_cCosh; -Lbg: data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); - data->Immed.push_back(Value_t(1)); -Lll: data->ByteCode.push_back(cImmed); - AddFunctionOpcode(cAdd); -Llm: opcode = cSqrt; - FP_ReDefinePointers(); - goto TailCall_cSqrt; -Lbh: ImmedPtr[0] = fp_cosh(x); return; -Lbi: ImmedPtr[0] = RadiansToDegrees(x); return; -Lbj: data->ByteCode.pop_back(); - AddFunctionOpcode(cSec); goto Lle; -Lbk: data->ByteCode.pop_back(); - AddFunctionOpcode(cTan); goto Lle; -Lbl: data->ByteCode.pop_back(); - AddFunctionOpcode(cSin); goto Lle; -Lbm: data->Immed.push_back(Value_t(0)); - ByteCodePtr[0] = cImmed; -Lln: AddFunctionOpcode(cMul); - data->Immed.push_back(Value_t(1)); -Llo: data->ByteCode.push_back(cImmed); -Llp: opcode = cAdd; goto Llh; -Lbn: data->ByteCode.pop_back(); - AddFunctionOpcode(cNeg); - AddFunctionOpcode(cExp); goto Lle; -Lbo: data->ByteCode.pop_back(); - AddFunctionOpcode(cNeg); - AddFunctionOpcode(cExp2); goto Lle; -Lbp: ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Lma: opcode = cMul; goto Llg; -Lca: data->ByteCode.pop_back(); - AddFunctionOpcode(cNeg); - AddFunctionOpcode(cPow); goto Lle; -Lcb: data->ByteCode.pop_back(); - AddFunctionOpcode(cCos); goto Lle; -Lcc: data->ByteCode.pop_back(); - AddFunctionOpcode(cCsc); goto Lle; -Lcd: data->ByteCode.pop_back(); - AddFunctionOpcode(cCot); goto Lle; -Lce: data->Immed.pop_back(); - data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); -Lmb: data->ByteCode.pop_back(); - opcode = cDeg; - FP_ReDefinePointers(); - goto TailCall_cDeg; -Lcf: data->Immed.pop_back(); - data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); -Lmc: data->ByteCode.pop_back(); - opcode = cRad; - FP_ReDefinePointers(); - goto TailCall_cRad; -Lcg: ImmedPtr[-1] = y/x; - data->Immed.pop_back(); goto Lld; -Lch: ImmedPtr[0] = -x; - ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Lmd: goto TailCall_cDiv; -Lci: ImmedPtr[-1] = y/x; goto Lai; -Lcj: ImmedPtr[0] = Value_t(1)/x; goto Lma; -Lck: ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Lme: goto TailCall_cEqual; -Lcl: ImmedPtr[-1] = fp_equal(y,x); goto Lai; -Lcm: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cExp); - data->Immed.push_back(fp_exp(x)); -Lmf: data->ByteCode.push_back(cImmed); goto Lle; -Lcn: ImmedPtr[0] = fp_exp(x); return; -Lco: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cExp2); - data->Immed.push_back(fp_exp2(x)); goto Lmf; -Lcp: ImmedPtr[0] = fp_exp2(x); return; -Lda: data->Immed.push_back(fp_log(Value_t(2))); - data->ByteCode.push_back(cImmed); -Lmg: AddFunctionOpcode(cMul); - opcode = cExp; - FP_ReDefinePointers(); - goto TailCall_cExp; -Ldb: data->ByteCode.pop_back(); - AddFunctionOpcode(cCeil); goto Llj; -Ldc: ImmedPtr[0] = fp_floor(x); return; -Ldd: ImmedPtr[-1] = fp_less(x,y); goto Lai; -Lde: ImmedPtr[0] = Value_t(0.5)/x; - ByteCodePtr[-1] = cImmed; - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); -Lmh: AddFunctionOpcode(cNotNot); return; -Ldf: ImmedPtr[-1] = fp_lessOrEq(x,y); goto Lai; -Ldg: ImmedPtr[0] = fp_int(x); return; -Ldh: data->ByteCode.pop_back(); - AddFunctionOpcode(cSec); return; -Ldi: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cTan; -Lmi: goto TailCall_cTan; -Ldj: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cSin; -Lmj: goto TailCall_cSin; -Ldk: data->ByteCode.pop_back(); - AddFunctionOpcode(cNeg); - opcode = cPow; -Lmk: FP_ReDefinePointers(); -Lml: goto TailCall_cPow; -Ldl: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cCos; goto Llk; -Ldm: data->ByteCode.pop_back(); - AddFunctionOpcode(cCsc); return; -Ldn: data->ByteCode.pop_back(); - AddFunctionOpcode(cRSqrt); return; -Ldo: data->ByteCode.pop_back(); - AddFunctionOpcode(cCot); return; -Ldp: ImmedPtr[0] = Value_t(1)/x; return; -Lea: ImmedPtr[0] = Value_t(0.5)/x; - ByteCodePtr[-1] = cImmed; - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); - opcode = cNot; - FP_ReDefinePointers(); -Lmm: goto TailCall_cNot; -Leb: ImmedPtr[-1] = fp_less(y,x); goto Lai; -Lec: ImmedPtr[-1] = fp_lessOrEq(y,x); goto Lai; -Led: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cLog); - data->Immed.push_back(fp_log(x)); goto Llo; -Lee: data->ByteCode.pop_back(); - AddFunctionOpcode(cAbs); - AddFunctionOpcode(cLog); -Lmn: data->ByteCode.push_back(cDup); goto Llp; -Lef: ImmedPtr[0] = fp_log(x); return; -Leg: data->Immed.push_back(fp_log10(const_e())); -Lmo: ByteCodePtr[0] = cImmed; goto Lle; -Leh: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cLog10); - data->Immed.push_back(fp_log10(x)); goto Llo; -Lei: data->ByteCode.pop_back(); - AddFunctionOpcode(cAbs); - AddFunctionOpcode(cLog10); goto Lmn; -Lej: ImmedPtr[0] = fp_log10(x); return; -Lek: data->Immed.push_back(fp_log2(const_e())); goto Lmo; -Lel: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cLog2); - data->Immed.push_back(fp_log2(x)); goto Llo; -Lem: data->ByteCode.pop_back(); - AddFunctionOpcode(cAbs); - AddFunctionOpcode(cLog2); goto Lmn; -Len: ImmedPtr[0] = fp_log2(x); return; -Leo: ImmedPtr[-1] = Max(x,y); goto Lai; -Lep: ImmedPtr[-1] = Min(x,y); goto Lai; -Lfa: ImmedPtr[-1] = fp_mod(y,x); goto Lai; -Lfb: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cSqr; -Lmp: goto TailCall_cSqr; -Lfc: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cDiv; goto Lmd; -Lfd: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); - AddFunctionOpcode(cMul); goto Llj; -Lfe: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); goto Llj; -Lff: ByteCodePtr[-2] = cImmed; - ByteCodePtr -= 2; - data->ByteCode.pop_back(); -Lna: data->ByteCode.pop_back(); goto Llg; -Lfg: ImmedPtr[-1] = x; -Lnb: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); goto Llf; -Lfh: data->Immed.pop_back(); -Lfi: data->Immed.pop_back(); - data->ByteCode.pop_back(); -Lnc: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); -Lnd: AddFunctionOpcode(A); - data->Immed.push_back(x); - data->ByteCode.push_back(cImmed); goto Llf; -Lfj: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(B); goto Lnd; -Lfk: data->Immed.pop_back(); goto Lnc; -Lfl: ByteCodePtr[-1] = cImmed; goto Lbf; -Lfm: ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; goto Lna; -Lfn: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); goto Lbf; -Lfo: ImmedPtr[0] = x+x; goto Lff; -Lfp: ImmedPtr[0] = RadiansToDegrees(x); goto Lfm; -Lga: data->Immed.pop_back(); goto Lfn; -Lgb: ImmedPtr[-1] = y*x; goto Lnb; -Lgc: ImmedPtr[0] = -x; goto Lfm; -Lgd: ImmedPtr[0] = DegreesToRadians(x); goto Lfm; -Lge: ImmedPtr[-1] = y*x; goto Lai; -Lgf: ByteCodePtr[0] = cDup; - ImmedPtr -= 1; - data->Immed.pop_back(); -Lne: opcode = cAdd; goto Lli; -Lgg: data->Immed.pop_back(); goto Lmb; -Lgh: data->Immed.pop_back(); goto Lmc; -Lgi: data->Immed.pop_back(); - data->ByteCode.pop_back(); goto Llj; -Lgj: data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); goto Llf; -Lgk: data->ByteCode.pop_back(); goto Lgj; -Lgl: ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); -Lnf: goto TailCall_cNEqual; -Lgm: ImmedPtr[-1] = fp_nequal(y,x); goto Lai; -Lgn: ImmedPtr[0] = -x; goto Lbp; -Lgo: ImmedPtr[0] = -x; - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); - opcode = cSin; - FP_ReDefinePointers(); goto Lmj; -Lgp: ImmedPtr[0] = -x; - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); - opcode = cSinh; - FP_ReDefinePointers(); - goto TailCall_cSinh; -Lha: ImmedPtr[0] = -x; - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); - opcode = cTan; - FP_ReDefinePointers(); goto Lmi; -Lhb: ImmedPtr[0] = -x; - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); - opcode = cTanh; - FP_ReDefinePointers(); - goto TailCall_cTanh; -Lhc: ImmedPtr[0] = -x; return; -Lhd: ByteCodePtr -= 1; - data->ByteCode.pop_back(); goto Lmm; -Lhe: data->ByteCode.pop_back(); - AddFunctionOpcode(cAbsNotNot); return; -Lhf: data->ByteCode.pop_back(); -Lho: AddFunctionOpcode(cAbsNot); return; -Lhg: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cNEqual; goto Lnf; -Lhh: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cLessOrEq; - goto TailCall_cLessOrEq; -Lhi: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cLess; - goto TailCall_cLess; -Lhj: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cGreaterOrEq; - goto TailCall_cGreaterOrEq; -Lhk: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cGreater; - goto TailCall_cGreater; -Lhl: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cEqual; goto Lme; -Lhm: data->ByteCode.pop_back(); goto Lmh; -Lhn: ImmedPtr[0] = !truthValue(x); return; -Lhp: ImmedPtr[-1] = truthValue(x)||truthValue(y); goto Lai; -Lia: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cAbs); - data->Immed.push_back(x+x); -Lng: data->ByteCode.push_back(cImmed); goto Lmk; -Lib: ByteCodePtr[-1] = cImmed; - data->ByteCode.pop_back(); goto Lmg; -Lic: ByteCodePtr[-1] = cImmed; - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); - opcode = cExp2; - FP_ReDefinePointers(); - goto TailCall_cExp2; -Lid: ImmedPtr[-1] = y*x; - data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); goto Lmk; -Lie: ByteCodePtr[-1] = cImmed; - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); goto Lmk; -Lif: ByteCodePtr[-1] = cImmed; - ByteCodePtr -= 1; - data->ByteCode.pop_back(); goto Lml; -Lig: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cMul); - data->Immed.push_back(x); goto Lng; -Lih: ImmedPtr[0] = Value_t(0); goto Lln; -Lii: data->Immed.pop_back(); - data->ByteCode.pop_back(); goto Llm; -Lij: data->Immed.pop_back(); - data->ByteCode.pop_back(); - opcode = cCbrt; - FP_ReDefinePointers(); - goto TailCall_cCbrt; -Lik: data->Immed.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cCbrt); -Lnh: opcode = cInv; - FP_ReDefinePointers(); - goto TailCall_cInv; -Lil: data->Immed.pop_back(); goto Ldn; -Lim: data->Immed.pop_back(); - data->ByteCode.pop_back(); goto Lnh; -Lin: data->Immed.pop_back(); - data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cAbs); - data->Immed.push_back(y*x); goto Lng; -Lio: ImmedPtr[0] = x+x; goto Lif; -Lip: ImmedPtr[-1] = fp_pow(y,x); goto Lai; -Lja: ImmedPtr[0] = DegreesToRadians(x); return; -Ljb: data->ByteCode.pop_back(); - AddFunctionOpcode(cSin); goto Llj; -Ljc: ImmedPtr[0] = fp_sin(x); return; -Ljd: data->ByteCode.pop_back(); - AddFunctionOpcode(cSqr); - data->Immed.push_back(Value_t(-1)); goto Lll; -Lje: data->ByteCode.pop_back(); - AddFunctionOpcode(cSinh); goto Llj; -Ljf: ImmedPtr[0] = fp_sinh(x); return; -Ljg: ByteCodePtr -= 1; - data->ByteCode.pop_back(); goto Lmp; -Ljh: ByteCodePtr -= 1; - data->ByteCode.pop_back(); - opcode = cAbs; goto Llc; -Lji: ImmedPtr[0] = fp_sqrt(x); return; -Ljj: ByteCodePtr -= 1; - data->ByteCode.pop_back(); goto Lne; -Ljk: ImmedPtr[-1] = y-x; goto Lai; -Ljl: ImmedPtr[0] = -x; goto Lne; -Ljm: data->ByteCode.pop_back(); - AddFunctionOpcode(cTan); goto Llj; -Ljn: ImmedPtr[0] = fp_tan(x); return; -Ljo: data->ByteCode.pop_back(); - AddFunctionOpcode(cTanh); goto Llj; -Ljp: ImmedPtr[0] = fp_tanh(x); return; -Lka: ImmedPtr[0] = fp_trunc(x); return; -Lkb: ImmedPtr[-1] = x-y; -Lni: data->Immed.pop_back(); - data->ByteCode.pop_back(); -Lnj: data->ByteCode.pop_back(); -Lnk: AddFunctionOpcode(A); return; -Lkc: ImmedPtr[0] = fp_tan(x); -Lnl: ByteCodePtr[-1] = cImmed; goto Lnj; -Lkd: ImmedPtr[0] = fp_log(x); goto Lnl; -Lke: ImmedPtr[0] = fp_log2(x); goto Lnl; -Lkf: ImmedPtr[0] = fp_exp(x); goto Lnl; -Lkg: ImmedPtr[0] = fp_pow(Value_t(10),x); goto Lnl; -Lkh: ImmedPtr[0] = fp_exp2(x); goto Lnl; -Lki: ImmedPtr[-1] = x/y; goto Lni; -Lkj: ImmedPtr[-1] = x/y; - data->Immed.pop_back(); - data->ByteCode.pop_back(); -Lnm: data->ByteCode.pop_back(); - AddFunctionOpcode(OppositeComparisonOpcode(A)); return; -Lkk: ImmedPtr[0] = -x; - ByteCodePtr[-1] = cImmed; goto Lnm; -Lkl: ImmedPtr[-1] = fp_pow(x,1/y); goto Lni; -Lkm: ImmedPtr[0] = fp_asinh(x); goto Lnl; -Lkn: data->Immed.pop_back(); - data->ByteCode.pop_back(); - data->ByteCode.pop_back(); - AddFunctionOpcode(cAbs); - data->Immed.push_back(fp_sqrt(x)); - data->ByteCode.push_back(cImmed); goto Lnk; -Lko: ImmedPtr[0] = fp_atanh(x); goto Lnl; -Lkp: data->ByteCode.push_back(cDup); return; -Lla: ByteCodePtr[0] = cDup; return; -Llb: data->ByteCode.push_back(opcode); return; -return; -// This list of dummy gotos is here to inhibit -// compiler warnings on unused labels -goto TailCall_cAcos;goto TailCall_cAcosh;goto TailCall_cAnd; -goto TailCall_cAsin;goto TailCall_cAsinh;goto TailCall_cAtan; -goto TailCall_cAtan2;goto TailCall_cAtanh;goto TailCall_cCeil; -goto TailCall_cFloor;goto TailCall_cInt;goto TailCall_cLog; -goto TailCall_cLog10;goto TailCall_cLog2;goto TailCall_cMax; -goto TailCall_cMin;goto TailCall_cMod;goto TailCall_cOr; -goto TailCall_cRad;goto TailCall_cSin;goto TailCall_cSinh; -goto TailCall_cSqrt;goto TailCall_cSub;goto TailCall_cTan; -goto TailCall_cTanh;goto TailCall_cTrunc; -#endif - -#undef FP_ReDefinePointers -#undef FP_TRACE_BYTECODE_OPTIMIZATION -#undef FP_TRACE_OPCODENAME diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fparser.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fparser.cpp deleted file mode 100644 index 1c2df00a42..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fparser.cpp +++ /dev/null @@ -1,3070 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.0.3 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -\***************************************************************************/ - -#pragma implementation - -#include "fpconfig.h" -#include "fparser.h" - -#include -#include -#include -#include -#include -#include -using namespace std; - -#include "fptypes.h" -using namespace FUNCTIONPARSERTYPES; - -#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA -#ifndef FP_USE_THREAD_SAFE_EVAL -#define FP_USE_THREAD_SAFE_EVAL -#endif -#endif - -#ifdef __GNUC__ -# define likely(x) __builtin_expect(!!(x), 1) -# define unlikely(x) __builtin_expect(!!(x), 0) -#else -# define likely(x) (x) -# define unlikely(x) (x) -#endif - -//========================================================================= -// Name handling functions -//========================================================================= -namespace -{ - template - inline Value_t const_pi() - { - return Value_t(3.1415926535897932384626433832795L); - } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline MpfrFloat const_pi() { return MpfrFloat::const_pi(); } -#endif - - template - inline Value_t const_e() - { - return Value_t(2.7182818284590452353602874713526624977572L); - } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline MpfrFloat const_e() { return MpfrFloat::const_e(); } -#endif - - - template - bool addNewNameData(namePtrsType& namePtrs, - std::pair >& newName, - bool isVar) - { - typename namePtrsType::iterator nameIter = - namePtrs.lower_bound(newName.first); - - if(nameIter != namePtrs.end() && newName.first == nameIter->first) - { - // redefining a var is not allowed. - if(isVar) - return false; - - // redefining other tokens is allowed, if the type stays the same. - if(nameIter->second.type != newName.second.type) - return false; - - // update the data - nameIter->second = newName.second; - return true; - } - - if(!isVar) - { - // Allocate a copy of the name (pointer stored in the map key) - // However, for VARIABLEs, the pointer points to VariableString, - // which is managed separately. Thusly, only done when !IsVar. - char* namebuf = new char[newName.first.nameLength]; - memcpy(namebuf, newName.first.name, newName.first.nameLength); - newName.first.name = namebuf; - } - - namePtrs.insert(nameIter, newName); - return true; - } - - template - std::string findName(const namePtrsType& nameMap, - unsigned index, - typename NameData::DataType type) - { - for(typename namePtrsType::const_iterator - iter = nameMap.begin(); - iter != nameMap.end(); - ++iter) - { - if(iter->second.type != type) continue; - if(iter->second.index == index) - return std::string(iter->first.name, - iter->first.name + iter->first.nameLength); - } - return "?"; - } - - unsigned readOpcodeForFloatType(const char* input) - { - /* - Return value if built-in function: - 16 lowest bits = function name length - 15 next bits = function opcode - 1 bit (&0x80000000U) = indicates function - Return value if not built-in function: - 31 lowest bits = function name length - other bits zero - */ -#include "fp_identifier_parser.inc" - return 0; - } - - inline unsigned readOpcodeForIntType(const char* input) - { - const unsigned value = readOpcodeForFloatType(input); - if((value & 0x80000000U) != 0 && - !Functions[(value >> 16) & 0x7FFF].okForInt()) - return value & 0xFFFF; - return value; - } - - template - struct IsIntType - { - enum { result = false }; - }; -#ifdef FP_SUPPORT_LONG_INT_TYPE - template<> - struct IsIntType - { - enum { result = true }; - }; -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - struct IsIntType - { - enum { result = true }; - }; -#endif - - template - inline unsigned readOpcode(const char* input) - { - return IsIntType::result - ? readOpcodeForIntType(input) - : readOpcodeForFloatType(input); - } - - template - bool containsOnlyValidNameChars(const std::string& name) - { - if(name.empty()) return false; - return readOpcode(name.c_str()) == (unsigned) name.size(); - } - - template - inline bool truthValue(Value_t d) - { - return IsIntType::result - ? d != 0 - : fp_abs(d) >= Value_t(0.5); - } - - template - inline bool truthValue_abs(Value_t abs_d) - { - return IsIntType::result - ? abs_d > 0 - : abs_d >= Value_t(0.5); - } - - template - inline Value_t Min(Value_t d1, Value_t d2) { return d1 - inline Value_t Max(Value_t d1, Value_t d2) { return d1>d2 ? d1 : d2; } - - template - inline const Value_t& GetDegreesToRadiansFactor() - { - static const Value_t factor = const_pi() / Value_t(180); - return factor; - } - - template - inline Value_t DegreesToRadians(Value_t degrees) - { - return degrees * GetDegreesToRadiansFactor(); - } - - template - inline const Value_t& GetRadiansToDegreesFactor() - { - static const Value_t factor = Value_t(180) / const_pi(); - return factor; - } - - template - inline Value_t RadiansToDegrees(Value_t radians) - { - return radians * GetRadiansToDegreesFactor(); - } - - template - inline bool isEvenInteger(Value_t value) - { - long longval = (long)value; - return fp_equal(value, Value_t(longval)) && (longval%2) == 0; - } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline bool isEvenInteger(MpfrFloat value) - { - return value.isInteger() && value%2 == 0; - } -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline bool isEvenInteger(GmpInt value) - { - return value%2 == 0; - } -#endif - - template - inline bool isOddInteger(Value_t value) - { - long longval = (long)value; - return fp_equal(value, Value_t(longval)) && (longval%2) != 0; - } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline bool isOddInteger(MpfrFloat value) - { - return value.isInteger() && value%2 != 0; - } -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline bool isOddInteger(GmpInt value) - { - return value%2 != 0; - } -#endif - - template - inline int valueToInt(Value_t value) { return int(value); } - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - template<> - inline int valueToInt(MpfrFloat value) { return int(value.toInt()); } -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline int valueToInt(GmpInt value) { return int(value.toInt()); } -#endif -} - - -//========================================================================= -// Data struct implementation -//========================================================================= -template -FunctionParserBase::Data::Data(): - referenceCounter(1), - numVariables(0), - StackSize(0) -{} - -template -FunctionParserBase::Data::Data(const Data& rhs): - referenceCounter(0), - numVariables(rhs.numVariables), - variablesString(rhs.variablesString), - namePtrs(), - FuncPtrs(rhs.FuncPtrs), - FuncParsers(rhs.FuncParsers), - ByteCode(rhs.ByteCode), - Immed(rhs.Immed), -#ifndef FP_USE_THREAD_SAFE_EVAL - Stack(rhs.StackSize), -#endif - StackSize(rhs.StackSize) -{ - for(typename namePtrsType::const_iterator i = - rhs.namePtrs.begin(); - i != rhs.namePtrs.end(); - ++i) - { - if(i->second.type == NameData::VARIABLE) - { - const size_t variableStringOffset = - i->first.name - rhs.variablesString.c_str(); - std::pair > tmp - (NamePtr(&variablesString[variableStringOffset], - i->first.nameLength), - i->second); - namePtrs.insert(namePtrs.end(), tmp); - } - else - { - std::pair > tmp - (NamePtr(new char[i->first.nameLength], i->first.nameLength), - i->second ); - memcpy(const_cast(tmp.first.name), i->first.name, - tmp.first.nameLength); - namePtrs.insert(namePtrs.end(), tmp); - } - } -} - -template -FunctionParserBase::Data::~Data() -{ - for(typename namePtrsType::iterator i = - namePtrs.begin(); - i != namePtrs.end(); - ++i) - { - if(i->second.type != NameData::VARIABLE) - delete[] i->first.name; - } -} - - -//========================================================================= -// FunctionParser constructors, destructor and assignment -//========================================================================= -template -FunctionParserBase::FunctionParserBase(): - delimiterChar(0), - parseErrorType(NO_FUNCTION_PARSED_YET), evalErrorType(0), - data(new Data), - useDegreeConversion(false), - evalRecursionLevel(0), - StackPtr(0), errorLocation(0) -{ -} - -template -FunctionParserBase::~FunctionParserBase() -{ - if(--(data->referenceCounter) == 0) - delete data; -} - -template -FunctionParserBase::FunctionParserBase(const FunctionParserBase& cpy): - delimiterChar(cpy.delimiterChar), - parseErrorType(cpy.parseErrorType), - evalErrorType(cpy.evalErrorType), - data(cpy.data), - useDegreeConversion(cpy.useDegreeConversion), - evalRecursionLevel(0), - StackPtr(0), errorLocation(0) -{ - ++(data->referenceCounter); -} - -template -FunctionParserBase& -FunctionParserBase::operator=(const FunctionParserBase& cpy) -{ - if(data != cpy.data) - { - if(--(data->referenceCounter) == 0) delete data; - - delimiterChar = cpy.delimiterChar; - parseErrorType = cpy.parseErrorType; - evalErrorType = cpy.evalErrorType; - data = cpy.data; - useDegreeConversion = cpy.useDegreeConversion; - evalRecursionLevel = cpy.evalRecursionLevel; - - ++(data->referenceCounter); - } - - return *this; -} - - -template -void FunctionParserBase::setDelimiterChar(char c) -{ - delimiterChar = c; -} - - -//--------------------------------------------------------------------------- -// Copy-on-write method -//--------------------------------------------------------------------------- -template -void FunctionParserBase::CopyOnWrite() -{ - if(data->referenceCounter > 1) - { - Data* oldData = data; - data = new Data(*oldData); - --(oldData->referenceCounter); - data->referenceCounter = 1; - } -} - -template -void FunctionParserBase::ForceDeepCopy() -{ - CopyOnWrite(); -} - - -//========================================================================= -// User-defined constant and function addition -//========================================================================= -template -bool FunctionParserBase::AddConstant(const std::string& name, - Value_t value) -{ - if(!containsOnlyValidNameChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::CONSTANT, value)); - - return addNewNameData(data->namePtrs, newName, false); -} - -template -bool FunctionParserBase::AddUnit(const std::string& name, - Value_t value) -{ - if(!containsOnlyValidNameChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::UNIT, value)); - return addNewNameData(data->namePtrs, newName, false); -} - -template -bool FunctionParserBase::AddFunction -(const std::string& name, FunctionPtr ptr, unsigned paramsAmount) -{ - if(!containsOnlyValidNameChars(name)) return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::FUNC_PTR, - unsigned(data->FuncPtrs.size()))); - - const bool success = addNewNameData(data->namePtrs, newName, false); - if(success) - { - data->FuncPtrs.push_back(typename Data::FuncPtrData()); - data->FuncPtrs.back().funcPtr = ptr; - data->FuncPtrs.back().params = paramsAmount; - } - return success; -} - -template -bool FunctionParserBase::CheckRecursiveLinking -(const FunctionParserBase* fp) const -{ - if(fp == this) return true; - for(unsigned i = 0; i < fp->data->FuncParsers.size(); ++i) - if(CheckRecursiveLinking(fp->data->FuncParsers[i].parserPtr)) - return true; - return false; -} - -template -bool FunctionParserBase::AddFunction(const std::string& name, - FunctionParserBase& fp) -{ - if(!containsOnlyValidNameChars(name) || - CheckRecursiveLinking(&fp)) - return false; - - CopyOnWrite(); - std::pair > newName - (NamePtr(name.data(), unsigned(name.size())), - NameData(NameData::PARSER_PTR, - unsigned(data->FuncParsers.size()))); - - const bool success = addNewNameData(data->namePtrs, newName, false); - if(success) - { - data->FuncParsers.push_back(typename Data::FuncPtrData()); - data->FuncParsers.back().parserPtr = &fp; - data->FuncParsers.back().params = fp.data->numVariables; - } - return success; -} - -template -bool FunctionParserBase::RemoveIdentifier(const std::string& name) -{ - CopyOnWrite(); - - NamePtr namePtr(name.data(), unsigned(name.size())); - - typename namePtrsType::iterator - nameIter = data->namePtrs.find(namePtr); - - if(nameIter != data->namePtrs.end()) - { - if(nameIter->second.type == NameData::VARIABLE) - { - // Illegal attempt to delete variables - return false; - } - delete[] nameIter->first.name; - data->namePtrs.erase(nameIter); - return true; - } - return false; -} - - -//========================================================================= -// Function parsing -//========================================================================= -namespace -{ - // Error messages returned by ErrorMsg(): - const char* const ParseErrorMessage[]= - { - "Syntax error", // 0 - "Mismatched parenthesis", // 1 - "Missing ')'", // 2 - "Empty parentheses", // 3 - "Syntax error: Operator expected", // 4 - "Not enough memory", // 5 - "An unexpected error occurred. Please make a full bug report " - "to the author", // 6 - "Syntax error in parameter 'Vars' given to " - "FunctionParser::Parse()", // 7 - "Illegal number of parameters to function", // 8 - "Syntax error: Premature end of string", // 9 - "Syntax error: Expecting ( after function", // 10 - "Syntax error: Unknown identifier", // 11 - "(No function has been parsed yet)", - "" - }; - - template - inline typename FunctionParserBase::ParseErrorType - noCommaError(char c) - { - return c == ')' ? - FunctionParserBase::ILL_PARAMS_AMOUNT : - FunctionParserBase::SYNTAX_ERROR; - } - - template - inline typename FunctionParserBase::ParseErrorType - noParenthError(char c) - { - return c == ',' ? - FunctionParserBase::ILL_PARAMS_AMOUNT : - FunctionParserBase::MISSING_PARENTH; - } - - template - struct IntLiteralMask - { - enum { mask = - // ( 1UL << ('-'-offset)) | - (0x3FFUL << ('0'-offset)) }; /* 0x3FF = 10 bits worth "1" */ - // Note: If you change fparser to support negative numbers parsing - // (as opposed to parsing them as cNeg followed by literal), - // enable the '-' line above, and change the offset value - // in BeginsLiteral() to '-' instead of '.'. - }; - - template - struct LiteralMask - { - enum { mask = - ( 1UL << ('.'-offset)) | - IntLiteralMask::mask }; - }; -#ifdef FP_SUPPORT_LONG_INT_TYPE - template - struct LiteralMask: public IntLiteralMask - { - }; -#endif -#ifdef FP_SUPPORT_GMP_INT_TYPE - template - struct LiteralMask: public IntLiteralMask - { - }; -#endif - - template - struct SimpleSpaceMask - { - enum { mask = - (1UL << ('\r'-offset)) | - (1UL << ('\n'-offset)) | - (1UL << ('\v'-offset)) | - (1UL << ('\t'-offset)) | - (1UL << (' ' -offset)) }; - }; - - template - inline bool BeginsLiteral(unsigned byte) - { - const unsigned n = sizeof(unsigned long)>=8 ? 0 : '.'; - byte -= n; - if(byte > (unsigned char)('9'-n)) return false; - unsigned long shifted = 1UL << byte; - const unsigned long mask = LiteralMask::mask; - return (mask & shifted) != 0; - } - - template - inline void SkipSpace(CharPtr& function) - { -/* - Space characters in unicode: -U+0020 SPACE Depends on font, often adjusted (see below) -U+00A0 NO-BREAK SPACE As a space, but often not adjusted -U+2000 EN QUAD 1 en (= 1/2 em) -U+2001 EM QUAD 1 em (nominally, the height of the font) -U+2002 EN SPACE 1 en (= 1/2 em) -U+2003 EM SPACE 1 em -U+2004 THREE-PER-EM SPACE 1/3 em -U+2005 FOUR-PER-EM SPACE 1/4 em -U+2006 SIX-PER-EM SPACE 1/6 em -U+2007 FIGURE SPACE Tabular width, the width of digits -U+2008 PUNCTUATION SPACE The width of a period . -U+2009 THIN SPACE 1/5 em (or sometimes 1/6 em) -U+200A HAIR SPACE Narrower than THIN SPACE -U+200B ZERO WIDTH SPACE Nominally no width, but may expand -U+202F NARROW NO-BREAK SPACE Narrower than NO-BREAK SPACE (or SPACE) -U+205F MEDIUM MATHEMATICAL SPACE 4/18 em -U+3000 IDEOGRAPHIC SPACE The width of ideographic (CJK) characters. - Also: -U+000A \n -U+000D \r -U+0009 \t -U+000B \v - As UTF-8 sequences: - 09 - 0A - 0B - 0D - 20 - C2 A0 - E2 80 80-8B - E2 80 AF - E2 81 9F - E3 80 80 -*/ - while(true) - { - const unsigned n = sizeof(unsigned long)>=8 ? 0 : '\t'; - typedef signed char schar; - unsigned byte = (unsigned char)*function; - byte -= n; - // ^Note: values smaller than n intentionally become - // big values here due to integer wrap. The - // comparison below thus excludes them, making - // the effective range 0x09..0x20 (32-bit) - // or 0x00..0x20 (64-bit) within the if-clause. - if(byte <= (unsigned char)(' '-n)) - { - unsigned long shifted = 1UL << byte; - const unsigned long mask = SimpleSpaceMask::mask; - if(mask & shifted) - { ++function; continue; } // \r, \n, \t, \v and space - break; - } - if(likely(byte < 0xC2-n)) break; - - if(byte == 0xC2-n && function[1] == char(0xA0)) - { function += 2; continue; } // U+00A0 - if(byte == 0xE3-n && - function[1] == char(0x80) && function[2] == char(0x80)) - { function += 3; continue; } // U+3000 - if(byte == 0xE2-n) - { - if(function[1] == char(0x81)) - { - if(function[2] != char(0x9F)) break; - function += 3; // U+205F - continue; - } - if(function[1] == char(0x80)) - if(function[2] == char(0xAF) || // U+202F - schar(function[2]) <= schar(0x8B) // U+2000..U+200B - ) - { - function += 3; - continue; - } - } - break; - } // while(true) - } // SkipSpace(CharPtr& function) -} - -// Return parse error message -// -------------------------- -template -const char* FunctionParserBase::ErrorMsg() const -{ - return ParseErrorMessage[parseErrorType]; -} - - -// Parse variables -// --------------- -template -bool FunctionParserBase::ParseVariables -(const std::string& inputVarString) -{ - if(data->variablesString == inputVarString) return true; - - /* Delete existing variables from namePtrs */ - for(typename namePtrsType::iterator i = - data->namePtrs.begin(); - i != data->namePtrs.end(); ) - { - if(i->second.type == NameData::VARIABLE) - { - typename namePtrsType::iterator j (i); - ++i; - data->namePtrs.erase(j); - } - else ++i; - } - data->variablesString = inputVarString; - - const std::string& vars = data->variablesString; - const unsigned len = unsigned(vars.size()); - - unsigned varNumber = VarBegin; - - const char* beginPtr = vars.c_str(); - const char* finalPtr = beginPtr + len; - while(beginPtr < finalPtr) - { - SkipSpace(beginPtr); - unsigned nameLength = readOpcode(beginPtr); - if(nameLength == 0 || (nameLength & 0x80000000U)) return false; - const char* endPtr = beginPtr + nameLength; - SkipSpace(endPtr); - if(endPtr != finalPtr && *endPtr != ',') return false; - - std::pair > newName - (NamePtr(beginPtr, nameLength), - NameData(NameData::VARIABLE, varNumber++)); - - if(!addNewNameData(data->namePtrs, newName, true)) - { - return false; - } - - beginPtr = endPtr + 1; - } - - data->numVariables = varNumber - VarBegin; - return true; -} - -// Parse interface functions -// ------------------------- -template -int FunctionParserBase::Parse(const char* Function, - const std::string& Vars, - bool useDegrees) -{ - CopyOnWrite(); - - if(!ParseVariables(Vars)) - { - parseErrorType = INVALID_VARS; - return int(strlen(Function)); - } - - return ParseFunction(Function, useDegrees); -} - -template -int FunctionParserBase::Parse(const std::string& Function, - const std::string& Vars, - bool useDegrees) -{ - CopyOnWrite(); - - if(!ParseVariables(Vars)) - { - parseErrorType = INVALID_VARS; - return int(Function.size()); - } - - return ParseFunction(Function.c_str(), useDegrees); -} - - -// Main parsing function -// --------------------- -template -int FunctionParserBase::ParseFunction(const char* function, - bool useDegrees) -{ - useDegreeConversion = useDegrees; - parseErrorType = FP_NO_ERROR; - - data->ByteCode.clear(); data->ByteCode.reserve(128); - data->Immed.clear(); data->Immed.reserve(128); - data->StackSize = StackPtr = 0; - - const char* ptr = CompileExpression(function); - if(parseErrorType != FP_NO_ERROR) return int(errorLocation - function); - - assert(ptr); // Should never be null at this point. It's a bug otherwise. - if(*ptr) - { - if(delimiterChar == 0 || *ptr != delimiterChar) - parseErrorType = EXPECT_OPERATOR; - return int(ptr - function); - } - -#ifndef FP_USE_THREAD_SAFE_EVAL - data->Stack.resize(data->StackSize); -#endif - - return -1; -} - - -//========================================================================= -// Parsing and bytecode compiling functions -//========================================================================= -template -inline const char* FunctionParserBase::SetErrorType(ParseErrorType t, - const char* pos) -{ - parseErrorType = t; - errorLocation = pos; - return 0; -} - -template -inline void FunctionParserBase::incStackPtr() -{ - if(++StackPtr > data->StackSize) ++(data->StackSize); -} - -namespace -{ - const unsigned char powi_factor_table[128] = - { - 0,1,0,0,0,0,0,0, 0, 0,0,0,0,0,0,3,/* 0 - 15 */ - 0,0,0,0,0,0,0,0, 0, 5,0,3,0,0,3,0,/* 16 - 31 */ - 0,0,0,0,0,0,0,3, 0, 0,0,0,0,5,0,0,/* 32 - 47 */ - 0,0,5,3,0,0,3,5, 0, 3,0,0,3,0,0,3,/* 48 - 63 */ - 0,0,0,0,0,0,0,0, 0, 0,0,3,0,0,3,0,/* 64 - 79 */ - 0,9,0,0,0,5,0,3, 0, 0,5,7,0,0,0,5,/* 80 - 95 */ - 0,0,0,3,5,0,3,0, 0, 3,0,0,3,0,5,3,/* 96 - 111 */ - 0,0,3,5,0,9,0,7, 3,11,0,3,0,5,3,0,/* 112 - 127 */ - }; - - inline int get_powi_factor(int abs_int_exponent) - { - if(abs_int_exponent >= int(sizeof(powi_factor_table))) return 0; - return powi_factor_table[abs_int_exponent]; - } - -#if 0 - int EstimatePowiComplexity(int abs_int_exponent) - { - int cost = 0; - while(abs_int_exponent > 1) - { - int factor = get_powi_factor(abs_int_exponent); - if(factor) - { - cost += EstimatePowiComplexity(factor); - abs_int_exponent /= factor; - continue; - } - if(!(abs_int_exponent & 1)) - { - abs_int_exponent /= 2; - cost += 3; // sqr - } - else - { - cost += 4; // dup+mul - abs_int_exponent -= 1; - } - } - return cost; - } -#endif - - bool IsEligibleIntPowiExponent(int int_exponent) - { - if(int_exponent == 0) return false; - int abs_int_exponent = int_exponent; - #if 0 - int cost = 0; - - if(abs_int_exponent < 0) - { - cost += 11; - abs_int_exponent = -abs_int_exponent; - } - - cost += EstimatePowiComplexity(abs_int_exponent); - - return cost < (10*3 + 4*4); - #else - if(abs_int_exponent < 0) abs_int_exponent = -abs_int_exponent; - - return (abs_int_exponent >= 1) - && (abs_int_exponent <= 46 || - (abs_int_exponent <= 1024 && - (abs_int_exponent & (abs_int_exponent - 1)) == 0)); - #endif - } - - bool IsLogicalOpcode(unsigned op) - { - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - return true; - default: break; - } - return false; - } - - bool IsComparisonOpcode(unsigned op) - { - switch(op) - { - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - return true; - default: break; - } - return false; - } - - unsigned OppositeComparisonOpcode(unsigned op) - { - switch(op) - { - case cLess: return cGreater; - case cGreater: return cLess; - case cLessOrEq: return cGreaterOrEq; - case cGreaterOrEq: return cLessOrEq; - } - return op; - } - - bool IsNeverNegativeValueOpcode(unsigned op) - { - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - case cSqrt: case cRSqrt: case cSqr: - case cAbs: - case cAcos: case cCosh: - return true; - default: break; - } - return false; - } - - bool IsAlwaysIntegerOpcode(unsigned op) - { - switch(op) - { - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cEqual: case cNEqual: - case cLess: case cLessOrEq: - case cGreater: case cGreaterOrEq: - case cInt: case cFloor: case cCeil: case cTrunc: - return true; - default: break; - } - return false; - } - - bool IsUnaryOpcode(unsigned op) - { - switch(op) - { - case cInv: case cNeg: - case cNot: case cAbsNot: - case cNotNot: case cAbsNotNot: - case cSqr: case cRSqrt: - case cDeg: case cRad: - return true; - } - return (op < FUNC_AMOUNT && Functions[op].params == 1); - } - - bool IsBinaryOpcode(unsigned op) - { - switch(op) - { - case cAdd: case cSub: case cRSub: - case cMul: case cDiv: case cRDiv: - case cMod: - case cEqual: case cNEqual: case cLess: - case cLessOrEq: case cGreater: case cGreaterOrEq: - case cAnd: case cAbsAnd: - case cOr: case cAbsOr: - return true; - } - return (op < FUNC_AMOUNT && Functions[op].params == 2); - } - - bool HasInvalidRangesOpcode(unsigned op) - { -#ifndef FP_NO_EVALUATION_CHECKS - // Returns true, if the given opcode has a range of - // input values that gives an error. - switch(op) - { - case cAcos: // allowed range: |x| <= 1 - case cAsin: // allowed range: |x| <= 1 - case cAcosh: // allowed range: x >= 1 - case cAtanh: // allowed range: |x| < 1 - //case cCot: // note: no range, just separate values - //case cCsc: // note: no range, just separate values - case cLog: // allowed range: x > 0 - case cLog2: // allowed range: x > 0 - case cLog10: // allowed range: x > 0 - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by: // allowed range: x > 0 - #endif - //case cPow: // note: no range, just separate values - //case cSec: // note: no range, just separate values - case cSqrt: // allowed range: x >= 0 - case cRSqrt: // allowed range: x > 0 - //case cDiv: // note: no range, just separate values - //case cRDiv: // note: no range, just separate values - //case cInv: // note: no range, just separate values - return true; - } -#endif - return false; - } - -#ifdef FP_EPSILON - const double EpsilonOrZero = FP_EPSILON; -#else - const double EpsilonOrZero = 0.0; -#endif - -} - -template -inline void FunctionParserBase::AddImmedOpcode(Value_t value) -{ - data->Immed.push_back(value); - data->ByteCode.push_back(cImmed); -} - -template -inline void FunctionParserBase::CompilePowi(int abs_int_exponent) -{ - int num_muls=0; - while(abs_int_exponent > 1) - { - int factor = get_powi_factor(abs_int_exponent); - if(factor) - { - CompilePowi(factor); - abs_int_exponent /= factor; - continue; - } - if(!(abs_int_exponent & 1)) - { - abs_int_exponent /= 2; - data->ByteCode.push_back(cSqr); - } - else - { - data->ByteCode.push_back(cDup); - incStackPtr(); - abs_int_exponent -= 1; - ++num_muls; - } - } - if(num_muls > 0) - { - data->ByteCode.resize(data->ByteCode.size()+num_muls, cMul); - StackPtr -= num_muls; - } -} - -template -inline bool FunctionParserBase::TryCompilePowi(Value_t original_immed) -{ - Value_t changed_immed = original_immed; - for(int sqrt_count=0; /**/; ++sqrt_count) - { - int int_exponent = valueToInt(changed_immed); - if(changed_immed == Value_t(int_exponent) && - IsEligibleIntPowiExponent(int_exponent)) - { - int abs_int_exponent = int_exponent; - if(abs_int_exponent < 0) - abs_int_exponent = -abs_int_exponent; - - data->Immed.pop_back(); data->ByteCode.pop_back(); - --StackPtr; - // ^Though the above is accounted for by the procedure - // that generates cPow, we need it for correct cFetch - // indexes in CompilePowi(). - - while(sqrt_count > 0) - { - int opcode = cSqrt; - if(sqrt_count == 1 && int_exponent < 0) - { - opcode = cRSqrt; - int_exponent = -int_exponent; - } - data->ByteCode.push_back(opcode); - --sqrt_count; - } - CompilePowi(abs_int_exponent); - if(int_exponent < 0) data->ByteCode.push_back(cInv); - ++StackPtr; // Needed because cPow adding will assume this. - return true; - } - if(sqrt_count >= 4) break; - changed_immed += changed_immed; - } - - // When we don't know whether x >= 0, we still know that - // x^y can be safely converted into exp(y * log(x)) - // when y is _not_ integer, because we know that x >= 0. - // Otherwise either expression will give a NaN. - if(/*!IsIntegerConst(original_immed) ||*/ - IsNeverNegativeValueOpcode(data->ByteCode[data->ByteCode.size()-2])) - { - data->Immed.pop_back(); - data->ByteCode.pop_back(); - //--StackPtr; - accounted for by the procedure that generates cPow - AddFunctionOpcode(cLog); - AddImmedOpcode(original_immed); - //incStackPtr(); - this and the next are redundant because... - AddFunctionOpcode(cMul); - //--StackPtr; - ...because the cImmed was popped earlier. - AddFunctionOpcode(cExp); - return true; - } - return false; -} - -//#include "fpoptimizer/fpoptimizer_opcodename.hh" -// ^ needed only if FP_TRACE_BYTECODE_OPTIMIZATION() is used - -template -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ -#define FP_FLOAT_VERSION 1 -#include "fp_opcode_add.inc" -#undef FP_FLOAT_VERSION -} - -#ifdef FP_SUPPORT_LONG_INT_TYPE -template<> -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ - typedef long Value_t; -#define FP_FLOAT_VERSION 0 -#include "fp_opcode_add.inc" -#undef FP_FLOAT_VERSION -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -inline void FunctionParserBase::AddFunctionOpcode(unsigned opcode) -{ - typedef GmpInt Value_t; -#define FP_FLOAT_VERSION 0 -#include "fp_opcode_add.inc" -#undef FP_FLOAT_VERSION -} -#endif - -template -const char* FunctionParserBase::CompileIf(const char* function) -{ - if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function); - - function = CompileExpression(function+1); - if(!function) return 0; - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - OPCODE opcode = cIf; - if(data->ByteCode.back() == cNotNot) data->ByteCode.pop_back(); - if(IsNeverNegativeValueOpcode(data->ByteCode.back())) - { - // If we know that the condition to be tested is always - // a positive value (such as when produced by "x= 0.5, - // cAbsIf simply tests whether cond >= 0.5. - opcode = cAbsIf; - } - - data->ByteCode.push_back(opcode); - const unsigned curByteCodeSize = unsigned(data->ByteCode.size()); - data->ByteCode.push_back(0); // Jump index; to be set later - data->ByteCode.push_back(0); // Immed jump index; to be set later - - --StackPtr; - - function = CompileExpression(function + 1); - if(!function) return 0; - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - data->ByteCode.push_back(cJump); - const unsigned curByteCodeSize2 = unsigned(data->ByteCode.size()); - const unsigned curImmedSize2 = unsigned(data->Immed.size()); - data->ByteCode.push_back(0); // Jump index; to be set later - data->ByteCode.push_back(0); // Immed jump index; to be set later - - --StackPtr; - - function = CompileExpression(function + 1); - if(!function) return 0; - if(*function != ')') - return SetErrorType(noParenthError(*function), function); - - /* A cNop is added as an easy fix for the problem which happens if cNeg - or other similar opcodes optimized by Parse() immediately follow an - else-branch which could be confused as optimizable with that opcode - (eg. cImmed). The optimizer removes the cNop safely. - */ - data->ByteCode.push_back(cNop); - - // Set jump indices - data->ByteCode[curByteCodeSize] = curByteCodeSize2+1; - data->ByteCode[curByteCodeSize+1] = curImmedSize2; - data->ByteCode[curByteCodeSize2] = unsigned(data->ByteCode.size())-1; - data->ByteCode[curByteCodeSize2+1] = unsigned(data->Immed.size()); - - ++function; - SkipSpace(function); - return function; -} - -template -const char* FunctionParserBase::CompileFunctionParams -(const char* function, unsigned requiredParams) -{ - if(*function != '(') return SetErrorType(EXPECT_PARENTH_FUNC, function); - - if(requiredParams > 0) - { - const char* function_end = CompileExpression(function+1); - if(!function_end) - { - // If an error occurred, verify whether it was caused by () - ++function; - SkipSpace(function); - if(*function == ')') return SetErrorType(ILL_PARAMS_AMOUNT, function); - // Not caused by (), use the error message given by CompileExpression() - return 0; - } - function = function_end; - - for(unsigned i = 1; i < requiredParams; ++i) - { - if(*function != ',') - return SetErrorType(noCommaError(*function), function); - - function = CompileExpression(function+1); - if(!function) return 0; - } - // No need for incStackPtr() because each parse parameter calls it - StackPtr -= requiredParams-1; - } - else - { - incStackPtr(); // return value of function is pushed onto the stack - ++function; - SkipSpace(function); - } - - if(*function != ')') - return SetErrorType(noParenthError(*function), function); - ++function; - SkipSpace(function); - return function; -} - -template -const char* FunctionParserBase::CompileElement(const char* function) -{ - if(BeginsLiteral( (unsigned char) *function)) - return CompileLiteral(function); - - unsigned nameLength = readOpcode(function); - if(nameLength == 0) - { - // No identifier found - if(*function == '(') return CompileParenthesis(function); - if(*function == ')') return SetErrorType(MISM_PARENTH, function); - return SetErrorType(SYNTAX_ERROR, function); - } - - // Function, variable or constant - if(nameLength & 0x80000000U) // Function - { - OPCODE func_opcode = OPCODE( (nameLength >> 16) & 0x7FFF ); - return CompileFunction(function + (nameLength & 0xFFFF), func_opcode); - } - - NamePtr name(function, nameLength); - const char* endPtr = function + nameLength; - SkipSpace(endPtr); - - typename namePtrsType::iterator nameIter = - data->namePtrs.find(name); - if(nameIter == data->namePtrs.end()) - { - return SetErrorType(UNKNOWN_IDENTIFIER, function); - } - - const NameData* nameData = &nameIter->second; - switch(nameData->type) - { - case NameData::VARIABLE: // is variable - if(unlikely(!data->ByteCode.empty() && data->ByteCode.back() == nameData->index)) - data->ByteCode.push_back(cDup); - else - data->ByteCode.push_back(nameData->index); - incStackPtr(); - return endPtr; - - case NameData::CONSTANT: - AddImmedOpcode(nameData->value); - incStackPtr(); - return endPtr; - - case NameData::UNIT: - break; - - /* The reason why a cNop is added after a cFCall and a cPCall opcode is - that the function index could otherwise be confused with an actual - opcode (most prominently cImmed), making parse-time optimizations bug - (eg. if cNeg immediately follows an index value equal to cImmed, in - which case the parser would "optimize" it to negating the (inexistent) - literal, causing mayhem). The optimizer gets rid of the cNop safely. - (Another option would be to add some offset to the function index - when storing it in the bytecode, and then subtract that offset when - interpreting the bytecode, but this causes more programming overhead - than the speed overhead caused by the cNop to be worth the trouble, - especially since the function call caused by the opcode is quite slow - anyways.) - */ - case NameData::FUNC_PTR: - function = CompileFunctionParams - (endPtr, data->FuncPtrs[nameData->index].params); - //if(!function) return 0; - data->ByteCode.push_back(cFCall); - data->ByteCode.push_back(nameData->index); - data->ByteCode.push_back(cNop); - return function; - - case NameData::PARSER_PTR: - function = CompileFunctionParams - (endPtr, data->FuncParsers[nameData->index].params); - //if(!function) return 0; - data->ByteCode.push_back(cPCall); - data->ByteCode.push_back(nameData->index); - data->ByteCode.push_back(cNop); - return function; - } - - // When it's an unit (or unrecognized type): - return SetErrorType(SYNTAX_ERROR, function); -} - -template -inline const char* FunctionParserBase::CompileFunction -(const char* function, unsigned func_opcode) -{ - SkipSpace(function); - const FuncDefinition& funcDef = Functions[func_opcode]; - - if(func_opcode == cIf) // "if" is a special case - return CompileIf(function); - - unsigned requiredParams = funcDef.params; -#ifndef FP_DISABLE_EVAL - if(func_opcode == cEval) - requiredParams = data->numVariables; -#endif - - function = CompileFunctionParams(function, requiredParams); - if(!function) return 0; - - if(useDegreeConversion) - { - if(funcDef.flags & FuncDefinition::AngleIn) - AddFunctionOpcode(cRad); - - AddFunctionOpcode(func_opcode); - - if(funcDef.flags & FuncDefinition::AngleOut) - AddFunctionOpcode(cDeg); - } - else - { - AddFunctionOpcode(func_opcode); - } - return function; -} - -template -inline const char* FunctionParserBase::CompileParenthesis(const char* function) -{ - ++function; // Skip '(' - - SkipSpace(function); - if(*function == ')') return SetErrorType(EMPTY_PARENTH, function); - function = CompileExpression(function); - if(!function) return 0; - - if(*function != ')') return SetErrorType(MISSING_PARENTH, function); - ++function; // Skip ')' - - SkipSpace(function); - return function; -} - -template -inline const char* FunctionParserBase::CompileLiteral(const char* function) -{ - char* endPtr; - const double val = strtod(function, &endPtr); - if(endPtr == function) return SetErrorType(SYNTAX_ERROR, function); - AddImmedOpcode(val); - incStackPtr(); - SkipSpace(endPtr); - return endPtr; -} - -template -const char* -FunctionParserBase::CompilePossibleUnit(const char* function) -{ - unsigned nameLength = readOpcode(function); - if(nameLength & 0x80000000U) return function; // built-in function name - if(nameLength != 0) - { - NamePtr name(function, nameLength); - - typename namePtrsType::iterator nameIter = - data->namePtrs.find(name); - if(nameIter != data->namePtrs.end()) - { - const NameData* nameData = &nameIter->second; - if(nameData->type == NameData::UNIT) - { - AddImmedOpcode(nameData->value); - incStackPtr(); - AddFunctionOpcode(cMul); - --StackPtr; - - const char* endPtr = function + nameLength; - SkipSpace(endPtr); - return endPtr; - } - } - } - - return function; -} - -template -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - function = CompilePossibleUnit(function); - - if(*function == '^') - { - ++function; - SkipSpace(function); - - unsigned op = cPow; - if(data->ByteCode.back() == cImmed) - { - if(data->Immed.back() == const_e()) - { op = cExp; data->ByteCode.pop_back(); - data->Immed.pop_back(); --StackPtr; } - else if(data->Immed.back() == Value_t(2)) - { op = cExp2; data->ByteCode.pop_back(); - data->Immed.pop_back(); --StackPtr; } - } - - function = CompileUnaryMinus(function); - if(!function) return 0; - - // add opcode - AddFunctionOpcode(op); - - if(op == cPow) --StackPtr; - } - return function; -} - -#ifdef FP_SUPPORT_FLOAT_TYPE -template<> -inline const char* FunctionParserBase::CompileLiteral(const char* function) -{ - char* endPtr; - const float val = strtof(function, &endPtr); - if(endPtr == function) return SetErrorType(SYNTAX_ERROR, function); - AddImmedOpcode(val); - incStackPtr(); - SkipSpace(endPtr); - return endPtr; -} -#endif - -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE -template<> -inline const char* FunctionParserBase::CompileLiteral(const char* function) -{ - char* endPtr; - const long double val = strtold(function, &endPtr); - if(endPtr == function) return SetErrorType(SYNTAX_ERROR, function); - AddImmedOpcode(val); - incStackPtr(); - SkipSpace(endPtr); - return endPtr; -} -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE -template<> -inline const char* FunctionParserBase::CompileLiteral(const char* function) -{ - char* endPtr; - const long val = strtol(function, &endPtr, 10); - if(endPtr == function) return SetErrorType(SYNTAX_ERROR, function); - AddImmedOpcode(val); - incStackPtr(); - SkipSpace(endPtr); - return endPtr; -} - -template<> -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - return CompilePossibleUnit(function); -} -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -template<> -inline const char* FunctionParserBase::CompileLiteral(const char* function) -{ - char* endPtr; - const MpfrFloat val = MpfrFloat::parseString(function, &endPtr); - if(endPtr == function) return SetErrorType(SYNTAX_ERROR, function); - AddImmedOpcode(val); - incStackPtr(); - SkipSpace(endPtr); - return endPtr; -} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -inline const char* FunctionParserBase::CompileLiteral(const char* function) -{ - char* endPtr; - const GmpInt val = GmpInt::parseString(function, &endPtr); - if(endPtr == function) return SetErrorType(SYNTAX_ERROR, function); - AddImmedOpcode(val); - incStackPtr(); - SkipSpace(endPtr); - return endPtr; -} - -template<> -inline const char* -FunctionParserBase::CompilePow(const char* function) -{ - function = CompileElement(function); - if(!function) return 0; - return CompilePossibleUnit(function); -} -#endif - - - - -template -inline const char* -FunctionParserBase::CompileUnaryMinus(const char* function) -{ - char op = *function; - switch(op) - { - case '-': - case '!': - ++function; - SkipSpace(function); - - function = CompileUnaryMinus(function); - if(!function) return 0; - - AddFunctionOpcode(op=='-' ? cNeg : cNot); - - return function; - default: break; - } - return CompilePow(function); -} - -template -inline const char* -FunctionParserBase::CompileMult(const char* function) -{ - unsigned op = 0; - while(true) - { - function = CompileUnaryMinus(function); - if(!function) return 0; - - // add opcode - if(op) - { - AddFunctionOpcode(op); - if(op != cInv) --StackPtr; - } - switch(*function) - { - case '*': op = cMul; break; - case '/': op = cDiv; break; - case '%': op = cMod; break; - default: return function; - } - - ++function; - SkipSpace(function); - - if(op != cMod && - data->ByteCode.back() == cImmed && - data->Immed.back() == Value_t(1)) - { - op = (op == cDiv ? cInv : 0); - data->Immed.pop_back(); - data->ByteCode.pop_back(); - --StackPtr; - } - } - return function; -} - -template -inline const char* -FunctionParserBase::CompileAddition(const char* function) -{ - unsigned op=0; - while(true) - { - function = CompileMult(function); - if(!function) return 0; - - // add opcode - if(op) - { - AddFunctionOpcode(op); - if(op != cNeg) --StackPtr; - } - switch(*function) - { - case '+': op = cAdd; break; - case '-': op = cSub; break; - default: return function; - } - - ++function; - SkipSpace(function); - - if(data->ByteCode.back() == cImmed && - data->Immed.back() == Value_t(0)) - { - op = (op == cSub ? cNeg : 0); - data->Immed.pop_back(); - data->ByteCode.pop_back(); - --StackPtr; - } - } - return function; -} - -template -inline const char* -FunctionParserBase::CompileComparison(const char* function) -{ - unsigned op=0; - while(true) - { - function = CompileAddition(function); - if(!function) return 0; - - if(op) - { - AddFunctionOpcode(op); - --StackPtr; - } - switch(*function) - { - case '=': - ++function; op = cEqual; break; - case '!': - if(function[1] == '=') - { function += 2; op = cNEqual; break; } - // If '=' does not follow '!', a syntax error will - // be generated at the outermost parsing level - return function; - case '<': - if(function[1] == '=') - { function += 2; op = cLessOrEq; break; } - ++function; op = cLess; break; - case '>': - if(function[1] == '=') - { function += 2; op = cGreaterOrEq; break; } - ++function; op = cGreater; break; - default: return function; - } - SkipSpace(function); - } - return function; -} - -template -inline const char* -FunctionParserBase::CompileAnd(const char* function) -{ - size_t param0end=0; - while(true) - { - function = CompileComparison(function); - if(!function) return 0; - - if(param0end) - { - if(data->ByteCode.back() == cNotNot) data->ByteCode.pop_back(); - - unsigned& param0last = data->ByteCode[param0end-1]; - unsigned& param1last = data->ByteCode.back(); - if(IsNeverNegativeValueOpcode(param1last) && - IsNeverNegativeValueOpcode(param0last)) - { - /* Change !x & !y into !(x | y). Because y might - * contain an cIf, we replace the first cNot/cAbsNot - * with cNop to avoid jump indices being broken. - */ - if((param0last == cNot || param0last == cAbsNot) - && (param1last == cNot || param1last == cAbsNot)) - { - param1last = (param0last==cAbsNot && param1last==cAbsNot) - ? cAbsOr : cOr; - param0last = cNop; - AddFunctionOpcode(cAbsNot); - } - else - AddFunctionOpcode(cAbsAnd); - } - else - AddFunctionOpcode(cAnd); - --StackPtr; - } - if(*function != '&') break; - ++function; - SkipSpace(function); - param0end = data->ByteCode.size(); - } - return function; -} - -template -const char* -FunctionParserBase::CompileExpression(const char* function) -{ - size_t param0end=0; - while(true) - { - SkipSpace(function); - function = CompileAnd(function); - if(!function) return 0; - - if(param0end) - { - if(data->ByteCode.back() == cNotNot) data->ByteCode.pop_back(); - - unsigned& param0last = data->ByteCode[param0end-1]; - unsigned& param1last = data->ByteCode.back(); - if(IsNeverNegativeValueOpcode(param1last) - && IsNeverNegativeValueOpcode(param0last)) - { - /* Change !x | !y into !(x & y). Because y might - * contain an cIf, we replace the first cNot/cAbsNot - * with cNop to avoid jump indices being broken. - */ - if((param0last == cNot || param0last == cAbsNot) - && (param1last == cNot || param1last == cAbsNot)) - { - param1last = (param0last==cAbsNot && param1last==cAbsNot) - ? cAbsAnd : cAnd; - param0last = cNop; - AddFunctionOpcode(cAbsNot); - } - else - AddFunctionOpcode(cAbsOr); - } - else - AddFunctionOpcode(cOr); - --StackPtr; - } - if(*function != '|') break; - ++function; - param0end = data->ByteCode.size(); - } - return function; -} - -//=========================================================================== -// Function evaluation -//=========================================================================== -template -Value_t FunctionParserBase::Eval(const Value_t* Vars) -{ - if(parseErrorType != FP_NO_ERROR) return Value_t(0); - - const unsigned* const ByteCode = &(data->ByteCode[0]); - const Value_t* const Immed = data->Immed.empty() ? 0 : &(data->Immed[0]); - const unsigned ByteCodeSize = unsigned(data->ByteCode.size()); - unsigned IP, DP=0; - int SP=-1; - -#ifdef FP_USE_THREAD_SAFE_EVAL - /* If Eval() may be called by multiple threads simultaneously, - * then Eval() must allocate its own stack. - */ -#ifdef FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA - /* alloca() allocates room from the hardware stack. - * It is automatically freed when the function returns. - */ - Value_t* const Stack = (Value_t*)alloca(data->StackSize*sizeof(Value_t)); -#else - /* Allocate from the heap. Ensure that it is freed - * automatically no matter which exit path is taken. - */ - struct AutoDealloc - { - Value_t* ptr; - ~AutoDealloc() { delete[] ptr; } - } AutoDeallocStack = { new Value_t[data->StackSize] }; - Value_t*& Stack = AutoDeallocStack.ptr; -#endif -#else - /* No thread safety, so use a global stack. */ - std::vector& Stack = data->Stack; -#endif - - for(IP=0; IP Value_t(1)) - { evalErrorType=4; return Value_t(0); } -# endif - Stack[SP] = fp_acos(Stack[SP]); break; - - case cAcosh: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP] < Value_t(1)) - { evalErrorType=4; return Value_t(0); } -# endif - Stack[SP] = fp_acosh(Stack[SP]); break; - - case cAsin: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP] < Value_t(-1) || Stack[SP] > Value_t(1)) - { evalErrorType=4; return Value_t(0); } -# endif - Stack[SP] = fp_asin(Stack[SP]); break; - - case cAsinh: Stack[SP] = fp_asinh(Stack[SP]); break; - - case cAtan: Stack[SP] = fp_atan(Stack[SP]); break; - - case cAtan2: Stack[SP-1] = fp_atan2(Stack[SP-1], Stack[SP]); - --SP; break; - - case cAtanh: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP] <= Value_t(-1) || Stack[SP] >= Value_t(1)) - { evalErrorType=4; return Value_t(0); } -# endif - Stack[SP] = fp_atanh(Stack[SP]); break; - - case cCbrt: Stack[SP] = fp_cbrt(Stack[SP]); break; - - case cCeil: Stack[SP] = fp_ceil(Stack[SP]); break; - - case cCos: Stack[SP] = fp_cos(Stack[SP]); break; - - case cCosh: Stack[SP] = fp_cosh(Stack[SP]); break; - - case cCot: - { - const Value_t t = fp_tan(Stack[SP]); -# ifndef FP_NO_EVALUATION_CHECKS - if(t == Value_t(0)) { evalErrorType=1; return Value_t(0); } -# endif - Stack[SP] = Value_t(1)/t; break; - } - - case cCsc: - { - const Value_t s = fp_sin(Stack[SP]); -# ifndef FP_NO_EVALUATION_CHECKS - if(s == 0) { evalErrorType=1; return Value_t(0); } -# endif - Stack[SP] = Value_t(1)/s; break; - } - - -# ifndef FP_DISABLE_EVAL - case cEval: - { - const unsigned varAmount = data->numVariables; - Value_t retVal = Value_t(0); - if(evalRecursionLevel == FP_EVAL_MAX_REC_LEVEL) - { - evalErrorType = 5; - } - else - { - ++evalRecursionLevel; -# ifndef FP_USE_THREAD_SAFE_EVAL - /* Eval() will use data->Stack for its storage. - * Swap the current stack with an empty one. - * This is the not-thread-safe method. - */ - std::vector tmpStack(Stack.size()); - data->Stack.swap(tmpStack); - retVal = Eval(&tmpStack[SP - varAmount + 1]); - data->Stack.swap(tmpStack); -# else - /* Thread safety mode. We don't need to - * worry about stack reusing here, because - * each instance of Eval() will allocate - * their own stack. - */ - retVal = Eval(&Stack[SP - varAmount + 1]); -# endif - --evalRecursionLevel; - } - SP -= varAmount-1; - Stack[SP] = retVal; - break; - } -# endif - - case cExp: Stack[SP] = fp_exp(Stack[SP]); break; - - case cExp2: Stack[SP] = fp_exp2(Stack[SP]); break; - - case cFloor: Stack[SP] = fp_floor(Stack[SP]); break; - - case cIf: - if(truthValue(Stack[SP--])) - IP += 2; - else - { - const unsigned* buf = &ByteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - } - break; - - case cInt: Stack[SP] = fp_int(Stack[SP]); break; - - case cLog: -# ifndef FP_NO_EVALUATION_CHECKS - if(!(Stack[SP] > Value_t(0))) - { evalErrorType=3; return Value_t(0); } -# endif - Stack[SP] = fp_log(Stack[SP]); break; - - case cLog10: -# ifndef FP_NO_EVALUATION_CHECKS - if(!(Stack[SP] > Value_t(0))) - { evalErrorType=3; return Value_t(0); } -# endif - Stack[SP] = fp_log10(Stack[SP]); - break; - - case cLog2: -# ifndef FP_NO_EVALUATION_CHECKS - if(!(Stack[SP] > Value_t(0))) - { evalErrorType=3; return Value_t(0); } -# endif - Stack[SP] = fp_log2(Stack[SP]); - break; - - case cMax: Stack[SP-1] = Max(Stack[SP-1], Stack[SP]); - --SP; break; - - case cMin: Stack[SP-1] = Min(Stack[SP-1], Stack[SP]); - --SP; break; - - case cPow: -# ifndef FP_NO_EVALUATION_CHECKS - // x:Negative ^ y:NonInteger is failure, - // except when the reciprocal of y forms an integer - /*if(Stack[SP-1] < Value_t(0) && - !IsIntegerConst(Stack[SP]) && - !IsIntegerConst(1.0 / Stack[SP])) - { evalErrorType=3; return Value_t(0); }*/ - // x:0 ^ y:negative is failure - if(Stack[SP-1] == Value_t(0) && - Stack[SP] < Value_t(0)) - { evalErrorType=3; return Value_t(0); } -# endif - Stack[SP-1] = fp_pow(Stack[SP-1], Stack[SP]); - --SP; break; - - case cTrunc: Stack[SP] = fp_trunc(Stack[SP]); break; - - case cSec: - { - const Value_t c = fp_cos(Stack[SP]); -# ifndef FP_NO_EVALUATION_CHECKS - if(c == Value_t(0)) { evalErrorType=1; return Value_t(0); } -# endif - Stack[SP] = Value_t(1)/c; break; - } - - case cSin: Stack[SP] = fp_sin(Stack[SP]); break; - - case cSinh: Stack[SP] = fp_sinh(Stack[SP]); break; - - case cSqrt: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP] < Value_t(0)) { evalErrorType=2; return Value_t(0); } -# endif - Stack[SP] = fp_sqrt(Stack[SP]); break; - - case cTan: Stack[SP] = fp_tan(Stack[SP]); break; - - case cTanh: Stack[SP] = fp_tanh(Stack[SP]); break; - - -// Misc: - case cImmed: Stack[++SP] = Immed[DP++]; break; - - case cJump: - { - const unsigned* buf = &ByteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - break; - } - -// Operators: - case cNeg: Stack[SP] = -Stack[SP]; break; - case cAdd: Stack[SP-1] += Stack[SP]; --SP; break; - case cSub: Stack[SP-1] -= Stack[SP]; --SP; break; - case cMul: Stack[SP-1] *= Stack[SP]; --SP; break; - - case cDiv: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } -# else - if(IsIntType::result && Stack[SP] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } -# endif - Stack[SP-1] /= Stack[SP]; --SP; break; - - case cMod: - if(Stack[SP] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } - Stack[SP-1] = fp_mod(Stack[SP-1], Stack[SP]); - --SP; break; - - case cEqual: - Stack[SP-1] = fp_equal(Stack[SP-1], Stack[SP]); - --SP; break; - - case cNEqual: - Stack[SP-1] = fp_nequal(Stack[SP-1], Stack[SP]); - --SP; break; - - case cLess: - Stack[SP-1] = fp_less(Stack[SP-1], Stack[SP]); - --SP; break; - - case cLessOrEq: - Stack[SP-1] = fp_lessOrEq(Stack[SP-1], Stack[SP]); - --SP; break; - - case cGreater: - Stack[SP-1] = fp_less(Stack[SP], Stack[SP-1]); - --SP; break; - - case cGreaterOrEq: - Stack[SP-1] = fp_lessOrEq(Stack[SP], Stack[SP-1]); - --SP; break; - - case cNot: Stack[SP] = Value_t(!truthValue(Stack[SP])); break; - - case cAnd: - Stack[SP-1] = Value_t - (truthValue(Stack[SP-1]) && truthValue(Stack[SP])); - --SP; break; - - case cOr: - Stack[SP-1] = Value_t - (truthValue(Stack[SP-1]) || truthValue(Stack[SP])); - --SP; break; - - case cNotNot: Stack[SP] = Value_t(truthValue(Stack[SP])); break; - -// Degrees-radians conversion: - case cDeg: Stack[SP] = RadiansToDegrees(Stack[SP]); break; - case cRad: Stack[SP] = DegreesToRadians(Stack[SP]); break; - -// User-defined function calls: - case cFCall: - { - unsigned index = ByteCode[++IP]; - unsigned params = data->FuncPtrs[index].params; - Value_t retVal = - data->FuncPtrs[index].funcPtr(&Stack[SP-params+1]); - SP -= int(params)-1; - Stack[SP] = retVal; - break; - } - - case cPCall: - { - unsigned index = ByteCode[++IP]; - unsigned params = data->FuncParsers[index].params; - Value_t retVal = - data->FuncParsers[index].parserPtr->Eval - (&Stack[SP-params+1]); - SP -= int(params)-1; - Stack[SP] = retVal; - const int error = - data->FuncParsers[index].parserPtr->EvalError(); - if(error) - { - evalErrorType = error; - return 0; - } - break; - } - - -#ifdef FP_SUPPORT_OPTIMIZER - case cFetch: - { - unsigned stackOffs = ByteCode[++IP]; - Stack[SP+1] = Stack[stackOffs]; ++SP; - break; - } - - case cPopNMov: - { - unsigned stackOffs_target = ByteCode[++IP]; - unsigned stackOffs_source = ByteCode[++IP]; - Stack[stackOffs_target] = Stack[stackOffs_source]; - SP = stackOffs_target; - break; - } - - case cLog2by: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP-1] <= Value_t(0)) - { evalErrorType=3; return Value_t(0); } -# endif - Stack[SP-1] = fp_log2(Stack[SP-1]) * Stack[SP]; - --SP; - break; -#endif // FP_SUPPORT_OPTIMIZER - case cAbsNot: - Stack[SP] = Value_t(!truthValue_abs(Stack[SP])); break; - case cAbsNotNot: - Stack[SP] = Value_t(truthValue_abs(Stack[SP])); break; - case cAbsAnd: - Stack[SP-1] = Value_t(truthValue_abs(Stack[SP-1]) && - truthValue_abs(Stack[SP])); - --SP; break; - case cAbsOr: - Stack[SP-1] = Value_t(truthValue_abs(Stack[SP-1]) || - truthValue_abs(Stack[SP])); - --SP; break; - case cAbsIf: - if(truthValue_abs(Stack[SP--])) - IP += 2; - else - { - const unsigned* buf = &ByteCode[IP+1]; - IP = buf[0]; - DP = buf[1]; - } - break; - - case cDup: Stack[SP+1] = Stack[SP]; ++SP; break; - - case cInv: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } -# else - if(IsIntType::result && Stack[SP] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } -# endif - Stack[SP] = Value_t(1)/Stack[SP]; - break; - - case cSqr: - Stack[SP] = Stack[SP]*Stack[SP]; - break; - - case cRDiv: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP-1] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } -# else - if(IsIntType::result && Stack[SP-1] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } -# endif - Stack[SP-1] = Stack[SP] / Stack[SP-1]; --SP; break; - - case cRSub: Stack[SP-1] = Stack[SP] - Stack[SP-1]; --SP; break; - - case cRSqrt: -# ifndef FP_NO_EVALUATION_CHECKS - if(Stack[SP] == Value_t(0)) - { evalErrorType=1; return Value_t(0); } -# endif - Stack[SP] = Value_t(1) / fp_sqrt(Stack[SP]); break; - - case cNop: break; - -// Variables: - default: - Stack[++SP] = Vars[ByteCode[IP]-VarBegin]; - } - } - - evalErrorType=0; - return Stack[SP]; -} - - -//=========================================================================== -// Variable deduction -//=========================================================================== -namespace -{ - template - int deduceVariables(FunctionParserBase& fParser, - const char* funcStr, - std::string& destVarString, - int* amountOfVariablesFound, - std::vector* destVarNames, - bool useDegrees) - { - typedef std::set StrSet; - StrSet varNames; - - int oldIndex = -1; - - while(true) - { - destVarString.clear(); - for(StrSet::iterator iter = varNames.begin(); - iter != varNames.end(); - ++iter) - { - if(iter != varNames.begin()) destVarString += ","; - destVarString += *iter; - } - - const int index = - fParser.Parse(funcStr, destVarString, useDegrees); - if(index < 0) break; - if(index == oldIndex) return index; - - unsigned nameLength = readOpcode(funcStr + index); - if(nameLength & 0x80000000U) return index; - if(nameLength == 0) return index; - - varNames.insert(std::string(funcStr + index, nameLength)); - oldIndex = index; - } - - if(amountOfVariablesFound) - *amountOfVariablesFound = int(varNames.size()); - - if(destVarNames) - destVarNames->assign(varNames.begin(), varNames.end()); - - return -1; - } -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - int* amountOfVariablesFound, - bool useDegrees) -{ - std::string varString; - return deduceVariables(*this, function.c_str(), varString, - amountOfVariablesFound, 0, useDegrees); -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - std::string& resultVarString, - int* amountOfVariablesFound, - bool useDegrees) -{ - std::string varString; - const int index = - deduceVariables(*this, function.c_str(), varString, - amountOfVariablesFound, 0, useDegrees); - if(index < 0) resultVarString = varString; - return index; -} - -template -int FunctionParserBase::ParseAndDeduceVariables -(const std::string& function, - std::vector& resultVars, - bool useDegrees) -{ - std::string varString; - std::vector vars; - const int index = - deduceVariables(*this, function.c_str(), varString, - 0, &vars, useDegrees); - if(index < 0) resultVars.swap(vars); - return index; -} - - -//=========================================================================== -// Debug output -//=========================================================================== -#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT -#include -#include -namespace -{ - inline void printHex(std::ostream& dest, unsigned n) - { - std::ios::fmtflags flags = dest.flags(); - dest.width(4); dest.fill('0'); std::hex(dest); //uppercase(dest); - dest << n; - dest.flags(flags); - } - - void padLine(std::ostringstream& dest, unsigned destLength) - { - for(size_t currentLength = dest.str().length(); - currentLength < destLength; - ++currentLength) - { - dest << ' '; - } - } - - const struct PowiMuliType - { - unsigned opcode_square; - unsigned opcode_cumulate; - unsigned opcode_invert; - unsigned opcode_half; - unsigned opcode_invhalf; - } iseq_powi = {cSqr,cMul,cInv,cSqrt,cRSqrt}, - iseq_muli = {~unsigned(0), cAdd,cNeg, ~unsigned(0),~unsigned(0) }; - - template - Value_t ParsePowiMuli( - const PowiMuliType& opcodes, - const std::vector& ByteCode, unsigned& IP, - unsigned limit, - size_t factor_stack_base, - std::vector& stack, - bool IgnoreExcess) - { - Value_t result = Value_t(1); - while(IP < limit) - { - if(ByteCode[IP] == opcodes.opcode_square) - { - if(!IsIntegerConst(result)) break; - result *= Value_t(2); - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invert) - { - if(result < Value_t(0)) break; - result = -result; - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_half) - { - if(IsIntegerConst(result) && result > Value_t(0) && - (valueToInt(result)) % 2 == 0) - break; - if(IsIntegerConst(result * Value_t(0.5))) break; - result *= Value_t(0.5); - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invhalf) - { - if(IsIntegerConst(result) && result > Value_t(0) && - (valueToInt(result)) % 2 == 0) - break; - if(IsIntegerConst(result * Value_t(-0.5))) break; - result *= Value_t(-0.5); - ++IP; - continue; - } - - unsigned dup_fetch_pos = IP; - Value_t lhs = Value_t(1); - - #ifdef FP_SUPPORT_OPTIMIZER - if(ByteCode[IP] == cFetch) - { - unsigned index = ByteCode[++IP]; - if(index < factor_stack_base - || size_t(index-factor_stack_base) >= stack.size()) - { - // It wasn't a powi-fetch after all - IP = dup_fetch_pos; - break; - } - lhs = stack[index - factor_stack_base]; - // Note: ^This assumes that cFetch of recentmost - // is always converted into cDup. - goto dup_or_fetch; - } - #endif - if(ByteCode[IP] == cDup) - { - lhs = result; - goto dup_or_fetch; - - dup_or_fetch: - stack.push_back(result); - ++IP; - Value_t subexponent = ParsePowiMuli - (opcodes, - ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - if(IP >= limit && IgnoreExcess) - return lhs*subexponent; - if(IP >= limit || ByteCode[IP] != opcodes.opcode_cumulate) - { - // It wasn't a powi-dup after all - IP = dup_fetch_pos; - break; - } - ++IP; // skip opcode_cumulate - stack.pop_back(); - result += lhs*subexponent; - continue; - } - break; - } - return result; - } - - template - Value_t ParsePowiSequence(const std::vector& ByteCode, - unsigned& IP, unsigned limit, - size_t factor_stack_base, - bool IgnoreExcess = false) - { - std::vector stack; - stack.push_back(Value_t(1)); - return ParsePowiMuli(iseq_powi, ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - } - - template - Value_t ParseMuliSequence(const std::vector& ByteCode, - unsigned& IP, unsigned limit, - size_t factor_stack_base, - bool IgnoreExcess = false) - { - std::vector stack; - stack.push_back(Value_t(1)); - return ParsePowiMuli(iseq_muli, ByteCode, IP, limit, - factor_stack_base, stack, - IgnoreExcess); - } - - struct IfInfo - { - std::pair condition; - std::pair thenbranch; - unsigned endif_location; - - IfInfo() : condition(), thenbranch(), endif_location() { } - }; -} - -template -void FunctionParserBase::PrintByteCode(std::ostream& dest, - bool showExpression) const -{ - dest << "Size of stack: " << data->StackSize << "\n"; - - std::ostringstream outputBuffer; - std::ostream& output = (showExpression ? outputBuffer : dest); - - const std::vector& ByteCode = data->ByteCode; - const std::vector& Immed = data->Immed; - - std::vector > stack; - std::vector if_stack; - - for(unsigned IP = 0, DP = 0; IP <= ByteCode.size(); ++IP) - { - after_powi_or_muli:; - std::string n; - bool out_params = false; - unsigned params = 2, produces = 1, opcode = 0; - - if(showExpression && !if_stack.empty() && - ( // Normal If termination rule: - if_stack.back().endif_location == IP - // This rule matches when cJumps are threaded: - || (IP < ByteCode.size() && ByteCode[IP] == cJump - && !if_stack.back().thenbranch.second.empty()) - )) - { - printHex(output, IP); - if(if_stack.back().endif_location == IP) - output << ": (phi)"; - else - output << ": (phi_threaded)"; - - stack.resize(stack.size()+2); - std::swap(stack[stack.size()-3], stack[stack.size()-1]); - std::swap(if_stack.back().condition, stack[stack.size()-3]); - std::swap(if_stack.back().thenbranch, stack[stack.size()-2]); - opcode = cIf; - params = 3; - --IP; - if_stack.pop_back(); - } - else - { - if(IP >= ByteCode.size()) break; - opcode = ByteCode[IP]; - - if(showExpression && ( - opcode == cSqr || opcode == cDup - || opcode == cInv - || opcode == cSqrt || opcode == cRSqrt - #ifdef FP_SUPPORT_OPTIMIZER - || opcode == cFetch - #endif - )) - { - unsigned changed_ip = IP; - Value_t exponent = - ParsePowiSequence - (ByteCode, changed_ip, - if_stack.empty() - ? (unsigned)ByteCode.size() - : if_stack.back().endif_location, - stack.size()-1); - std::string operation_prefix; - std::ostringstream operation_value; - int prio = 0; - if(exponent == 1.0) - { - if(opcode != cDup) goto not_powi_or_muli; - Value_t factor = - ParseMuliSequence - (ByteCode, changed_ip, - if_stack.empty() - ? (unsigned)ByteCode.size() - : if_stack.back().endif_location, - stack.size()-1); - if(factor == Value_t(1) || factor == Value_t(-1)) - goto not_powi_or_muli; - operation_prefix = "*"; - operation_value << factor; - prio = 3; - } - else - { - prio = 2; - operation_prefix = "^"; - operation_value << exponent; - } - - //unsigned explanation_before = changed_ip-2; - unsigned explanation_before = changed_ip-1; - - const char* explanation_prefix = "_"; - for(const unsigned first_ip = IP; IP < changed_ip; ++IP) - { - printHex(output, IP); - output << ": "; - - const char* sep = "|"; - if(first_ip+1 == changed_ip) - { sep = "="; explanation_prefix = " "; } - else if(IP == first_ip) sep = "\\"; - else if(IP+1 == changed_ip) sep = "/"; - else explanation_prefix = "="; - - switch(ByteCode[IP]) - { - case cInv: output << "inv"; break; - case cNeg: output << "neg"; break; - case cDup: output << "dup"; break; - case cSqr: output << "sqr"; break; - case cMul: output << "mul"; break; - case cAdd: output << "add"; break; - case cCbrt: output << "cbrt"; break; - case cSqrt: output << "sqrt"; break; - case cRSqrt: output << "rsqrt"; break; - #ifdef FP_SUPPORT_OPTIMIZER - case cFetch: - { - unsigned index = ByteCode[++IP]; - output << "cFetch(" << index << ")"; - break; - } - #endif - default: break; - } - padLine(outputBuffer, 20); - output << sep; - if(IP >= explanation_before) - { - explanation_before = (unsigned)ByteCode.size(); - output << explanation_prefix - << '[' << (stack.size()-1) << ']'; - std::string last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - output << last; - output << operation_prefix; - output << operation_value.str(); - } - else - { - unsigned p = first_ip; - Value_t exp = operation_prefix=="^" ? - ParsePowiSequence - (ByteCode, p, IP+1, stack.size()-1, true) : - ParseMuliSequence - (ByteCode, p, IP+1, stack.size()-1, true); - std::string last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - output << " ..." << last; - output << operation_prefix; - output << exp; - } - dest << outputBuffer.str() << std::endl; - outputBuffer.str(""); - } - - std::string& last = stack.back().second; - if(stack.back().first >= prio) - last = "(" + last + ")"; - last += operation_prefix; - last += operation_value.str(); - stack.back().first = prio; - - goto after_powi_or_muli; - } - not_powi_or_muli:; - printHex(output, IP); - output << ": "; - - switch(opcode) - { - case cIf: - { - unsigned label = ByteCode[IP+1]+1; - output << "jz "; - printHex(output, label); - params = 1; - produces = 0; - IP += 2; - - if_stack.resize(if_stack.size() + 1); - std::swap( if_stack.back().condition, stack.back() ); - if_stack.back().endif_location = (unsigned) ByteCode.size(); - stack.pop_back(); - break; - } - case cAbsIf: - { - unsigned dp = ByteCode[IP+2]; - unsigned label = ByteCode[IP+1]+1; - output << "jz_abs " << dp << ","; - printHex(output, label); - params = 1; - produces = 0; - IP += 2; - - if_stack.resize(if_stack.size() + 1); - std::swap( if_stack.back().condition, stack.back() ); - if_stack.back().endif_location = (unsigned) ByteCode.size(); - stack.pop_back(); - break; - } - - case cJump: - { - unsigned dp = ByteCode[IP+2]; - unsigned label = ByteCode[IP+1]+1; - - if(!if_stack.empty() && !stack.empty()) - { - std::swap(if_stack.back().thenbranch, stack.back()); - if_stack.back().endif_location = label; - stack.pop_back(); - } - - output << "jump " << dp << ","; - printHex(output, label); - params = 0; - produces = 0; - IP += 2; - break; - } - case cImmed: - { - if(showExpression) - { - std::ostringstream buf; - buf.precision(8); - buf << Immed[DP]; - stack.push_back( std::make_pair(0, buf.str()) ); - } - output.precision(8); - output << "push " << Immed[DP]; - ++DP; - produces = 0; - break; - } - - case cFCall: - { - const unsigned index = ByteCode[++IP]; - params = data->FuncPtrs[index].params; - static std::string name; - name = "f:" + findName(data->namePtrs, index, - NameData::FUNC_PTR); - n = name.c_str(); - out_params = true; - break; - } - - case cPCall: - { - const unsigned index = ByteCode[++IP]; - params = data->FuncParsers[index].params; - static std::string name; - name = "p:" + findName(data->namePtrs, index, - NameData::PARSER_PTR); - n = name.c_str(); - out_params = true; - break; - } - - default: - if(OPCODE(opcode) < VarBegin) - { - switch(opcode) - { - case cNeg: n = "neg"; params = 1; break; - case cAdd: n = "add"; break; - case cSub: n = "sub"; break; - case cMul: n = "mul"; break; - case cDiv: n = "div"; break; - case cMod: n = "mod"; break; - case cPow: n = "pow"; break; - case cEqual: n = "eq"; break; - case cNEqual: n = "neq"; break; - case cLess: n = "lt"; break; - case cLessOrEq: n = "le"; break; - case cGreater: n = "gt"; break; - case cGreaterOrEq: n = "ge"; break; - case cAnd: n = "and"; break; - case cOr: n = "or"; break; - case cNot: n = "not"; params = 1; break; - case cNotNot: n = "notnot"; params = 1; break; - case cDeg: n = "deg"; params = 1; break; - case cRad: n = "rad"; params = 1; break; - - #ifndef FP_DISABLE_EVAL - case cEval: n = "eval"; params = data->numVariables; - #endif - - #ifdef FP_SUPPORT_OPTIMIZER - case cLog2by: n = "log2by"; params = 2; out_params = 1; break; - case cFetch: - { - unsigned index = ByteCode[++IP]; - if(showExpression && index < stack.size()) - stack.push_back(stack[index]); - output << "cFetch(" << index << ")"; - produces = 0; - break; - } - case cPopNMov: - { - size_t a = ByteCode[++IP]; - size_t b = ByteCode[++IP]; - if(showExpression && b < stack.size()) - { - std::pair stacktop(0, "?"); - if(b < stack.size()) stacktop = stack[b]; - stack.resize(a); - stack.push_back(stacktop); - } - output << "cPopNMov(" << a << ", " << b << ")"; - produces = 0; - break; - } - #endif - case cAbsAnd: n = "abs_and"; break; - case cAbsOr: n = "abs_or"; break; - case cAbsNot: n = "abs_not"; params = 1; break; - case cAbsNotNot: n = "abs_notnot"; params = 1; break; - case cDup: - { - if(showExpression) - stack.push_back(stack.back()); - output << "dup"; - produces = 0; - break; - } - case cInv: n = "inv"; params = 1; break; - case cSqr: n = "sqr"; params = 1; break; - case cRDiv: n = "rdiv"; break; - case cRSub: n = "rsub"; break; - case cRSqrt: n = "rsqrt"; params = 1; break; - - case cNop: - output << "nop"; params = 0; produces = 0; - break; - - default: - n = Functions[opcode-cAbs].name; - params = Functions[opcode-cAbs].params; - out_params = params != 1; - } - } - else - { - if(showExpression) - { - stack.push_back(std::make_pair(0, - (findName(data->namePtrs, opcode, - NameData::VARIABLE)))); - } - output << "push Var" << opcode-VarBegin; - produces = 0; - } - } - } - if(produces) output << n; - if(out_params) output << " (" << params << ")"; - if(showExpression) - { - padLine(outputBuffer, 20); - - if(produces > 0) - { - std::ostringstream buf; - const char *paramsep = ",", *suff = ""; - int prio = 0; bool commutative = false; - switch(opcode) - { - case cIf: buf << "if("; suff = ")"; - break; - case cAbsIf: buf << "if("; suff = ")"; - break; - case cOr: prio = 6; paramsep = "|"; commutative = true; - break; - case cAnd: prio = 5; paramsep = "&"; commutative = true; - break; - case cAdd: prio = 4; paramsep = "+"; commutative = true; - break; - case cSub: prio = 4; paramsep = "-"; - break; - case cMul: prio = 3; paramsep = "*"; commutative = true; - break; - case cDiv: prio = 3; paramsep = "/"; - break; - case cPow: prio = 2; paramsep = "^"; - break; - case cAbsOr: prio = 6; paramsep = "|"; commutative = true; - break; - case cAbsAnd: prio = 5; paramsep = "&"; commutative = true; - break; - case cSqr: prio = 2; suff = "^2"; - break; - case cNeg: buf << "(-("; suff = "))"; - break; - case cNot: buf << "(!("; suff = "))"; - break; - default: buf << n << '('; suff = ")"; - } - - const char* sep = ""; - for(unsigned a=0; a& prev = - stack[stack.size() - params + a]; - if(prio > 0 && (prev.first > prio || - (prev.first==prio && !commutative))) - buf << '(' << prev.second << ')'; - else - buf << prev.second; - } - sep = paramsep; - } - if(stack.size() >= params) - stack.resize(stack.size() - params); - else - stack.clear(); - buf << suff; - stack.push_back(std::make_pair(prio, buf.str())); - //if(n.size() <= 4 && !out_params) padLine(outputBuffer, 20); - } - //padLine(outputBuffer, 20); - output << "= "; - if(((opcode == cIf || opcode == cAbsIf) && params != 3) - || opcode == cJump || opcode == cNop) - output << "(void)"; - else if(stack.empty()) - output << "[?] ?"; - else - output << '[' << (stack.size()-1) << ']' - << stack.back().second; - } - - if(showExpression) - { - dest << outputBuffer.str() << std::endl; - outputBuffer.str(""); - } - else - output << std::endl; - } -} -#endif - - -#ifndef FP_SUPPORT_OPTIMIZER -template -void FunctionParserBase::Optimize() -{ - // Do nothing if no optimizations are supported. -} -#endif - -FUNCTIONPARSER_INSTANTIATE_TYPES - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fparser.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fparser.h deleted file mode 100644 index fa9695478a..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fparser.h +++ /dev/null @@ -1,159 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.0.3 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -\***************************************************************************/ - -#ifndef ONCE_FPARSER_H_ -#define ONCE_FPARSER_H_ - -#pragma interface - -#include -#include - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT -#include -#endif - -#ifdef _MSC_VER -// Visual Studio's warning about missing definitions for the explicit -// FunctionParserBase instantiations is irrelevant here. -#pragma warning(disable : 4661) -#endif - -namespace FPoptimizer_CodeTree { class CodeTree; } - -template -class FunctionParserBase -{ -public: - enum ParseErrorType - { - SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH, - EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS, - ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC, - UNKNOWN_IDENTIFIER, - NO_FUNCTION_PARSED_YET, - FP_NO_ERROR - }; - - typedef Value_t value_type; - - - int Parse(const char* Function, const std::string& Vars, - bool useDegrees = false); - int Parse(const std::string& Function, const std::string& Vars, - bool useDegrees = false); - - void setDelimiterChar(char); - - const char* ErrorMsg() const; - inline ParseErrorType GetParseErrorType() const { return parseErrorType; } - - Value_t Eval(const Value_t* Vars); - inline int EvalError() const { return evalErrorType; } - - bool AddConstant(const std::string& name, Value_t value); - bool AddUnit(const std::string& name, Value_t value); - - typedef Value_t (*FunctionPtr)(const Value_t*); - - bool AddFunction(const std::string& name, - FunctionPtr, unsigned paramsAmount); - bool AddFunction(const std::string& name, FunctionParserBase&); - - bool RemoveIdentifier(const std::string& name); - - void Optimize(); - - - int ParseAndDeduceVariables(const std::string& function, - int* amountOfVariablesFound = 0, - bool useDegrees = false); - int ParseAndDeduceVariables(const std::string& function, - std::string& resultVarString, - int* amountOfVariablesFound = 0, - bool useDegrees = false); - int ParseAndDeduceVariables(const std::string& function, - std::vector& resultVars, - bool useDegrees = false); - - - FunctionParserBase(); - ~FunctionParserBase(); - - // Copy constructor and assignment operator (implemented using the - // copy-on-write technique for efficiency): - FunctionParserBase(const FunctionParserBase&); - FunctionParserBase& operator=(const FunctionParserBase&); - - - void ForceDeepCopy(); - - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT - // For debugging purposes only: - void PrintByteCode(std::ostream& dest, bool showExpression = true) const; -#endif - - - -//======================================================================== -private: -//======================================================================== - -// Private data: -// ------------ - char delimiterChar; - ParseErrorType parseErrorType; - int evalErrorType; - - friend class FPoptimizer_CodeTree::CodeTree; - - struct Data; - Data* data; - - bool useDegreeConversion; - unsigned evalRecursionLevel; - unsigned StackPtr; - const char* errorLocation; - - -// Private methods: -// --------------- - void CopyOnWrite(); - bool CheckRecursiveLinking(const FunctionParserBase*) const; - bool NameExists(const char*, unsigned); - bool ParseVariables(const std::string&); - int ParseFunction(const char*, bool); - const char* SetErrorType(ParseErrorType, const char*); - - void AddFunctionOpcode(unsigned); - void AddImmedOpcode(Value_t v); - void incStackPtr(); - void CompilePowi(int); - bool TryCompilePowi(Value_t); - - const char* CompileIf(const char*); - const char* CompileFunctionParams(const char*, unsigned); - const char* CompileElement(const char*); - const char* CompilePossibleUnit(const char*); - const char* CompilePow(const char*); - const char* CompileUnaryMinus(const char*); - const char* CompileMult(const char*); - const char* CompileAddition(const char*); - const char* CompileComparison(const char*); - const char* CompileAnd(const char*); - const char* CompileExpression(const char*); - inline const char* CompileFunction(const char*, unsigned); - inline const char* CompileParenthesis(const char*); - inline const char* CompileLiteral(const char*); -}; - -class FunctionParser: public FunctionParserBase {}; -class FunctionParser_f: public FunctionParserBase {}; -class FunctionParser_ld: public FunctionParserBase {}; -class FunctionParser_li: public FunctionParserBase {}; - -#endif diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpaux.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpaux.h deleted file mode 100644 index a6878bf357..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpaux.h +++ /dev/null @@ -1,599 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.0.3 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -\***************************************************************************/ - -// NOTE: -// This file contains only internal types for the function parser library. -// You don't need to include this file in your code. Include "fparser.hh" -// only. - -#ifndef ONCE_FPARSER_AUX_H_ -#define ONCE_FPARSER_AUX_H_ - -#include -#include - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -#include "mpfr/MpfrFloat.h" -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -#include "mpfr/GmpInt.h" -#endif - -#ifdef ONCE_FPARSER_H_ -namespace FUNCTIONPARSERTYPES -{ -//========================================================================== -// Math funcs -//========================================================================== - /* fp_pow() is a wrapper for std::pow() - * that produces an identical value for - * exp(1) ^ 2.0 (0x4000000000000000) - * as exp(2.0) (0x4000000000000000) - * - std::pow() on x86_64 - * produces 2.0 (0x3FFFFFFFFFFFFFFF) instead! - * See comments below for other special traits. - */ - template - inline ValueT fp_pow_with_exp_log(const ValueT& x, const ValueT& y) - { - // Requirements: x > 0. - return fp_exp(fp_log(x) * y); - } - - template - inline ValueT fp_powi(ValueT x, unsigned long y) - { - // Requirements: y is non-negative integer. - ValueT result(1); - while(y != 0) - { - if(y & 1) { result *= x; y -= 1; } - else { x *= x; y /= 2; } - } - return result; - } - - template - ValueT fp_pow(const ValueT& x, const ValueT& y) - { - if(x == ValueT(1)) return ValueT(1); - // y is now zero or positive - - if(IsIntegerConst(y)) - { - // Use fast binary exponentiation algorithm - // See http://en.wikipedia.org/wiki/Exponentiation_by_squaring - if(y >= ValueT(0)) - return fp_powi(x, (long)y); - else - return ValueT(1) / fp_powi(x, -(long)y); - } - - if(y >= ValueT(0)) - { - // y is now positive. Calculate using exp(log(x)*y). - // See http://en.wikipedia.org/wiki/Exponentiation#Real_powers - if(x > ValueT(0)) return fp_pow_with_exp_log(x, y); - if(x == ValueT(0)) return ValueT(0); - // At this point, y > 0.0 and x is known to be < 0.0, - // because positive and zero cases are already handled. - // - if(!IsIntegerConst(y*ValueT(16))) - return -fp_pow_with_exp_log(-x, y); - // ^This is not technically correct, but it allows - // functions such as cbrt(x^5), that is, x^(5/3), - // to be evaluated when x is negative. - // It is too complicated (and slow) to test whether y - // is a formed from a ratio of an integer to an odd integer. - // (And due to floating point inaccuracy, pointless too.) - // For example, x^1.30769230769... is - // actually x^(17/13), i.e. (x^17) ^ (1/13). - // (-5)^(17/13) gives us now -8.204227562330453. - // To see whether the result is right, we can test the given - // root: (-8.204227562330453)^13 gives us the value of (-5)^17, - // which proves that the expression was correct. - // - // The y*16 check prevents e.g. (-4)^(3/2) from being calculated, - // as it would confuse functioninfo when pow() returns no error - // but sqrt() does when the formula is converted into sqrt(x)*x. - // - // The errors in this approach are: - // (-2)^sqrt(2) should produce NaN - // or actually sqrt(2)I + 2^sqrt(2), - // produces -(2^sqrt(2)) instead. - // (Impact: Neglible) - // Thus, at worst, we're changing a NaN (or complex) - // result into a negative real number result. - } - else - { - // y is negative. Utilize the x^y = 1/(x^-y) identity. - if(x > ValueT(0)) return fp_pow_with_exp_log(ValueT(1) / x, -y); - if(x < ValueT(0)) - { - if(!IsIntegerConst(y*ValueT(-16))) - return -fp_pow_with_exp_log(ValueT(-1) / x, -y); - // ^ See comment above. - } - // Remaining case: 0.0 ^ negative number - } - // This is reached when: - // x=0 and y<0 - // x<0 and y*16 is either positive or negative integer - // It is used for producing error values and as a safe fallback. - return fp_pow_base(x, y); - } - -// ------------------------------------------------------------------------- -// double -// ------------------------------------------------------------------------- - inline double fp_abs(double x) { return fabs(x); } - inline double fp_acos(double x) { return acos(x); } - inline double fp_asin(double x) { return asin(x); } - inline double fp_atan(double x) { return atan(x); } - inline double fp_atan2(double x, double y) { return atan2(x, y); } -#ifdef FP_SUPPORT_CBRT - inline double fp_cbrt(double x) { return cbrt(x); } -#else - inline double fp_cbrt(double x) { return x>0 ? exp(log( x)/3.0) - : x<0 ? -exp(log(-x)/3.0) - : 0.0; } -#endif - inline double fp_ceil(double x) { return ceil(x); } - inline double fp_cos(double x) { return cos(x); } - inline double fp_cosh(double x) { return cosh(x); } - inline double fp_exp(double x) { return exp(x); } - inline double fp_floor(double x) { return floor(x); } - inline double fp_int(double x) { return floor(x + .5); } - inline double fp_log(double x) { return log(x); } - inline double fp_log10(double x) - { return log(x) * - 0.434294481903251827651128918916605082294397005803666566; } - inline double fp_mod(double x, double y) { return fmod(x, y); } - inline double fp_sin(double x) { return sin(x); } - inline double fp_sinh(double x) { return sinh(x); } - inline double fp_sqrt(double x) { return sqrt(x); } - inline double fp_tan(double x) { return tan(x); } - inline double fp_tanh(double x) { return tanh(x); } - -#ifndef FP_SUPPORT_ASINH - inline double fp_asinh(double x) { return log(x + sqrt(x*x + 1.0)); } - inline double fp_acosh(double x) { return log(x + sqrt(x*x - 1.0)); } - inline double fp_atanh(double x) { return log((1.0+x) / (1.0-x)) * 0.5; } -#else - inline double fp_asinh(double x) { return asinh(x); } - inline double fp_acosh(double x) { return acosh(x); } - inline double fp_atanh(double x) { return atanh(x); } -#endif // FP_SUPPORT_ASINH - - inline double fp_trunc(double x) { return x<0.0 ? ceil(x) : floor(x); } - - inline double fp_pow_base(double x, double y) { return pow(x, y); } - -#ifndef FP_SUPPORT_LOG2 - inline double fp_log2(double x) - { return log(x) * 1.4426950408889634073599246810018921374266459541529859; } -#else - inline double fp_log2(double x) { return log2(x); } -#endif // FP_SUPPORT_LOG2 - - inline double fp_exp2(double x) { return fp_pow(2.0, x); } - -#ifdef FP_EPSILON - template - inline Value_t fp_epsilon() { return FP_EPSILON; } -#else - template - inline Value_t fp_epsilon() { return 0.0; } -#endif - -#ifdef FP_EPSILON - inline bool FloatEqual(double a, double b) - { return fabs(a - b) <= fp_epsilon(); } -#else - inline bool FloatEqual(double a, double b) - { return a == b; } -#endif // FP_EPSILON - - inline bool IsIntegerConst(double a) - { return FloatEqual(a, (double)(long)a); } - - -// ------------------------------------------------------------------------- -// float -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_FLOAT_TYPE - inline float fp_abs(float x) { return fabsf(x); } - inline float fp_acos(float x) { return acosf(x); } - inline float fp_asin(float x) { return asinf(x); } - inline float fp_atan(float x) { return atanf(x); } - inline float fp_atan2(float x, float y) { return atan2f(x, y); } -#ifdef FP_SUPPORT_CBRT - inline float fp_cbrt(float x) { return cbrtf(x); } -#else - inline float fp_cbrt(float x) { return x>0 ? expf(logf( x)/3.0f) - : x<0 ? -expf(logf(-x)/3.0f) - : 0.0f; } -#endif - inline float fp_ceil(float x) { return ceilf(x); } - inline float fp_cos(float x) { return cosf(x); } - inline float fp_cosh(float x) { return coshf(x); } - inline float fp_exp(float x) { return expf(x); } - inline float fp_floor(float x) { return floorf(x); } - inline float fp_int(float x) { return floorf(x + .5F); } - inline float fp_log(float x) { return logf(x); } - inline float fp_log10(float x) - { return logf(x) * - 0.434294481903251827651128918916605082294397005803666566F; } - inline float fp_mod(float x, float y) { return fmodf(x, y); } - inline float fp_sin(float x) { return sinf(x); } - inline float fp_sinh(float x) { return sinhf(x); } - inline float fp_sqrt(float x) { return sqrtf(x); } - inline float fp_tan(float x) { return tanf(x); } - inline float fp_tanh(float x) { return tanhf(x); } - -#ifndef FP_SUPPORT_ASINH - inline float fp_asinh(float x) { return logf(x + sqrt(x*x + 1.0F)); } - inline float fp_acosh(float x) { return logf(x + sqrt(x*x - 1.0F)); } - inline float fp_atanh(float x) { return logf((1.0F+x) / (1.0F-x)) * 0.5F; } -#else - inline float fp_asinh(float x) { return asinhf(x); } - inline float fp_acosh(float x) { return acoshf(x); } - inline float fp_atanh(float x) { return atanhf(x); } -#endif // FP_SUPPORT_ASINH - - inline float fp_trunc(float x) { return x<0.0F ? ceilf(x) : floorf(x); } - - inline float fp_pow_base(float x, float y) { return powf(x, y); } - -#ifndef FP_SUPPORT_LOG2 - inline float fp_log2(float x) - { return logf(x) * - 1.4426950408889634073599246810018921374266459541529859F; } -#else - inline float fp_log2(float x) { return log2f(x); } -#endif // FP_SUPPORT_LOG2 - - inline float fp_exp2(float x) { return fp_pow(2.0F, x); } - -#ifdef FP_EPSILON - template<> - inline float fp_epsilon() { return 1e-6F; } -#else - template<> - inline float fp_epsilon() { return 0.0F; } -#endif - -#ifdef FP_EPSILON - inline bool FloatEqual(float a, float b) - { return fabsf(a - b) <= fp_epsilon(); } -#else - inline bool FloatEqual(float a, float b) - { return a == b; } -#endif // FP_EPSILON - - inline bool IsIntegerConst(float a) - { return FloatEqual(a, (float)(long)a); } -#endif // FP_SUPPORT_FLOAT_TYPE - - - -// ------------------------------------------------------------------------- -// long double -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE - inline long double fp_abs(long double x) { return fabsl(x); } - inline long double fp_acos(long double x) { return acosl(x); } - inline long double fp_asin(long double x) { return asinl(x); } - inline long double fp_atan(long double x) { return atanl(x); } - inline long double fp_atan2(long double x, long double y) - { return atan2l(x, y); } -#ifdef FP_SUPPORT_CBRT - inline long double fp_cbrt(long double x) { return cbrtl(x); } -#else - inline long double fp_cbrt(long double x) - { return x>0 ? expl(logl( x)/3.0l) - : x<0 ? -expl(logl(-x)/3.0l) - : 0.0l; } -#endif - inline long double fp_ceil(long double x) { return ceill(x); } - inline long double fp_cos(long double x) { return cosl(x); } - inline long double fp_cosh(long double x) { return coshl(x); } - inline long double fp_exp(long double x) { return expl(x); } - inline long double fp_floor(long double x) { return floorl(x); } - inline long double fp_int(long double x) { return floorl(x + .5L); } - inline long double fp_log(long double x) { return logl(x); } - inline long double fp_log10(long double x) - { return logl(x) * - 0.434294481903251827651128918916605082294397005803666566L; } - inline long double fp_mod(long double x, long double y) - { return fmodl(x, y); } - inline long double fp_sin(long double x) { return sinl(x); } - inline long double fp_sinh(long double x) { return sinhl(x); } - inline long double fp_sqrt(long double x) { return sqrtl(x); } - inline long double fp_tan(long double x) { return tanl(x); } - inline long double fp_tanh(long double x) { return tanhl(x); } - -#ifndef FP_SUPPORT_ASINH - inline long double fp_asinh(long double x) - { return logl(x + sqrtl(x*x + 1.0L)); } - inline long double fp_acosh(long double x) - { return logl(x + sqrtl(x*x - 1.0L)); } - inline long double fp_atanh(long double x) - { return logl((1.0L+x) / (1.0L-x)) * 0.5L; } -#else - inline long double fp_asinh(long double x) { return asinhl(x); } - inline long double fp_acosh(long double x) { return acoshl(x); } - inline long double fp_atanh(long double x) { return atanhl(x); } -#endif // FP_SUPPORT_ASINH - - inline long double fp_trunc(long double x) - { return x<0.0L ? ceill(x) : floorl(x); } - - inline long double fp_pow_base(long double x, long double y) - { return powl(x, y); } - -#ifndef FP_SUPPORT_LOG2 - inline long double fp_log2(long double x) - { return log(x) * 1.4426950408889634073599246810018921374266459541529859L; } -#else - inline long double fp_log2(long double x) { return log2l(x); } -#endif // FP_SUPPORT_LOG2 - - inline long double fp_exp2(long double x) { return fp_pow(2.0L, x); } - -#ifdef FP_EPSILON - inline bool FloatEqual(long double a, long double b) - { return fabsl(a - b) <= fp_epsilon(); } -#else - inline bool FloatEqual(long double a, long double b) - { return a == b; } -#endif // FP_EPSILON - - inline bool IsIntegerConst(long double a) - { return FloatEqual(a, (long double)(long)a); } -#endif // FP_SUPPORT_LONG_DOUBLE_TYPE - - -// ------------------------------------------------------------------------- -// Long int -// ------------------------------------------------------------------------- - inline long fp_abs(long x) { return x < 0 ? -x : x; } - inline long fp_acos(long) { return 0; } - inline long fp_asin(long) { return 0; } - inline long fp_atan(long) { return 0; } - inline long fp_atan2(long, long) { return 0; } - inline long fp_cbrt(long) { return 0; } - inline long fp_ceil(long x) { return x; } - inline long fp_cos(long) { return 0; } - inline long fp_cosh(long) { return 0; } - inline long fp_exp(long) { return 0; } - inline long fp_floor(long x) { return x; } - inline long fp_int(long x) { return x; } - inline long fp_log(long) { return 0; } - inline long fp_log10(long) { return 0; } - inline long fp_mod(long x, long y) { return x % y; } - inline long fp_pow(long, long) { return 0; } - inline long fp_sin(long) { return 0; } - inline long fp_sinh(long) { return 0; } - inline long fp_sqrt(long) { return 1; } - inline long fp_tan(long) { return 0; } - inline long fp_tanh(long) { return 0; } - inline long fp_asinh(long) { return 0; } - inline long fp_acosh(long) { return 0; } - inline long fp_atanh(long) { return 0; } - inline long fp_trunc(long x) { return x; } - inline long fp_pow_base(long, long) { return 0; } - inline long fp_log2(long) { return 0; } - inline long fp_exp2(long) { return 0; } - - template<> - inline long fp_epsilon() { return 0; } - - inline bool IsIntegerConst(long) { return true; } - - -// ------------------------------------------------------------------------- -// MpfrFloat -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE - inline MpfrFloat fp_abs(const MpfrFloat& x) { return MpfrFloat::abs(x); } - inline MpfrFloat fp_acos(const MpfrFloat& x) { return MpfrFloat::acos(x); } - inline MpfrFloat fp_asin(const MpfrFloat& x) { return MpfrFloat::asin(x); } - inline MpfrFloat fp_atan(const MpfrFloat& x) { return MpfrFloat::atan(x); } - inline MpfrFloat fp_atan2(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::atan2(x, y); } - inline MpfrFloat fp_cbrt(const MpfrFloat& x) { return MpfrFloat::cbrt(x); } - inline MpfrFloat fp_ceil(const MpfrFloat& x) { return MpfrFloat::ceil(x); } - inline MpfrFloat fp_cos(const MpfrFloat& x) { return MpfrFloat::cos(x); } - inline MpfrFloat fp_cosh(const MpfrFloat& x) { return MpfrFloat::cosh(x); } - inline MpfrFloat fp_exp(const MpfrFloat& x) { return MpfrFloat::exp(x); } - inline MpfrFloat fp_floor(const MpfrFloat& x) { return MpfrFloat::floor(x); } - inline MpfrFloat fp_int(const MpfrFloat& x) { return MpfrFloat::round(x); } - inline MpfrFloat fp_log(const MpfrFloat& x) { return MpfrFloat::log(x); } - inline MpfrFloat fp_log10(const MpfrFloat& x) { return MpfrFloat::log10(x); } - inline MpfrFloat fp_mod(const MpfrFloat& x, const MpfrFloat& y) { return x % y; } - inline MpfrFloat fp_sin(const MpfrFloat& x) { return MpfrFloat::sin(x); } - inline MpfrFloat fp_sinh(const MpfrFloat& x) { return MpfrFloat::sinh(x); } - inline MpfrFloat fp_sqrt(const MpfrFloat& x) { return MpfrFloat::sqrt(x); } - inline MpfrFloat fp_tan(const MpfrFloat& x) { return MpfrFloat::tan(x); } - inline MpfrFloat fp_tanh(const MpfrFloat& x) { return MpfrFloat::tanh(x); } - inline MpfrFloat fp_asinh(const MpfrFloat& x) { return MpfrFloat::asinh(x); } - inline MpfrFloat fp_acosh(const MpfrFloat& x) { return MpfrFloat::acosh(x); } - inline MpfrFloat fp_atanh(const MpfrFloat& x) { return MpfrFloat::atanh(x); } - inline MpfrFloat fp_trunc(const MpfrFloat& x) { return MpfrFloat::trunc(x); } - - inline MpfrFloat fp_pow(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); } - inline MpfrFloat fp_pow_base(const MpfrFloat& x, const MpfrFloat& y) { return MpfrFloat::pow(x, y); } - - inline MpfrFloat fp_log2(const MpfrFloat& x) { return MpfrFloat::log2(x); } - inline MpfrFloat fp_exp2(const MpfrFloat& x) { return MpfrFloat::exp2(x); } - - inline bool IsIntegerConst(const MpfrFloat& a) { return a.isInteger(); } - - template<> - inline MpfrFloat fp_epsilon() { return MpfrFloat::someEpsilon(); } -#endif // FP_SUPPORT_MPFR_FLOAT_TYPE - - -// ------------------------------------------------------------------------- -// GMP int -// ------------------------------------------------------------------------- -#ifdef FP_SUPPORT_GMP_INT_TYPE - inline GmpInt fp_abs(GmpInt x) { return GmpInt::abs(x); } - inline GmpInt fp_acos(GmpInt) { return 0; } - inline GmpInt fp_asin(GmpInt) { return 0; } - inline GmpInt fp_atan(GmpInt) { return 0; } - inline GmpInt fp_atan2(GmpInt, GmpInt) { return 0; } - inline GmpInt fp_cbrt(GmpInt) { return 0; } - inline GmpInt fp_ceil(GmpInt x) { return x; } - inline GmpInt fp_cos(GmpInt) { return 0; } - inline GmpInt fp_cosh(GmpInt) { return 0; } - inline GmpInt fp_exp(GmpInt) { return 0; } - inline GmpInt fp_floor(GmpInt x) { return x; } - inline GmpInt fp_int(GmpInt x) { return x; } - inline GmpInt fp_log(GmpInt) { return 0; } - inline GmpInt fp_log10(GmpInt) { return 0; } - inline GmpInt fp_mod(GmpInt x, GmpInt y) { return x % y; } - inline GmpInt fp_pow(GmpInt, GmpInt) { return 0; } - inline GmpInt fp_sin(GmpInt) { return 0; } - inline GmpInt fp_sinh(GmpInt) { return 0; } - inline GmpInt fp_sqrt(GmpInt) { return 0; } - inline GmpInt fp_tan(GmpInt) { return 0; } - inline GmpInt fp_tanh(GmpInt) { return 0; } - inline GmpInt fp_asinh(GmpInt) { return 0; } - inline GmpInt fp_acosh(GmpInt) { return 0; } - inline GmpInt fp_atanh(GmpInt) { return 0; } - inline GmpInt fp_trunc(GmpInt x) { return x; } - inline GmpInt fp_pow_base(GmpInt, GmpInt) { return 0; } - inline GmpInt fp_log2(GmpInt) { return 0; } - inline GmpInt fp_exp2(GmpInt) { return 0; } - - template<> - inline GmpInt fp_epsilon() { return 0; } - - inline bool IsIntegerConst(GmpInt) { return true; } -#endif // FP_SUPPORT_GMP_INT_TYPE - - - -// ------------------------------------------------------------------------- -// Comparison -// ------------------------------------------------------------------------- -#ifdef FP_EPSILON - template - inline bool fp_equal(Value_t x, Value_t y) - { return fp_abs(x - y) <= fp_epsilon(); } - - template - inline bool fp_nequal(Value_t x, Value_t y) - { return fp_abs(x - y) > fp_epsilon(); } - - template - inline bool fp_less(Value_t x, Value_t y) - { return x < y - fp_epsilon(); } - - template - inline bool fp_lessOrEq(Value_t x, Value_t y) - { return x <= y + fp_epsilon(); } -#else // FP_EPSILON - template - inline bool fp_equal(Value_t x, Value_t y) { return x == y; } - - template - inline bool fp_nequal(Value_t x, Value_t y) { return x != y; } - - template - inline bool fp_less(Value_t x, Value_t y) { return x < y; } - - template - inline bool fp_lessOrEq(Value_t x, Value_t y) { return x <= y; } -#endif // FP_EPSILON - - template<> - inline bool fp_equal(long x, long y) { return x == y; } - - template<> - inline bool fp_nequal(long x, long y) { return x != y; } - - template<> - inline bool fp_less(long x, long y) { return x < y; } - - template<> - inline bool fp_lessOrEq(long x, long y) { return x <= y; } - -#ifdef FP_SUPPORT_GMP_INT_TYPE - template<> - inline bool fp_equal(GmpInt x, GmpInt y) { return x == y; } - - template<> - inline bool fp_nequal(GmpInt x, GmpInt y) { return x != y; } - - template<> - inline bool fp_less(GmpInt x, GmpInt y) { return x < y; } - - template<> - inline bool fp_lessOrEq(GmpInt x, GmpInt y) { return x <= y; } -#endif -} // namespace FUNCTIONPARSERTYPES - -#endif // ONCE_FPARSER_H_ - - -#ifndef FP_DISABLE_DOUBLE_TYPE -#define FUNCTIONPARSER_INSTANTIATE_DOUBLE \ - template class FunctionParserBase; -#else -#define FUNCTIONPARSER_INSTANTIATE_DOUBLE -#endif - -#ifdef FP_SUPPORT_FLOAT_TYPE -#define FUNCTIONPARSER_INSTANTIATE_FLOAT \ - template class FunctionParserBase; -#else -#define FUNCTIONPARSER_INSTANTIATE_FLOAT -#endif - -#ifdef FP_SUPPORT_LONG_DOUBLE_TYPE -#define FUNCTIONPARSER_INSTANTIATE_LONG_DOUBLE \ - template class FunctionParserBase; -#else -#define FUNCTIONPARSER_INSTANTIATE_LONG_DOUBLE -#endif - -#ifdef FP_SUPPORT_LONG_INT_TYPE -#define FUNCTIONPARSER_INSTANTIATE_LONG_INT \ - template class FunctionParserBase; -#else -#define FUNCTIONPARSER_INSTANTIATE_LONG_INT -#endif - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -#define FUNCTIONPARSER_INSTANTIATE_MPFR_FLOAT \ - template class FunctionParserBase; -#else -#define FUNCTIONPARSER_INSTANTIATE_MPFR_FLOAT -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -#define FUNCTIONPARSER_INSTANTIATE_GMP_INT \ - template class FunctionParserBase; -#else -#define FUNCTIONPARSER_INSTANTIATE_GMP_INT -#endif - -/* Add 'FUNCTIONPARSER_INSTANTIATE_TYPES' at the end of all .cc files - containing FunctionParserBase implementations. - */ -#define FUNCTIONPARSER_INSTANTIATE_TYPES \ - FUNCTIONPARSER_INSTANTIATE_DOUBLE \ - FUNCTIONPARSER_INSTANTIATE_FLOAT \ - FUNCTIONPARSER_INSTANTIATE_LONG_DOUBLE \ - FUNCTIONPARSER_INSTANTIATE_LONG_INT \ - FUNCTIONPARSER_INSTANTIATE_MPFR_FLOAT \ - FUNCTIONPARSER_INSTANTIATE_GMP_INT - -#endif // ONCE_FPARSER_AUX_H_ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpconfig.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpconfig.h deleted file mode 100644 index 4c90de4dfc..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpconfig.h +++ /dev/null @@ -1,139 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.0.3 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen *| -\***************************************************************************/ - -// Configuration file -// ------------------ - -/* NOTE: - This file is for the internal use of the function parser only. - You don't need to include this file in your source files, just - include "fparser.hh". -*/ - - -/* Uncomment any of these lines or define them in your compiler settings - to enable the correspondent version of the parser. (These are disabled - by default because they rely on C99 functions, and non-standard libraries - in the case pf MPFR and GMP, and they make compiling needlessly slower - and the resulting binary needlessly larger if they are not used in the - program.) -*/ -//#define FP_SUPPORT_FLOAT_TYPE -#define FP_SUPPORT_LONG_DOUBLE_TYPE -//#define FP_SUPPORT_LONG_INT_TYPE -//#define FP_SUPPORT_MPFR_FLOAT_TYPE -//#define FP_SUPPORT_GMP_INT_TYPE - -/* Uncomment this line of define it in your compiler settings if you want - to disable compiling the basic double version of the library, in case - one of the above types is used but not the double type. (If the double - type is not used, then disabling it makes compiling faster and the - resulting binary smaller.) - */ -//#define FP_DISABLE_DOUBLE_TYPE - -/* - Note that these do not change what FunctionParser supports, they only - change how the function is evaluated, potentially making it faster when - these functions are involved. - These will make the source code use asinh(), acosh(), atanh(), exp2() - and log2(). -*/ -//#define FP_SUPPORT_TR1_MATH_FUNCS - -#ifdef FP_SUPPORT_TR1_MATH_FUNCS -#define FP_SUPPORT_ASINH -#define FP_SUPPORT_EXP2 -#define FP_SUPPORT_LOG2 -#define FP_SUPPORT_CBRT -#endif - -/* - Comment out the following line to enable the eval() function, which can - be used in the function string to recursively call the same function. - Note that enabling this function may be dangerous even if the maximum - recursion level is limited because it is still possible to write functions - using it which take enormous amounts of time to evaluate even though the - maximum recursion is never reached. This may be undesirable in some - applications. - Alternatively you can define the FP_ENABLE_EVAL precompiler constant in - your compiler settings. -*/ -#ifndef FP_ENABLE_EVAL -#define FP_DISABLE_EVAL -#endif - - -/* - Maximum recursion level for eval() calls: -*/ -#define FP_EVAL_MAX_REC_LEVEL 1000 - - -/* - Whether to use shortcut evaluation for the & and | operators: -*/ -#define FP_DISABLE_SHORTCUT_LOGICAL_EVALUATION -#ifndef FP_DISABLE_SHORTCUT_LOGICAL_EVALUATION -#define FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION -#endif - -/* - Whether to enable optimizations that may ignore side effects - of if() calls, such as changing if(x,!y,0) into x&!y. - This is basically the polar opposite of "shortcut logical evaluation". - Disabled by default, because it makes eval() rather unsafe. -*/ -#ifdef FP_ENABLE_IGNORE_IF_SIDEEFFECTS -#endif - -/* - Comment out the following lines out if you are not going to use the - optimizer and want a slightly smaller library. The Optimize() method - can still be called, but it will not do anything. - If you are unsure, just leave it. It won't slow down the other parts of - the library. -*/ -//#define FP_NO_SUPPORT_OPTIMIZER -#ifndef FP_NO_SUPPORT_OPTIMIZER -#define FP_SUPPORT_OPTIMIZER -#endif - - -/* - Epsilon value used with the comparison operators (must be non-negative): - (Comment it out if you don't want to use epsilon in comparisons. Might - lead to marginally faster evaluation of the comparison operators, but - can introduce inaccuracies in comparisons.) -*/ -#define FP_EPSILON 1e-14 - - -/* - No member function of FunctionParser is thread-safe. Most prominently, - Eval() is not thread-safe. By uncommenting one of these lines the Eval() - function can be made thread-safe at the cost of a possible small overhead. - The second version requires that the compiler supports the alloca() function, - which is not standard, but is faster. - */ -//#define FP_USE_THREAD_SAFE_EVAL -//#define FP_USE_THREAD_SAFE_EVAL_WITH_ALLOCA - -/* - Uncomment (or define in your compiler options) to disable evaluation checks. - (Consult the documentation for details.) - */ -#define FP_NO_EVALUATION_CHECKS - - - -// Temporary settings while double is the only supported type by the optimizer -#ifdef FP_DISABLE_DOUBLE_TYPE -#ifndef FP_NO_SUPPORT_OPTIMIZER -#define FP_NO_SUPPORT_OPTIMIZER -#endif -#undef FP_SUPPORT_OPTIMIZER -#endif diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpoptimizer.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpoptimizer.cpp deleted file mode 100644 index 9fda0c12d9..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fpoptimizer.cpp +++ /dev/null @@ -1,10948 +0,0 @@ -#line 1 "fpoptimizer/fpoptimizer_header.txt" -/***************************************************************************\ -|* Function Parser for C++ v4.0.3 *| -|*-------------------------------------------------------------------------*| -|* Function optimizer *| -|*-------------------------------------------------------------------------*| -|* Copyright: Joel Yliluoma *| -\***************************************************************************/ - -/* NOTE: - This is a concatenation of all the header and source files of the - original optimizer source code. All the code has been concatenated - into this single file for convenience of usage (in other words, to - simply use the optimizer, it's enough to add this file to the project - rather than a multitude of files which the original optimizer source - code is composed of). - - Thus this file exists for the usage of the Function parser library - only, and is not suitable for developing it further. If you want to - develop the library further, you should download the development - version of the library, which has all the original source files. - */ - -#include "fpconfig.h" -#ifdef FP_SUPPORT_OPTIMIZER - -#define FPOPTIMIZER_MERGED_FILE - -#line 1 "fpoptimizer/fpoptimizer_hash.h" -#ifndef FPoptimizerHashH -#define FPoptimizerHashH - -#ifdef _MSC_VER - -typedef unsigned long long fphash_value_t; -#define FPHASH_CONST(x) x##ULL - -#else - -#include -typedef uint_fast64_t fphash_value_t; -#define FPHASH_CONST(x) x##ULL - -#endif - -namespace FUNCTIONPARSERTYPES -{ - struct fphash_t - { - fphash_value_t hash1, hash2; - - bool operator==(const fphash_t& rhs) const - { return hash1 == rhs.hash1 && hash2 == rhs.hash2; } - - bool operator!=(const fphash_t& rhs) const - { return hash1 != rhs.hash1 || hash2 != rhs.hash2; } - - bool operator<(const fphash_t& rhs) const - { return hash1 != rhs.hash1 ? hash1 < rhs.hash1 : hash2 < rhs.hash2; } - }; -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_autoptr.h" -#ifndef FPOptimizerAutoPtrH -#define FPOptimizerAutoPtrH - -template -class FPOPT_autoptr -{ -public: - FPOPT_autoptr() : p(0) { } - FPOPT_autoptr(Ref* b) : p(b) { Birth(); } - FPOPT_autoptr(const FPOPT_autoptr& b) : p(b.p) { Birth(); } - - inline Ref& operator* () const { return *p; } - inline Ref* operator->() const { return p; } - - FPOPT_autoptr& operator= (Ref* b) { Set(b); return *this; } - FPOPT_autoptr& operator= (const FPOPT_autoptr& b) { Set(b.p); return *this; } -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - FPOPT_autoptr(FPOPT_autoptr&& b) : p(b.p) { b.p = 0; } - FPOPT_autoptr& operator= (FPOPT_autoptr&& b) { if(p != b.p) { Forget(); p=b.p; b.p=0; } - return *this; } -#endif - - ~FPOPT_autoptr() { Forget(); } - - void UnsafeSetP(Ref* newp) { p = newp; } - void swap(FPOPT_autoptr& b) { Ref* tmp=p; p=b.p; b.p=tmp; } - -private: - inline static void Have(Ref* p2); - inline void Forget(); - inline void Birth(); - inline void Set(Ref* p2); -private: - Ref* p; -}; - -// -template -inline void FPOPT_autoptr::Forget() -{ - if(!p) return; - p->RefCount -= 1; - if(!p->RefCount) delete p; - //assert(p->RefCount >= 0); -} -template -inline void FPOPT_autoptr::Have(Ref* p2) -{ - if(p2) ++(p2->RefCount); -} -template -inline void FPOPT_autoptr::Birth() -{ - Have(p); -} -template -inline void FPOPT_autoptr::Set(Ref* p2) -{ - Have(p2); - Forget(); - p = p2; -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_codetree.h" -#ifndef FPOptimizer_CodeTreeH -#define FPOptimizer_CodeTreeH - -#include "fpconfig.h" -#include "fparser.h" -#include "fptypes.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -#include -#include - -// line removed for fpoptimizer.c: #include "fpoptimizer_hash.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_autoptr.h" - -#ifdef FP_EPSILON - #define NEGATIVE_MAXIMUM (-FP_EPSILON) -#else - #define NEGATIVE_MAXIMUM (-1e-14) -#endif - -namespace FPoptimizer_Grammar -{ - struct Grammar; -} - -namespace FPoptimizer_ByteCode -{ - class ByteCodeSynth; -} - -namespace FPoptimizer_CodeTree -{ - class CodeTree; - - struct MinMaxTree - { - double min,max; - bool has_min, has_max; - MinMaxTree() : min(),max(),has_min(false),has_max(false) { } - MinMaxTree(double mi,double ma): min(mi),max(ma),has_min(true),has_max(true) { } - MinMaxTree(bool,double ma): min(),max(ma),has_min(false),has_max(true) { } - MinMaxTree(double mi,bool): min(mi),max(),has_min(true),has_max(false) { } - }; - - struct CodeTreeData; - class CodeTree - { - typedef FPOPT_autoptr DataP; - DataP data; - - public: - public: - CodeTree(); - ~CodeTree(); - - explicit CodeTree(double v); // produce an immed - struct VarTag { }; - explicit CodeTree(unsigned varno, VarTag); // produce a var reference - struct CloneTag { }; - explicit CodeTree(const CodeTree& b, CloneTag); - - /* Generates a CodeTree from the given bytecode */ - void GenerateFrom( - const std::vector& byteCode, - const std::vector& immed, - const FunctionParser::Data& data, - bool keep_powi = false); - - void GenerateFrom( - const std::vector& byteCode, - const std::vector& immed, - const FunctionParser::Data& data, - const std::vector& var_trees, - bool keep_powi = false); - - void SynthesizeByteCode( - std::vector& byteCode, - std::vector& immed, - size_t& stacktop_max); - - void SynthesizeByteCode( - FPoptimizer_ByteCode::ByteCodeSynth& synth, - bool MustPopTemps=true) const; - - size_t SynthCommonSubExpressions( - FPoptimizer_ByteCode::ByteCodeSynth& synth) const; - - void SetParams(const std::vector& RefParams); - void SetParamsMove(std::vector& RefParams); - - CodeTree GetUniqueRef(); - // ^use this when CodeTree tmp=x; tmp.CopyOnWrite(); does not do exactly what you want - -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - void SetParams(std::vector&& RefParams); -#endif - void SetParam(size_t which, const CodeTree& b); - void SetParamMove(size_t which, CodeTree& b); - void AddParam(const CodeTree& param); - void AddParamMove(CodeTree& param); - void AddParams(const std::vector& RefParams); - void AddParamsMove(std::vector& RefParams); - void AddParamsMove(std::vector& RefParams, size_t replacing_slot); - void DelParam(size_t index); - void DelParams(); - - void Become(const CodeTree& b); - - inline size_t GetParamCount() const { return GetParams().size(); } - inline CodeTree& GetParam(size_t n) { return GetParams()[n]; } - inline const CodeTree& GetParam(size_t n) const { return GetParams()[n]; } - inline void SetOpcode(FUNCTIONPARSERTYPES::OPCODE o); - inline void SetFuncOpcode(FUNCTIONPARSERTYPES::OPCODE o, unsigned f); - inline void SetVar(unsigned v); - inline void SetImmed(double v); - inline FUNCTIONPARSERTYPES::OPCODE GetOpcode() const; - inline FUNCTIONPARSERTYPES::fphash_t GetHash() const; - inline const std::vector& GetParams() const; - inline std::vector& GetParams(); - inline size_t GetDepth() const; - inline const double& GetImmed() const; - inline unsigned GetVar() const; - inline unsigned GetFuncNo() const; - inline bool IsDefined() const { return GetOpcode() != FUNCTIONPARSERTYPES::cNop; } - - inline bool IsImmed() const { return GetOpcode() == FUNCTIONPARSERTYPES::cImmed; } - inline bool IsVar() const { return GetOpcode() == FUNCTIONPARSERTYPES::VarBegin; } - bool IsLongIntegerImmed() const { return IsImmed() && GetImmed() == (double)GetLongIntegerImmed(); } - long GetLongIntegerImmed() const { return (long)GetImmed(); } - bool IsLogicalValue() const; - inline unsigned GetRefCount() const; - /* This function calculates the minimum and maximum values - * of the tree's result. If an estimate cannot be made, - * has_min/has_max are indicated as false. - */ - MinMaxTree CalculateResultBoundaries_do() const; - MinMaxTree CalculateResultBoundaries() const; - - enum TriTruthValue { IsAlways, IsNever, Unknown }; - TriTruthValue GetEvennessInfo() const; - - bool IsAlwaysSigned(bool positive) const; - bool IsAlwaysParity(bool odd) const - { return GetEvennessInfo() == (odd?IsNever:IsAlways); } - bool IsAlwaysInteger(bool integer) const; - - void ConstantFolding(); - bool ConstantFolding_AndLogic(); - bool ConstantFolding_OrLogic(); - bool ConstantFolding_MulLogicItems(); - bool ConstantFolding_AddLogicItems(); - bool ConstantFolding_IfOperations(); - bool ConstantFolding_PowOperations(); - bool ConstantFolding_ComparisonOperations(); - template - bool ConstantFolding_LogicCommon(CondType cond_type, bool is_logical); - bool ConstantFolding_MulGrouping(); - bool ConstantFolding_AddGrouping(); - bool ConstantFolding_Assimilate(); - - void Rehash(bool constantfolding = true); - inline void Mark_Incompletely_Hashed(); - inline bool Is_Incompletely_Hashed() const; - - inline const FPoptimizer_Grammar::Grammar* GetOptimizedUsing() const; - inline void SetOptimizedUsing(const FPoptimizer_Grammar::Grammar* g); - - bool RecreateInversionsAndNegations(bool prefer_base2 = false); - void FixIncompleteHashes(); - - void swap(CodeTree& b) { data.swap(b.data); } - bool IsIdenticalTo(const CodeTree& b) const; - void CopyOnWrite(); - }; - - struct CodeTreeData - { - int RefCount; - - /* Describing the codetree node */ - FUNCTIONPARSERTYPES::OPCODE Opcode; - union - { - double Value; // In case of cImmed: value of the immed - unsigned Var; // In case of VarBegin: variable number - unsigned Funcno; // In case of cFCall or cPCall - }; - - // Parameters for the function - // These use the sign: - // For cAdd: operands to add together (0 to n) - // sign indicates that the value is negated before adding (0-x) - // For cMul: operands to multiply together (0 to n) - // sign indicates that the value is inverted before multiplying (1/x) - // For cAnd: operands to bitwise-and together (0 to n) - // sign indicates that the value is inverted before anding (!x) - // For cOr: operands to bitwise-or together (0 to n) - // sign indicates that the value is inverted before orring (!x) - // These don't use the sign (sign is always false): - // For cMin: operands to select the minimum of - // For cMax: operands to select the maximum of - // For cImmed, not used - // For VarBegin, not used - // For cIf: operand 1 = condition, operand 2 = yes-branch, operand 3 = no-branch - // For anything else: the parameters required by the operation/function - std::vector Params; - - /* Internal operation */ - FUNCTIONPARSERTYPES::fphash_t Hash; - size_t Depth; - const FPoptimizer_Grammar::Grammar* OptimizedUsing; - - CodeTreeData(); - CodeTreeData(const CodeTreeData& b); - explicit CodeTreeData(double i); -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - CodeTreeData(CodeTreeData&& b); -#endif - - bool IsIdenticalTo(const CodeTreeData& b) const; - void Sort(); - void Recalculate_Hash_NoRecursion(); - }; - - inline void CodeTree::SetOpcode(FUNCTIONPARSERTYPES::OPCODE o) - { data->Opcode = o; } - inline void CodeTree::SetFuncOpcode(FUNCTIONPARSERTYPES::OPCODE o, unsigned f) - { SetOpcode(o); data->Funcno = f; } - inline void CodeTree::SetVar(unsigned v) - { SetOpcode(FUNCTIONPARSERTYPES::VarBegin); data->Var = v; } - inline void CodeTree::SetImmed(double v) - { SetOpcode(FUNCTIONPARSERTYPES::cImmed); data->Value = v; } - inline FUNCTIONPARSERTYPES::OPCODE CodeTree::GetOpcode() const { return data->Opcode; } - inline FUNCTIONPARSERTYPES::fphash_t CodeTree::GetHash() const { return data->Hash; } - inline const std::vector& CodeTree::GetParams() const { return data->Params; } - inline std::vector& CodeTree::GetParams() { return data->Params; } - inline size_t CodeTree::GetDepth() const { return data->Depth; } - inline const double& CodeTree::GetImmed() const { return data->Value; } - inline unsigned CodeTree::GetVar() const { return data->Var; } - inline unsigned CodeTree::GetFuncNo() const { return data->Funcno; } - - inline const FPoptimizer_Grammar::Grammar* CodeTree::GetOptimizedUsing() const - { return data->OptimizedUsing; } - inline void CodeTree::SetOptimizedUsing(const FPoptimizer_Grammar::Grammar* g) - { data->OptimizedUsing = g; } - inline unsigned CodeTree::GetRefCount() const { return data->RefCount; } - - inline void CodeTree::Mark_Incompletely_Hashed() { data->Depth = 0; } - inline bool CodeTree::Is_Incompletely_Hashed() const { return data->Depth == 0; } - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT - void DumpHashes(const FPoptimizer_CodeTree::CodeTree& tree, std::ostream& o = std::cout); - void DumpTree(const FPoptimizer_CodeTree::CodeTree& tree, std::ostream& o = std::cout); - void DumpTreeWithIndent(const FPoptimizer_CodeTree::CodeTree& tree, std::ostream& o = std::cout, const std::string& indent = "\\"); -#endif -} - -#endif - -#endif - -#line 1 "fpoptimizer/fpoptimizer_grammar.h" -#ifndef FPOPT_NAN_CONST - -#include - -#include "fpconfig.h" -#include "fparser.h" -#include "fptypes.h" - -#define FPOPT_NAN_CONST (-1712345.25) /* Would use 0.0 / 0.0 here, but some compilers don't accept it. */ - -namespace FPoptimizer_CodeTree -{ - class CodeTree; -} - -namespace FPoptimizer_Grammar -{ - enum ImmedConstraint_Value - { - ValueMask = 0x07, - Value_AnyNum = 0x0, // any value - Value_EvenInt = 0x1, // any even integer (0,2,4, etc) - Value_OddInt = 0x2, // any odd integer (1,3, etc) - Value_IsInteger = 0x3, // any integer-value (excludes e.g. 0.2) - Value_NonInteger = 0x4, // any non-integer (excludes e.g. 1 or 5) - Value_Logical = 0x5 // a result of cNot,cNotNot,cAnd,cOr or comparators - }; - enum ImmedConstraint_Sign - { - SignMask = 0x18, - Sign_AnySign = 0x00, // - or + - Sign_Positive = 0x08, // positive only - Sign_Negative = 0x10, // negative only - Sign_NoIdea = 0x18 // where sign cannot be guessed - }; - enum ImmedConstraint_Oneness - { - OnenessMask = 0x60, - Oneness_Any = 0x00, - Oneness_One = 0x20, // +1 or -1 - Oneness_NotOne = 0x40 // anything but +1 or -1 - }; - enum ImmedConstraint_Constness - { - ConstnessMask = 0x80, - Constness_Any = 0x00, - Constness_Const = 0x80 - }; - - /* The param_opcode field of the ParamSpec has the following - * possible values (from enum SpecialOpcode): - * NumConstant: - * this describes a specific constant value (constvalue) - * that must be matched / synthesized. - * ParamHolder: - * this describes any node - * that must be matched / synthesized. - * "index" is the ID of the NamedHolder: - * In matching, all NamedHolders having the same ID - * must match the identical node. - * In synthesizing, the node matched by - * a NamedHolder with this ID must be synthesized. - * SubFunction: - * this describes a subtree - * that must be matched / synthesized. - * The subtree is described in subfunc_opcode,param_begin..+param_count. - * If the type is GroupFunction, the tree is expected - * to yield a constant value which is tested. - */ - enum SpecialOpcode - { - NumConstant, // Holds a particular value (syntax-time constant) - ParamHolder, // Holds a particular named param - SubFunction // Holds an opcode and the params - }; - - enum ParamMatchingType - { - PositionalParams, // this set of params in this order - SelectedParams, // this set of params in any order - AnyParams, // these params are included - GroupFunction // this function represents a constant value - }; - - enum RuleType - { - ProduceNewTree, // replace self with the first (and only) from replaced_param - ReplaceParams // replace indicate params with replaced_params - }; - -#ifdef __GNUC__ -# define PACKED_GRAMMAR_ATTRIBUTE __attribute__((packed)) -#else -# define PACKED_GRAMMAR_ATTRIBUTE -#endif - - enum { PARAM_INDEX_BITS = 9 }; - - /* A ParamSpec object describes - * either a parameter (leaf, node) that must be matched, - * or a parameter (leaf, node) that must be synthesized. - */ - typedef std::pair ParamSpec; - ParamSpec ParamSpec_Extract(unsigned paramlist, unsigned index); - bool ParamSpec_Compare(const void* a, const void* b, SpecialOpcode type); - unsigned ParamSpec_GetDepCode(const ParamSpec& b); - - struct ParamSpec_ParamHolder - { - unsigned index : 8; // holder ID - unsigned constraints : 8; // constraints - unsigned depcode :16; - } PACKED_GRAMMAR_ATTRIBUTE; - - struct ParamSpec_NumConstant - { - double constvalue; // the value - } PACKED_GRAMMAR_ATTRIBUTE; - - struct ParamSpec_SubFunctionData - { - /* Expected parameters (leaves) of the tree: */ - unsigned param_count : 2; - unsigned param_list : 30; - /* The opcode that the tree must have when SubFunction */ - FUNCTIONPARSERTYPES::OPCODE subfunc_opcode : 8; - - /* When matching, type describes the method of matching. - * - * Sample input tree: (cOr 2 3) (cOr 2 4) (cOr 3 2) (cOr 4 2 3) (cOr 2) - * Possible methods: - * PositionalParams, e.g. (cOr [2 3]): match no match no match no match no match - * The nodes described here are - * to be matched, in this order. - * SelectedParams, e.g. (cOr {2 3}): match no match match no match no match - * The nodes described here are - * to be matched, in any order. - * AnyParams, e.g. (cOr 2 3 ): match no match match match no match - * At least the nodes described here - * are to be matched, in any order. - * When synthesizing, the type is ignored. - */ - ParamMatchingType match_type : 3; /* When SubFunction */ - /* Note: match_type needs 2, but we specify 3 because - * otherwise Microsoft VC++ borks things up - * as it interprets the value as signed. - */ - /* Optional restholder index for capturing the rest of parameters (0=not used) - * Only valid when match_type = AnyParams - */ - unsigned restholder_index : 5; - } PACKED_GRAMMAR_ATTRIBUTE; // size: 2+30+6+2+8=48 bits=6 bytes - - struct ParamSpec_SubFunction - { - ParamSpec_SubFunctionData data; - unsigned constraints : 8; // constraints - unsigned depcode : 8; - } PACKED_GRAMMAR_ATTRIBUTE; // 8 bytes - - /* Theoretical minimal sizes in each param_opcode cases: - * Assume param_opcode needs 3 bits. - * NumConstant: 3 + 64 (or 3+4 if just use index to clist[]) - * ParamHolder: 3 + 7 + 2 (7 for constraints, 2 for immed index) - * SubFunction: 3 + 7 + 2 + 2 + 3*9 = 41 - */ - - /* A rule describes a pattern for matching - * and the method how to reconstruct the - * matched node(s) in the tree. - */ - struct Rule - { - /* If the rule matched, this field describes how to perform - * the replacement. - * When type==ProduceNewTree, - * the source tree is replaced entirely with - * the new tree described at repl_param_begin[0]. - * When type==ReplaceParams, - * the matching leaves in the source tree are removed - * and new leaves are constructedfrom the trees - * described at repl_param_begin[0..repl_param_count]. - * Other leaves remain intact. - */ - RuleType ruletype : 2; - bool logical_context : 1; - - /* The replacement parameters (if NewTree, begin[0] represents the new tree) */ - unsigned repl_param_count : 2; /* Assumed to be 1 when type == ProduceNewTree */ - unsigned repl_param_list : 27; - - /* The function that we must match. Always a SubFunction. */ - ParamSpec_SubFunctionData match_tree; - } PACKED_GRAMMAR_ATTRIBUTE; // size: 2+1+2+27 + 48 = 80 bits = 10 bytes - - /* Grammar is a set of rules for tree substitutions. */ - struct Grammar - { - /* The rules of this grammar */ - unsigned rule_count; - unsigned char rule_list[999]; // maximum limit... - /* Note: Changing the limit has no effect to performance of - * fparser. The limit is only actually used within grammar_parser. - * A too low limit causes a memory corruption during the parse. - * A too high limit just may cause inconvenience. - * The actual grammar items linked to fparser are optimized for size, - * and the size of the Grammar object may be considerably smaller - * than what is indicated by this prototype. - */ - }; - - extern "C" { - extern const Rule grammar_rules[]; - #ifndef FPOPTIMIZER_MERGED_FILE - extern const Grammar grammar_optimize_round1; - extern const Grammar grammar_optimize_round2; - extern const Grammar grammar_optimize_round3; - extern const Grammar grammar_optimize_round4; - extern const Grammar grammar_optimize_shortcut_logical_evaluation; - extern const Grammar grammar_optimize_nonshortcut_logical_evaluation; - extern const Grammar grammar_optimize_ignore_if_sideeffects; - extern const Grammar grammar_optimize_abslogical; - extern const Grammar grammar_optimize_base2_expand; - #endif - } - - void DumpParam(const ParamSpec& p, std::ostream& o = std::cout); - void DumpParams(unsigned paramlist, unsigned count, std::ostream& o = std::cout); -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_consts.h" -#ifndef M_PI -#define M_PI 3.1415926535897932384626433832795 -#endif - -#define CONSTANT_E 2.71828182845904523536 // exp(1) -#define CONSTANT_EI 0.3678794411714423215955 // exp(-1) -#define CONSTANT_2E 7.3890560989306502272304 // exp(2) -#define CONSTANT_2EI 0.135335283236612691894 // exp(-2) -#define CONSTANT_PI M_PI // atan2(0,-1) -#define CONSTANT_L10 2.30258509299404590109 // log(10) -#define CONSTANT_L2 0.69314718055994530943 // log(2) -#define CONSTANT_L10I 0.43429448190325176116 // 1/log(10) -#define CONSTANT_L2I 1.4426950408889634074 // 1/log(2) -#define CONSTANT_L10E CONSTANT_L10I // log10(e) -#define CONSTANT_L10EI CONSTANT_L10 // 1/log10(e) -#define CONSTANT_L10B 0.3010299956639811952137 // log10(2) -#define CONSTANT_L10BI 3.3219280948873623478703 // 1/log10(2) -#define CONSTANT_LB10 CONSTANT_L10BI // log2(10) -#define CONSTANT_LB10I CONSTANT_L10B // 1/log2(10) -#define CONSTANT_L2E CONSTANT_L2I // log2(e) -#define CONSTANT_L2EI CONSTANT_L2 // 1/log2(e) -#define CONSTANT_DR (180.0 / M_PI) // 180/pi -#define CONSTANT_RD (M_PI / 180.0) // pi/180 - -#define CONSTANT_POS_INF HUGE_VAL // positive infinity, from math.h -#define CONSTANT_NEG_INF (-HUGE_VAL) // negative infinity -#define CONSTANT_PIHALF (M_PI / 2) - -#line 1 "fpoptimizer/fpoptimizer_optimize.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_grammar.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -#include -#include -#include - -//#define DEBUG_SUBSTITUTIONS - -namespace FPoptimizer_Optimize -{ - using namespace FPoptimizer_Grammar; - using namespace FPoptimizer_CodeTree; - using namespace FUNCTIONPARSERTYPES; - - /* This struct collects information regarding the matching process so far */ - class MatchInfo - { - public: - std::vector - > > restholder_matches; - std::vector paramholder_matches; - std::vector matched_params; - public: - /* These functions save data from matching */ - bool SaveOrTestRestHolder( - unsigned restholder_index, - const std::vector& treelist) - { - if(restholder_matches.size() <= restholder_index) - { - restholder_matches.resize(restholder_index+1); - restholder_matches[restholder_index].first = true; - restholder_matches[restholder_index].second = treelist; - return true; - } - if(restholder_matches[restholder_index].first == false) - { - restholder_matches[restholder_index].first = true; - restholder_matches[restholder_index].second = treelist; - return true; - } - const std::vector& found = - restholder_matches[restholder_index].second; - if(treelist.size() != found.size()) - return false; - for(size_t a=0; a& treelist) - { - if(restholder_matches.size() <= restholder_index) - restholder_matches.resize(restholder_index+1); - restholder_matches[restholder_index].first = true; - restholder_matches[restholder_index].second.swap(treelist); - } - - bool SaveOrTestParamHolder( - unsigned paramholder_index, - const CodeTree& treeptr) - { - if(paramholder_matches.size() <= paramholder_index) - { - paramholder_matches.reserve(paramholder_index+1); - paramholder_matches.resize(paramholder_index); - paramholder_matches.push_back(treeptr); - return true; - } - if(!paramholder_matches[paramholder_index].IsDefined()) - { - paramholder_matches[paramholder_index] = treeptr; - return true; - } - return treeptr.IsIdenticalTo(paramholder_matches[paramholder_index]); - } - - void SaveMatchedParamIndex(unsigned index) - { - matched_params.push_back(index); - } - - /* These functions retrieve the data from matching - * for use when synthesizing the resulting tree. - */ - const CodeTree& GetParamHolderValueIfFound( unsigned paramholder_index ) const - { - static const CodeTree dummytree; - if(paramholder_matches.size() <= paramholder_index) - return dummytree; - return paramholder_matches[paramholder_index]; - } - - const CodeTree& GetParamHolderValue( unsigned paramholder_index ) const - { return paramholder_matches[paramholder_index]; } - - bool HasRestHolder(unsigned restholder_index) const - { return restholder_matches.size() > restholder_index - && restholder_matches[restholder_index].first == true; } - - const std::vector& GetRestHolderValues( unsigned restholder_index ) const - { - static const std::vector empty_result; - if(restholder_matches.size() <= restholder_index) - return empty_result; - return restholder_matches[restholder_index].second; - } - - const std::vector& GetMatchedParamIndexes() const - { return matched_params; } - - /* */ - void swap(MatchInfo& b) - { - restholder_matches.swap(b.restholder_matches); - paramholder_matches.swap(b.paramholder_matches); - matched_params.swap(b.matched_params); - } - MatchInfo& operator=(const MatchInfo& b) - { - restholder_matches = b.restholder_matches; - paramholder_matches = b.paramholder_matches; - matched_params = b.matched_params; - return *this; - } - }; - - class MatchPositionSpecBase; - - // For iterating through match candidates - typedef FPOPT_autoptr MatchPositionSpecBaseP; - - class MatchPositionSpecBase - { - public: - int RefCount; - public: - MatchPositionSpecBase() : RefCount(0) { } - virtual ~MatchPositionSpecBase() { } - }; - struct MatchResultType - { - bool found; - MatchPositionSpecBaseP specs; - - MatchResultType(bool f) : found(f), specs() { } - MatchResultType(bool f, - const MatchPositionSpecBaseP& s) : found(f), specs(s) { } - }; - - /* Synthesize the given grammatic rule's replacement into the codetree */ - void SynthesizeRule( - const Rule& rule, - CodeTree& tree, - MatchInfo& info); - - /* Test the given parameter to a given CodeTree */ - MatchResultType TestParam( - const ParamSpec& parampair, - const CodeTree& tree, - const MatchPositionSpecBaseP& start_at, - MatchInfo& info); - - /* Test the list of parameters to a given CodeTree */ - MatchResultType TestParams( - const ParamSpec_SubFunctionData& model_tree, - const CodeTree& tree, - const MatchPositionSpecBaseP& start_at, - MatchInfo& info, - bool TopLevel); - - bool ApplyGrammar(const Grammar& grammar, - FPoptimizer_CodeTree::CodeTree& tree, - bool from_logical_context = false); - void ApplyGrammars(FPoptimizer_CodeTree::CodeTree& tree); - - bool IsLogisticallyPlausibleParamsMatch( - const ParamSpec_SubFunctionData& params, - const CodeTree& tree); -} - -namespace FPoptimizer_Grammar -{ - void DumpMatch(const Rule& rule, - const FPoptimizer_CodeTree::CodeTree& tree, - const FPoptimizer_Optimize::MatchInfo& info, - bool DidMatch, - std::ostream& o = std::cout); - void DumpMatch(const Rule& rule, - const FPoptimizer_CodeTree::CodeTree& tree, - const FPoptimizer_Optimize::MatchInfo& info, - const char* whydump, - std::ostream& o = std::cout); -} - -#endif - -#line 1 "fpoptimizer/crc32.h" -/* crc32 */ - -#ifdef _MSC_VER - - typedef unsigned int crc32_t; - -#else - - #include - typedef uint_least32_t crc32_t; - -#endif - -namespace crc32 -{ - enum { startvalue = 0xFFFFFFFFUL, poly = 0xEDB88320UL }; - - /* This code constructs the CRC32 table at compile-time, - * avoiding the need for a huge explicitly written table of magical numbers. */ - template // One byte of a CRC32 (eight bits): - struct b8 - { - enum { b1 = (crc & 1) ? (poly ^ (crc >> 1)) : (crc >> 1), - b2 = (b1 & 1) ? (poly ^ (b1 >> 1)) : (b1 >> 1), - b3 = (b2 & 1) ? (poly ^ (b2 >> 1)) : (b2 >> 1), - b4 = (b3 & 1) ? (poly ^ (b3 >> 1)) : (b3 >> 1), - b5 = (b4 & 1) ? (poly ^ (b4 >> 1)) : (b4 >> 1), - b6 = (b5 & 1) ? (poly ^ (b5 >> 1)) : (b5 >> 1), - b7 = (b6 & 1) ? (poly ^ (b6 >> 1)) : (b6 >> 1), - res= (b7 & 1) ? (poly ^ (b7 >> 1)) : (b7 >> 1) }; - }; - inline crc32_t update(crc32_t crc, unsigned/* char */b) // __attribute__((pure)) - { - // Four values of the table - #define B4(n) b8::res,b8::res,b8::res,b8::res - // Sixteen values of the table - #define R(n) B4(n),B4(n+4),B4(n+8),B4(n+12) - // The whole table, index by steps of 16 - static const crc32_t table[256] = - { R(0x00),R(0x10),R(0x20),R(0x30), R(0x40),R(0x50),R(0x60),R(0x70), - R(0x80),R(0x90),R(0xA0),R(0xB0), R(0xC0),R(0xD0),R(0xE0),R(0xF0) }; - #undef R - #undef B4 - return ((crc >> 8) /* & 0x00FFFFFF*/) ^ table[/*(unsigned char)*/(crc^b)&0xFF]; - } - inline crc32_t calc_upd(crc32_t c, const unsigned char* buf, size_t size) - { - crc32_t value = c; - for(size_t p=0; p - -const std::string FP_GetOpcodeName(FPoptimizer_Grammar::SpecialOpcode opcode, bool pad=false); -const std::string FP_GetOpcodeName(FUNCTIONPARSERTYPES::OPCODE opcode, bool pad=false); - -#line 1 "fpoptimizer/fpoptimizer_opcodename.c" -#include -#include -#include - -#include - -#include "fpconfig.h" -#include "fptypes.h" - -// line removed for fpoptimizer.c: #include "fpoptimizer_grammar.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_opcodename.h" - -using namespace FPoptimizer_Grammar; -using namespace FUNCTIONPARSERTYPES; - -const std::string FP_GetOpcodeName(FPoptimizer_Grammar::SpecialOpcode opcode, bool pad) -{ -#if 1 - /* Symbolic meanings for the opcodes? */ - const char* p = 0; - switch( opcode ) - { - case NumConstant: p = "NumConstant"; break; - case ParamHolder: p = "ParamHolder"; break; - case SubFunction: p = "SubFunction"; break; - } - std::ostringstream tmp; - //if(!p) std::cerr << "o=" << opcode << "\n"; - assert(p); - tmp << p; - if(pad) while(tmp.str().size() < 12) tmp << ' '; - return tmp.str(); -#else - /* Just numeric meanings */ - std::ostringstream tmp; - tmp << opcode; - if(pad) while(tmp.str().size() < 5) tmp << ' '; - return tmp.str(); -#endif -} - -const std::string FP_GetOpcodeName(FUNCTIONPARSERTYPES::OPCODE opcode, bool pad) -{ -#if 1 - /* Symbolic meanings for the opcodes? */ - const char* p = 0; - switch(opcode) - { - case cAbs: p = "cAbs"; break; - case cAcos: p = "cAcos"; break; - case cAcosh: p = "cAcosh"; break; - case cAsin: p = "cAsin"; break; - case cAsinh: p = "cAsinh"; break; - case cAtan: p = "cAtan"; break; - case cAtan2: p = "cAtan2"; break; - case cAtanh: p = "cAtanh"; break; - case cCbrt: p = "cCbrt"; break; - case cCeil: p = "cCeil"; break; - case cCos: p = "cCos"; break; - case cCosh: p = "cCosh"; break; - case cCot: p = "cCot"; break; - case cCsc: p = "cCsc"; break; - case cEval: p = "cEval"; break; - case cExp: p = "cExp"; break; - case cExp2: p = "cExp2"; break; - case cFloor: p = "cFloor"; break; - case cIf: p = "cIf"; break; - case cInt: p = "cInt"; break; - case cLog: p = "cLog"; break; - case cLog2: p = "cLog2"; break; - case cLog10: p = "cLog10"; break; - case cMax: p = "cMax"; break; - case cMin: p = "cMin"; break; - case cPow: p = "cPow"; break; - case cSec: p = "cSec"; break; - case cSin: p = "cSin"; break; - case cSinh: p = "cSinh"; break; - case cSqrt: p = "cSqrt"; break; - case cTan: p = "cTan"; break; - case cTanh: p = "cTanh"; break; - case cTrunc: p = "cTrunc"; break; - case cImmed: p = "cImmed"; break; - case cJump: p = "cJump"; break; - case cNeg: p = "cNeg"; break; - case cAdd: p = "cAdd"; break; - case cSub: p = "cSub"; break; - case cMul: p = "cMul"; break; - case cDiv: p = "cDiv"; break; - case cMod: p = "cMod"; break; - case cEqual: p = "cEqual"; break; - case cNEqual: p = "cNEqual"; break; - case cLess: p = "cLess"; break; - case cLessOrEq: p = "cLessOrEq"; break; - case cGreater: p = "cGreater"; break; - case cGreaterOrEq: p = "cGreaterOrEq"; break; - case cNot: p = "cNot"; break; - case cAnd: p = "cAnd"; break; - case cOr: p = "cOr"; break; - case cDeg: p = "cDeg"; break; - case cRad: p = "cRad"; break; - case cFCall: p = "cFCall"; break; - case cPCall: p = "cPCall"; break; -#ifdef FP_SUPPORT_OPTIMIZER - case cFetch: p = "cFetch"; break; - case cPopNMov: p = "cPopNMov"; break; - case cLog2by: p = "cLog2by"; break; -#endif - case cAbsNot: p = "cAbsNot"; break; - case cAbsNotNot: p = "cAbsNotNot"; break; - case cAbsAnd: p = "cAbsAnd"; break; - case cAbsOr: p = "cAbsOr"; break; - case cAbsIf: p = "cAbsIf"; break; - case cDup: p = "cDup"; break; - case cInv: p = "cInv"; break; - case cSqr: p = "cSqr"; break; - case cRDiv: p = "cRDiv"; break; - case cRSub: p = "cRSub"; break; - case cNotNot: p = "cNotNot"; break; - case cRSqrt: p = "cRSqrt"; break; - case cNop: p = "cNop"; break; - case VarBegin: p = "VarBegin"; break; - } - std::ostringstream tmp; - //if(!p) std::cerr << "o=" << opcode << "\n"; - assert(p); - tmp << p; - if(pad) while(tmp.str().size() < 12) tmp << ' '; - return tmp.str(); -#else - /* Just numeric meanings */ - std::ostringstream tmp; - tmp << opcode; - if(pad) while(tmp.str().size() < 5) tmp << ' '; - return tmp.str(); -#endif -} - -#line 1 "fpoptimizer/fpoptimizer_bytecodesynth.h" -#include "fpconfig.h" -#include "fparser.h" -#include "fptypes.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -#include -#include - -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" - -#ifndef FP_GENERATING_POWI_TABLE -enum { MAX_POWI_BYTECODE_LENGTH = 20 }; -#else -enum { MAX_POWI_BYTECODE_LENGTH = 999 }; -#endif -enum { MAX_MULI_BYTECODE_LENGTH = 3 }; - -namespace FPoptimizer_ByteCode -{ - class ByteCodeSynth - { - public: - ByteCodeSynth() - : ByteCode(), Immed(), StackTop(0), StackMax(0) - { - /* estimate the initial requirements as such */ - ByteCode.reserve(64); - Immed.reserve(8); - StackState.reserve(16); - } - - void Pull(std::vector& bc, - std::vector& imm, - size_t& StackTop_max) - { - ByteCode.swap(bc); - Immed.swap(imm); - StackTop_max = StackMax; - } - - size_t GetByteCodeSize() const { return ByteCode.size(); } - size_t GetStackTop() const { return StackTop; } - - void PushVar(unsigned varno) - { - ByteCode.push_back(varno); - SetStackTop(StackTop+1); - } - - void PushImmed(double immed) - { - using namespace FUNCTIONPARSERTYPES; - ByteCode.push_back(cImmed); - Immed.push_back(immed); - SetStackTop(StackTop+1); - } - - void StackTopIs(const FPoptimizer_CodeTree::CodeTree& tree) - { - if(StackTop > 0) - { - StackState[StackTop-1].first = true; - StackState[StackTop-1].second = tree; - } - } - - void EatNParams(unsigned eat_count) - { - SetStackTop(StackTop - eat_count); - } - - void ProducedNParams(unsigned produce_count) - { - SetStackTop(StackTop + produce_count); - } - - void AddOperation(unsigned opcode, unsigned eat_count, unsigned produce_count = 1) - { - EatNParams(eat_count); - - using namespace FUNCTIONPARSERTYPES; - - if(!ByteCode.empty() && opcode == cMul && ByteCode.back() == cDup) - ByteCode.back() = cSqr; - else - ByteCode.push_back(opcode); - - ProducedNParams(produce_count); - } - - void DoPopNMov(size_t targetpos, size_t srcpos) - { - using namespace FUNCTIONPARSERTYPES; - ByteCode.push_back(cPopNMov); - ByteCode.push_back( (unsigned) targetpos); - ByteCode.push_back( (unsigned) srcpos); - - SetStackTop(srcpos+1); - StackState[targetpos] = StackState[srcpos]; - SetStackTop(targetpos+1); - } - - void DoDup(size_t src_pos) - { - using namespace FUNCTIONPARSERTYPES; - if(src_pos == StackTop-1) - { - ByteCode.push_back(cDup); - } - else - { - ByteCode.push_back(cFetch); - ByteCode.push_back( (unsigned) src_pos); - } - SetStackTop(StackTop + 1); - StackState[StackTop-1] = StackState[src_pos]; - } - - size_t FindPos(const FPoptimizer_CodeTree::CodeTree& tree) const - { - /*std::cout << "Stack state now(" << StackTop << "):\n"; - for(size_t a=0; a0; ) - if(StackState[a].first && StackState[a].second.IsIdenticalTo(tree)) - return a; - return ~size_t(0); - } - - bool Find(const FPoptimizer_CodeTree::CodeTree& tree) const - { - return FindPos(tree) != ~size_t(0); - } - - bool FindAndDup(const FPoptimizer_CodeTree::CodeTree& tree) - { - size_t pos = FindPos(tree); - if(pos != ~size_t(0)) - { - DoDup(pos); - return true; - } - return false; - } - - struct IfData - { - size_t ofs; - }; - - void SynthIfStep1(IfData& ifdata, FUNCTIONPARSERTYPES::OPCODE op) - { - using namespace FUNCTIONPARSERTYPES; - SetStackTop(StackTop-1); // the If condition was popped. - - ifdata.ofs = ByteCode.size(); - ByteCode.push_back(op); - ByteCode.push_back(0); // code index - ByteCode.push_back(0); // Immed index - } - void SynthIfStep2(IfData& ifdata) - { - using namespace FUNCTIONPARSERTYPES; - SetStackTop(StackTop-1); // ignore the pushed then-branch result. - - ByteCode[ifdata.ofs+1] = unsigned( ByteCode.size()+2 ); - ByteCode[ifdata.ofs+2] = unsigned( Immed.size() ); - - ifdata.ofs = ByteCode.size(); - ByteCode.push_back(cJump); - ByteCode.push_back(0); // code index - ByteCode.push_back(0); // Immed index - } - void SynthIfStep3(IfData& ifdata) - { - using namespace FUNCTIONPARSERTYPES; - SetStackTop(StackTop-1); // ignore the pushed else-branch result. - - ByteCode[ifdata.ofs+1] = unsigned( ByteCode.size()-1 ); - ByteCode[ifdata.ofs+2] = unsigned( Immed.size() ); - - SetStackTop(StackTop+1); // one or the other was pushed. - - /* Threading jumps: - * If there are any cJumps that point - * to the cJump instruction we just changed, - * change them to point to this target as well. - * This screws up PrintByteCode() majorly. - */ - for(size_t a=0; a StackMax) - { - StackMax = StackTop; - StackState.resize(StackMax); - } - } - - private: - std::vector ByteCode; - std::vector Immed; - - std::vector< - std::pair - > StackState; - size_t StackTop; - size_t StackMax; - }; - - struct SequenceOpCode; - extern const SequenceOpCode AddSequence; /* Multiplication implemented with adds */ - extern const SequenceOpCode MulSequence; /* Exponentiation implemented with muls */ - - /* Generate a sequence that multiplies or exponentifies the - * last operand in the stack by the given constant integer - * amount (positive or negative). - */ - void AssembleSequence( - long count, - const SequenceOpCode& sequencing, - ByteCodeSynth& synth); -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_bytecodesynth.c" -// line removed for fpoptimizer.c: #include "fpoptimizer_bytecodesynth.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; - -namespace FPoptimizer_ByteCode -{ - const struct SequenceOpCode - { - double basevalue; - unsigned op_flip; - unsigned op_normal, op_normal_flip; - unsigned op_inverse, op_inverse_flip; - } AddSequence = {0.0, cNeg, cAdd, cAdd, cSub, cRSub }, - MulSequence = {1.0, cInv, cMul, cMul, cDiv, cRDiv }; -} - -using namespace FPoptimizer_ByteCode; - -#define POWI_TABLE_SIZE 256 -#define POWI_WINDOW_SIZE 3 -namespace FPoptimizer_ByteCode -{ - #ifndef FP_GENERATING_POWI_TABLE - extern const - unsigned char powi_table[POWI_TABLE_SIZE]; - const - #endif - unsigned char powi_table[POWI_TABLE_SIZE] = - { - 0, 1, 1, 1, 2, 1, 2, 1, /* 0 - 7 */ - 4, 1, 2, 1, 4, 1, 2, 131, /* 8 - 15 */ - 8, 1, 2, 1, 4, 1, 2, 1, /* 16 - 23 */ - 8, 133, 2, 131, 4, 1, 15, 1, /* 24 - 31 */ - 16, 1, 2, 1, 4, 1, 2, 131, /* 32 - 39 */ - 8, 1, 2, 1, 4, 133, 2, 1, /* 40 - 47 */ - 16, 1, 25, 131, 4, 1, 27, 5, /* 48 - 55 */ - 8, 3, 2, 1, 30, 1, 31, 3, /* 56 - 63 */ - 32, 1, 2, 1, 4, 1, 2, 1, /* 64 - 71 */ - 8, 1, 2, 131, 4, 1, 39, 1, /* 72 - 79 */ - 16, 137, 2, 1, 4, 133, 2, 131, /* 80 - 87 */ - 8, 1, 45, 135, 4, 31, 2, 5, /* 88 - 95 */ - 32, 1, 2, 131, 50, 1, 51, 1, /* 96 - 103 */ - 8, 3, 2, 1, 54, 1, 55, 3, /* 104 - 111 */ - 16, 1, 57, 133, 4, 137, 2, 135, /* 112 - 119 */ - 60, 1, 61, 3, 62, 133, 63, 1, /* 120 - 127 */ - 130, 1, 2, 1, 130, 1, 2, 131, /* 128 - 135 */ - 130, 1, 2, 1, 130, 1, 2, 139, /* 136 - 143 */ - 130, 1, 2, 131, 130, 1, 30, 1, /* 144 - 151 */ - 130, 137, 2, 31, 130, 1, 2, 131, /* 152 - 159 */ - 130, 1, 130, 1, 130, 133, 2, 1, /* 160 - 167 */ - 130, 1, 130, 1, 2, 1, 130, 133, /* 168 - 175 */ - 130, 1, 2, 1, 130, 1, 2, 61, /* 176 - 183 */ - 130, 133, 62, 139, 130, 137, 130, 1, /* 184 - 191 */ - 130, 1, 2, 131, 130, 1, 130, 1, /* 192 - 199 */ - 130, 1, 2, 1, 130, 1, 2, 131, /* 200 - 207 */ - 130, 1, 130, 1, 130, 131, 2, 133, /* 208 - 215 */ - 130, 1, 2, 131, 130, 141, 130, 1, /* 216 - 223 */ - 130, 133, 2, 1, 130, 1, 5, 135, /* 224 - 231 */ - 130, 1, 130, 1, 2, 131, 130, 1, /* 232 - 239 */ - 130, 1, 2, 131, 130, 133, 130, 141, /* 240 - 247 */ - 130, 131, 130, 1, 130, 1, 2, 131 /* 248 - 255 */ - }; /* as in gcc, but custom-optimized for stack calculation */ -} -static const int POWI_CACHE_SIZE = 256; - -#define FPO(x) /**/ -//#define FPO(x) x - - -namespace -{ - class PowiCache - { - private: - int cache[POWI_CACHE_SIZE]; - int cache_needed[POWI_CACHE_SIZE]; - - public: - PowiCache() - : cache(), cache_needed() /* Assume we have no factors in the cache */ - { - /* Decide which factors we would need multiple times. - * Output: - * cache[] = these factors were generated - * cache_needed[] = number of times these factors were desired - */ - cache[1] = 1; // We have this value already. - } - - bool Plan_Add(long value, int count) - { - if(value >= POWI_CACHE_SIZE) return false; - //FPO(fprintf(stderr, "%ld will be needed %d times more\n", count, need_count)); - cache_needed[value] += count; - return cache[value] != 0; - } - - void Plan_Has(long value) - { - if(value < POWI_CACHE_SIZE) - cache[value] = 1; // This value has been generated - } - - void Start(size_t value1_pos) - { - for(int n=2; n= 0) - { - // found from the cache - FPO(fprintf(stderr, "* I found %ld from cache (%u,%d)\n", - value, (unsigned)cache[value], cache_needed[value])); - return cache[value]; - } - } - return -1; - } - - void Remember(long value, size_t stackpos) - { - if(value >= POWI_CACHE_SIZE) return; - - FPO(fprintf(stderr, "* Remembering that %ld can be found at %u (%d uses remain)\n", - value, (unsigned)stackpos, cache_needed[value])); - cache[value] = (int) stackpos; - } - - void DumpContents() const - { - FPO(for(int a=1; a= 0 || cache_needed[a] > 0) - { - fprintf(stderr, "== cache: sp=%d, val=%d, needs=%d\n", - cache[a], a, cache_needed[a]); - }) - } - - int UseGetNeeded(long value) - { - if(value >= 0 && value < POWI_CACHE_SIZE) - return --cache_needed[value]; - return 0; - } - }; - - - size_t AssembleSequence_Subdivide( - long count, - PowiCache& cache, - const SequenceOpCode& sequencing, - ByteCodeSynth& synth); - - void Subdivide_Combine( - size_t apos, long aval, - size_t bpos, long bval, - PowiCache& cache, - - unsigned cumulation_opcode, - unsigned cimulation_opcode_flip, - - ByteCodeSynth& synth); - - void PlanNtimesCache - (long value, - PowiCache& cache, - int need_count, - int recursioncount=0) - { - if(value < 1) return; - - #ifdef FP_GENERATING_POWI_TABLE - if(recursioncount > 32) throw false; - #endif - - if(cache.Plan_Add(value, need_count)) return; - - long half = 1; - if(value < POWI_TABLE_SIZE) - { - half = powi_table[value]; - if(half & 128) - { - half &= 127; - if(half & 64) - half = -(half & 63) - 1; - - FPO(fprintf(stderr, "value=%ld, half=%ld, otherhalf=%ld\n", value,half,value/half)); - - PlanNtimesCache(half, cache, 1, recursioncount+1); - cache.Plan_Has(half); - return; - } - else if(half & 64) - { - half = -(half & 63) - 1; - } - } - else if(value & 1) - half = value & ((1 << POWI_WINDOW_SIZE) - 1); // that is, value & 7 - else - half = value / 2; - - long otherhalf = value-half; - if(half > otherhalf || half<0) std::swap(half,otherhalf); - - FPO(fprintf(stderr, "value=%ld, half=%ld, otherhalf=%ld\n", value,half,otherhalf)); - - if(half == otherhalf) - { - PlanNtimesCache(half, cache, 2, recursioncount+1); - } - else - { - PlanNtimesCache(half, cache, 1, recursioncount+1); - PlanNtimesCache(otherhalf>0?otherhalf:-otherhalf, - cache, 1, recursioncount+1); - } - cache.Plan_Has(value); - } - - size_t AssembleSequence_Subdivide( - long value, - PowiCache& cache, - const SequenceOpCode& sequencing, - ByteCodeSynth& synth) - { - int cachepos = cache.Find(value); - if(cachepos >= 0) - { - // found from the cache - return cachepos; - } - - long half = 1; - if(value < POWI_TABLE_SIZE) - { - half = powi_table[value]; - if(half & 128) - { - half &= 127; - if(half & 64) - half = -(half & 63) - 1; - - FPO(fprintf(stderr, "* I want %ld, my plan is %ld * %ld\n", value, half, value/half)); - size_t half_pos = AssembleSequence_Subdivide(half, cache, sequencing, synth); - if(cache.UseGetNeeded(half) > 0 - || half_pos != synth.GetStackTop()-1) - { - synth.DoDup(half_pos); - cache.Remember(half, synth.GetStackTop()-1); - } - AssembleSequence(value/half, sequencing, synth); - size_t stackpos = synth.GetStackTop()-1; - cache.Remember(value, stackpos); - cache.DumpContents(); - return stackpos; - } - else if(half & 64) - { - half = -(half & 63) - 1; - } - } - else if(value & 1) - half = value & ((1 << POWI_WINDOW_SIZE) - 1); // that is, value & 7 - else - half = value / 2; - - long otherhalf = value-half; - if(half > otherhalf || half<0) std::swap(half,otherhalf); - - FPO(fprintf(stderr, "* I want %ld, my plan is %ld + %ld\n", value, half, value-half)); - - if(half == otherhalf) - { - size_t half_pos = AssembleSequence_Subdivide(half, cache, sequencing, synth); - - // self-cumulate the subdivide result - Subdivide_Combine(half_pos,half, half_pos,half, cache, - sequencing.op_normal, sequencing.op_normal_flip, - synth); - } - else - { - long part1 = half; - long part2 = otherhalf>0?otherhalf:-otherhalf; - - size_t part1_pos = AssembleSequence_Subdivide(part1, cache, sequencing, synth); - size_t part2_pos = AssembleSequence_Subdivide(part2, cache, sequencing, synth); - - FPO(fprintf(stderr, "Subdivide(%ld: %ld, %ld)\n", value, half, otherhalf)); - - Subdivide_Combine(part1_pos,part1, part2_pos,part2, cache, - otherhalf>0 ? sequencing.op_normal : sequencing.op_inverse, - otherhalf>0 ? sequencing.op_normal_flip : sequencing.op_inverse_flip, - synth); - } - - size_t stackpos = synth.GetStackTop()-1; - cache.Remember(value, stackpos); - cache.DumpContents(); - return stackpos; - } - - void Subdivide_Combine( - size_t apos, long aval, - size_t bpos, long bval, - PowiCache& cache, - unsigned cumulation_opcode, - unsigned cumulation_opcode_flip, - ByteCodeSynth& synth) - { - /*FPO(fprintf(stderr, "== making result for (sp=%u, val=%d, needs=%d) and (sp=%u, val=%d, needs=%d), stacktop=%u\n", - (unsigned)apos, aval, aval>=0 ? cache_needed[aval] : -1, - (unsigned)bpos, bval, bval>=0 ? cache_needed[bval] : -1, - (unsigned)synth.GetStackTop()));*/ - - // Figure out whether we can trample a and b - int a_needed = cache.UseGetNeeded(aval); - int b_needed = cache.UseGetNeeded(bval); - - bool flipped = false; - - #define DUP_BOTH() do { \ - if(apos < bpos) { size_t tmp=apos; apos=bpos; bpos=tmp; flipped=!flipped; } \ - FPO(fprintf(stderr, "-> dup(%u) dup(%u) op\n", (unsigned)apos, (unsigned)bpos)); \ - synth.DoDup(apos); \ - synth.DoDup(apos==bpos ? synth.GetStackTop()-1 : bpos); } while(0) - #define DUP_ONE(p) do { \ - FPO(fprintf(stderr, "-> dup(%u) op\n", (unsigned)p)); \ - synth.DoDup(p); \ - } while(0) - - if(a_needed > 0) - { - if(b_needed > 0) - { - // If they must both be preserved, make duplicates - // First push the one that is at the larger stack - // address. This increases the odds of possibly using cDup. - DUP_BOTH(); - - //SCENARIO 1: - // Input: x B A x x - // Temp: x B A x x A B - // Output: x B A x x R - //SCENARIO 2: - // Input: x A B x x - // Temp: x A B x x B A - // Output: x A B x x R - } - else - { - // A must be preserved, but B can be trampled over - - // SCENARIO 1: - // Input: x B x x A - // Temp: x B x x A A B (dup both, later first) - // Output: x B x x A R - // SCENARIO 2: - // Input: x A x x B - // Temp: x A x x B A - // Output: x A x x R -- only commutative cases - // SCENARIO 3: - // Input: x x x B A - // Temp: x x x B A A B (dup both, later first) - // Output: x x x B A R - // SCENARIO 4: - // Input: x x x A B - // Temp: x x x A B A -- only commutative cases - // Output: x x x A R - // SCENARIO 5: - // Input: x A B x x - // Temp: x A B x x A B (dup both, later first) - // Output: x A B x x R - - // if B is not at the top, dup both. - if(bpos != synth.GetStackTop()-1) - DUP_BOTH(); // dup both - else - { - DUP_ONE(apos); // just dup A - flipped=!flipped; - } - } - } - else if(b_needed > 0) - { - // B must be preserved, but A can be trampled over - // This is a mirror image of the a_needed>0 case, so I'll cut the chase - if(apos != synth.GetStackTop()-1) - DUP_BOTH(); - else - DUP_ONE(bpos); - } - else - { - // Both can be trampled over. - // SCENARIO 1: - // Input: x B x x A - // Temp: x B x x A B - // Output: x B x x R - // SCENARIO 2: - // Input: x A x x B - // Temp: x A x x B A - // Output: x A x x R -- only commutative cases - // SCENARIO 3: - // Input: x x x B A - // Output: x x x R -- only commutative cases - // SCENARIO 4: - // Input: x x x A B - // Output: x x x R - // SCENARIO 5: - // Input: x A B x x - // Temp: x A B x x A B (dup both, later first) - // Output: x A B x x R - // SCENARIO 6: - // Input: x x x C - // Temp: x x x C C (c is both A and B) - // Output: x x x R - - if(apos == bpos && apos == synth.GetStackTop()-1) - DUP_ONE(apos); // scenario 6 - else if(apos == synth.GetStackTop()-1 && bpos == synth.GetStackTop()-2) - { - FPO(fprintf(stderr, "-> op\n")); // scenario 3 - flipped=!flipped; - } - else if(apos == synth.GetStackTop()-2 && bpos == synth.GetStackTop()-1) - FPO(fprintf(stderr, "-> op\n")); // scenario 4 - else if(apos == synth.GetStackTop()-1) - DUP_ONE(bpos); // scenario 1 - else if(bpos == synth.GetStackTop()-1) - { - DUP_ONE(apos); // scenario 2 - flipped=!flipped; - } - else - DUP_BOTH(); // scenario 5 - } - // Add them together. - synth.AddOperation(flipped ? cumulation_opcode_flip : cumulation_opcode, 2); - } - - void LightWeight( - long count, - const SequenceOpCode& sequencing, - ByteCodeSynth& synth) - { - while(count < 256) - { - int half = FPoptimizer_ByteCode::powi_table[count]; - if(half & 128) - { - half &= 127; - LightWeight(half, sequencing, synth); - count /= half; - } - else break; - } - if(count == 1) return; - if(!(count & 1)) - { - synth.AddOperation(cSqr, 1); - LightWeight(count/2, sequencing, synth); - } - else - { - synth.DoDup(synth.GetStackTop()-1); - LightWeight(count-1, sequencing, synth); - synth.AddOperation(cMul, 2); - } - } -} - -namespace FPoptimizer_ByteCode -{ - void AssembleSequence( - long count, - const SequenceOpCode& sequencing, - ByteCodeSynth& synth) - { - if(count == 0) - synth.PushImmed(sequencing.basevalue); - else - { - bool needs_flip = false; - if(count < 0) - { - needs_flip = true; - count = -count; - } - - if(false) - LightWeight(count,sequencing,synth); - else if(count > 1) - { - /* To prevent calculating the same factors over and over again, - * we use a cache. */ - PowiCache cache; - PlanNtimesCache(count, cache, 1); - - size_t stacktop_desired = synth.GetStackTop(); - - cache.Start( synth.GetStackTop()-1 ); - - FPO(fprintf(stderr, "Calculating result for %ld...\n", count)); - size_t res_stackpos = AssembleSequence_Subdivide( - count, cache, sequencing, - synth); - - size_t n_excess = synth.GetStackTop() - stacktop_desired; - if(n_excess > 0 || res_stackpos != stacktop_desired-1) - { - // Remove the cache values - synth.DoPopNMov(stacktop_desired-1, res_stackpos); - } - } - - if(needs_flip) - synth.AddOperation(sequencing.op_flip, 1); - } - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_codetree.c" -#include -#include - -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -#include "fptypes.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; -//using namespace FPoptimizer_Grammar; - -namespace FPoptimizer_CodeTree -{ - CodeTree::CodeTree() - : data(new CodeTreeData) - { - data->Opcode = cNop; - } - - CodeTree::CodeTree(double i) - : data(new CodeTreeData(i)) - { - data->Recalculate_Hash_NoRecursion(); - } - - CodeTree::CodeTree(unsigned v, CodeTree::VarTag) - : data(new CodeTreeData) - { - data->Opcode = VarBegin; - data->Var = v; - data->Recalculate_Hash_NoRecursion(); - } - - CodeTree::CodeTree(const CodeTree& b, CodeTree::CloneTag) - : data(new CodeTreeData(*b.data)) - { - } - - CodeTree::~CodeTree() - { - } - - struct ParamComparer - { - bool operator() (const CodeTree& a, const CodeTree& b) const - { - if(a.GetDepth() != b.GetDepth()) - return a.GetDepth() > b.GetDepth(); - return a.GetHash() < b.GetHash(); - } - }; - - void CodeTreeData::Sort() - { - /* If the tree is commutative, order the parameters - * in a set order in order to make equality tests - * efficient in the optimizer - */ - switch(Opcode) - { - case cAdd: - case cMul: - case cMin: - case cMax: - case cAnd: - case cOr: - case cEqual: - case cNEqual: - std::sort(Params.begin(), Params.end(), ParamComparer()); - break; - case cLess: - if(ParamComparer() (Params[1], Params[0])) - { std::swap(Params[0], Params[1]); Opcode = cGreater; } - break; - case cLessOrEq: - if(ParamComparer() (Params[1], Params[0])) - { std::swap(Params[0], Params[1]); Opcode = cGreaterOrEq; } - break; - case cGreater: - if(ParamComparer() (Params[1], Params[0])) - { std::swap(Params[0], Params[1]); Opcode = cLess; } - break; - case cGreaterOrEq: - if(ParamComparer() (Params[1], Params[0])) - { std::swap(Params[0], Params[1]); Opcode = cLessOrEq; } - break; - default: - break; - } - } - - void CodeTree::AddParam(const CodeTree& param) - { - //std::cout << "AddParam called\n"; - data->Params.push_back(param); - } - void CodeTree::AddParamMove(CodeTree& param) - { - data->Params.push_back(CodeTree()); - data->Params.back().swap(param); - } - void CodeTree::SetParam(size_t which, const CodeTree& b) - { - DataP slot_holder ( data->Params[which].data ); - data->Params[which] = b; - } - void CodeTree::SetParamMove(size_t which, CodeTree& b) - { - DataP slot_holder ( data->Params[which].data ); - data->Params[which].swap(b); - } - - void CodeTree::AddParams(const std::vector& RefParams) - { - data->Params.insert(data->Params.end(), RefParams.begin(), RefParams.end()); - } - void CodeTree::AddParamsMove(std::vector& RefParams) - { - size_t endpos = data->Params.size(), added = RefParams.size(); - data->Params.resize(endpos + added, CodeTree()); - for(size_t p=0; pParams[endpos+p].swap( RefParams[p] ); - } - void CodeTree::AddParamsMove(std::vector& RefParams, size_t replacing_slot) - { - DataP slot_holder ( data->Params[replacing_slot].data ); - DelParam(replacing_slot); - AddParamsMove(RefParams); - /* - const size_t n_added = RefParams.size(); - const size_t oldsize = data->Params.size(); - const size_t newsize = oldsize + n_added - 1; - if(RefParams.empty()) - DelParam(replacing_slot); - else - { - // 0 1 2 3 4 5 6 7 8 9 10 11 - // a a a a X b b b b b - // a a a a Y Y Y b b b b b - // - // replacing_slot = 4 - // n_added = 3 - // oldsize = 10 - // newsize = 12 - // tail_length = 5 - - data->Params.resize(newsize); - data->Params[replacing_slot].data = 0; - const size_t tail_length = oldsize - replacing_slot -1; - for(size_t tail=0; tailParams[newsize-1-tail].data.UnsafeSetP( - &*data->Params[newsize-1-tail-(n_added-1)].data); - for(size_t head=1; headParams[replacing_slot+head].data.UnsafeSetP( 0 ); - for(size_t p=0; pParams[replacing_slot+p].swap( RefParams[p] ); - } - */ - } - - void CodeTree::SetParams(const std::vector& RefParams) - { - //std::cout << "SetParams called" << (do_clone ? ", clone" : ", no clone") << "\n"; - std::vector tmp(RefParams); - data->Params.swap(tmp); - } - - void CodeTree::SetParamsMove(std::vector& RefParams) - { - data->Params.swap(RefParams); - RefParams.clear(); - } - -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - void CodeTree::SetParams(std::vector&& RefParams) - { - //std::cout << "SetParams&& called\n"; - SetParamsMove(RefParams); - } -#endif - - void CodeTree::DelParam(size_t index) - { - std::vector& Params = data->Params; - //std::cout << "DelParam(" << index << ") called\n"; - #ifdef __GXX_EXPERIMENTAL_CXX0X__ - /* rvalue reference semantics makes this optimal */ - Params.erase( Params.begin() + index ); - #else - /* This labor evades the need for refcount +1/-1 shuffling */ - Params[index].data = 0; - for(size_t p=index; p+1Params.clear(); - } - - /* Is the value of this tree definitely odd(true) or even(false)? */ - CodeTree::TriTruthValue CodeTree::GetEvennessInfo() const - { - if(!IsImmed()) return Unknown; - if(!IsLongIntegerImmed()) return Unknown; - return (GetLongIntegerImmed() & 1) ? IsNever : IsAlways; - } - - bool CodeTree::IsLogicalValue() const - { - switch(data->Opcode) - { - case cImmed: - return FloatEqual(data->Value, 0.0) - || FloatEqual(data->Value, 1.0); - case cAnd: - case cOr: - case cNot: - case cNotNot: - case cAbsAnd: - case cAbsOr: - case cAbsNot: - case cAbsNotNot: - case cEqual: - case cNEqual: - case cLess: - case cLessOrEq: - case cGreater: - case cGreaterOrEq: - /* These operations always produce truth values (0 or 1) */ - return true; - case cMul: - { - std::vector& Params = data->Params; - for(size_t a=0; a& Params = data->Params; - return Params[1].IsLogicalValue() - && Params[2].IsLogicalValue(); - } - default: - break; - } - return false; // Not a logical value. - } - - bool CodeTree::IsAlwaysInteger(bool integer) const - { - switch(data->Opcode) - { - case cImmed: - return IsLongIntegerImmed() ? integer==true : integer==false; - case cFloor: - case cInt: - return integer==true; - case cAnd: - case cOr: - case cNot: - case cNotNot: - case cEqual: - case cNEqual: - case cLess: - case cLessOrEq: - case cGreater: - case cGreaterOrEq: - /* These operations always produce truth values (0 or 1) */ - return integer==true; /* 0 and 1 are both integers */ - case cIf: - { - std::vector& Params = data->Params; - return Params[1].IsAlwaysInteger(integer) - && Params[2].IsAlwaysInteger(integer); - return true; /* 0 and 1 are both integers */ - } - case cAdd: - case cMul: - { - for(size_t a=GetParamCount(); a-- > 0; ) - if(!GetParam(a).IsAlwaysInteger(integer)) - return false; - return true; - } - default: - break; - } - return false; /* Don't know whether it's integer. */ - } - - bool CodeTree::IsAlwaysSigned(bool positive) const - { - MinMaxTree tmp = CalculateResultBoundaries(); - - if(positive) - return tmp.has_min && tmp.min >= 0.0 - && (!tmp.has_max || tmp.max >= 0.0); - else - return tmp.has_max && tmp.max < 0.0 - && (!tmp.has_min || tmp.min < 0.0); - } - - bool CodeTree::IsIdenticalTo(const CodeTree& b) const - { - //if((!&*data) != (!&*b.data)) return false; - if(&*data == &*b.data) return true; - return data->IsIdenticalTo(*b.data); - } - - bool CodeTreeData::IsIdenticalTo(const CodeTreeData& b) const - { - if(Hash != b.Hash) return false; // a quick catch-all - if(Opcode != b.Opcode) return false; - switch(Opcode) - { - case cImmed: return FloatEqual(Value, b.Value); - case VarBegin: return Var == b.Var; - case cFCall: - case cPCall: if(Funcno != b.Funcno) return false; break; - default: break; - } - if(Params.size() != b.Params.size()) return false; - for(size_t a=0; aRefCount > 1) - data = new CodeTreeData(*data); - } - - CodeTree CodeTree::GetUniqueRef() - { - if(data->RefCount > 1) - return CodeTree(*this, CloneTag()); - return *this; - } - - CodeTreeData::CodeTreeData() - : RefCount(0), - Opcode(cNop), Params(), Hash(), Depth(1), OptimizedUsing(0) - { - } - - CodeTreeData::CodeTreeData(const CodeTreeData& b) - : RefCount(0), - Opcode(b.Opcode), - Params(b.Params), - Hash(b.Hash), - Depth(b.Depth), - OptimizedUsing(b.OptimizedUsing) - { - switch(Opcode) - { - case VarBegin: Var = b.Var; break; - case cImmed: Value = b.Value; break; - case cPCall: - case cFCall: Funcno = b.Funcno; break; - default: break; - } - } - -#ifdef __GXX_EXPERIMENTAL_CXX0X__ - CodeTreeData::CodeTreeData(CodeTreeData&& b) - : RefCount(0), - Opcode(b.Opcode), - Params(b.Params), - Hash(b.Hash), - Depth(b.Depth), - OptimizedUsing(b.OptimizedUsing) - { - switch(Opcode) - { - case VarBegin: Var = b.Var; break; - case cImmed: Value = b.Value; break; - case cPCall: - case cFCall: Funcno = b.Funcno; break; - default: break; - } - } -#endif - - CodeTreeData::CodeTreeData(double i) - : RefCount(0), Opcode(cImmed), Params(), Hash(), Depth(1), OptimizedUsing(0) - { - Value = i; - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_debug.c" -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_opcodename.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -#include -#include -#include -#include -#include - -using namespace FUNCTIONPARSERTYPES; - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT -namespace -{ - void DumpHashesFrom( - const FPoptimizer_CodeTree::CodeTree& tree, - std::map >& done, - std::ostream& o) - { - for(size_t a=0; a > done; - DumpHashesFrom(tree, done, o); - - for(std::map >::const_iterator - i = done.begin(); - i != done.end(); - ++i) - { - const std::set& flist = i->second; - if(flist.size() != 1) o << "ERROR - HASH COLLISION?\n"; - for(std::set::const_iterator - j = flist.begin(); - j != flist.end(); - ++j) - { - o << '[' << std::hex << i->first.hash1 - << ',' << i->first.hash2 - << ']' << std::dec; - o << ": " << *j << "\n"; - } - } - } - - void DumpTree(const CodeTree& tree, std::ostream& o) - { - //o << "/*" << tree.Depth << "*/"; - const char* sep2 = " "; - /* - o << '[' << std::hex << tree.Hash.hash1 - << ',' << tree.Hash.hash2 - << ']' << std::dec; - */ - switch(tree.GetOpcode()) - { - case cImmed: - o << tree.GetImmed(); - /* - o << "(" << std::hex - << *(const uint_least64_t*)&tree.GetImmed() - << std::dec << ")"; - */ - return; - case VarBegin: o << "Var" << (tree.GetVar() - VarBegin); return; - case cAdd: sep2 = " +"; break; - case cMul: sep2 = " *"; break; - case cAnd: sep2 = " &"; break; - case cOr: sep2 = " |"; break; - case cPow: sep2 = " ^"; break; - default: - sep2 = " "; - o << FP_GetOpcodeName(tree.GetOpcode()); - if(tree.GetOpcode() == cFCall || tree.GetOpcode() == cPCall) - o << ':' << tree.GetFuncNo(); - } - o << '('; - if(tree.GetParamCount() <= 1 && sep2[1]) o << (sep2+1) << ' '; - for(size_t a=0; a 0) o << ' '; - - DumpTree(tree.GetParam(a), o); - - if(a+1 < tree.GetParamCount()) o << sep2; - } - o << ')'; - } - - void DumpTreeWithIndent(const CodeTree& tree, std::ostream& o, const std::string& indent) - { - o << '[' << std::hex << (void*)(&tree.GetParams()) - << std::dec - << ',' << tree.GetRefCount() - << ']'; - o << indent << '_'; - - switch(tree.GetOpcode()) - { - case cImmed: o << "cImmed " << tree.GetImmed(); o << '\n'; return; - case VarBegin: o << "VarBegin " << (tree.GetVar() - VarBegin); o << '\n'; return; - default: - o << FP_GetOpcodeName(tree.GetOpcode()); - if(tree.GetOpcode() == cFCall || tree.GetOpcode() == cPCall) - o << ':' << tree.GetFuncNo(); - o << '\n'; - } - for(size_t a=0; a - -namespace FPoptimizer_Grammar -{ - bool ParamSpec_Compare(const void* aa, const void* bb, SpecialOpcode type) - { - switch(type) - { - case ParamHolder: - { - ParamSpec_ParamHolder& a = *(ParamSpec_ParamHolder*) aa; - ParamSpec_ParamHolder& b = *(ParamSpec_ParamHolder*) bb; - return a.constraints == b.constraints - && a.index == b.index - && a.depcode == b.depcode; - } - case NumConstant: - { - ParamSpec_NumConstant& a = *(ParamSpec_NumConstant*) aa; - ParamSpec_NumConstant& b = *(ParamSpec_NumConstant*) bb; - return FloatEqual(a.constvalue, b.constvalue); - } - case SubFunction: - { - ParamSpec_SubFunction& a = *(ParamSpec_SubFunction*) aa; - ParamSpec_SubFunction& b = *(ParamSpec_SubFunction*) bb; - return a.constraints == b.constraints - && a.data.subfunc_opcode == b.data.subfunc_opcode - && a.data.match_type == b.data.match_type - && a.data.param_count == b.data.param_count - && a.data.param_list == b.data.param_list - && a.data.restholder_index == b.data.restholder_index - && a.depcode == b.depcode; - } - } - return true; - } - - unsigned ParamSpec_GetDepCode(const ParamSpec& b) - { - switch(b.first) - { - case ParamHolder: - { - const ParamSpec_ParamHolder* s = (const ParamSpec_ParamHolder*) b.second; - return s->depcode; - } - case SubFunction: - { - const ParamSpec_SubFunction* s = (const ParamSpec_SubFunction*) b.second; - return s->depcode; - } - default: break; - } - return 0; - } - - void DumpParam(const ParamSpec& parampair, std::ostream& o) - { - static const char ParamHolderNames[][2] = {"%","&", "x","y","z","a","b","c"}; - - //o << "/*p" << (&p-pack.plist) << "*/"; - unsigned constraints = 0; - switch(parampair.first) - { - case NumConstant: - { const ParamSpec_NumConstant& param = *(const ParamSpec_NumConstant*) parampair.second; - o.precision(12); - o << param.constvalue; break; } - case ParamHolder: - { const ParamSpec_ParamHolder& param = *(const ParamSpec_ParamHolder*) parampair.second; - o << ParamHolderNames[param.index]; - constraints = param.constraints; - break; } - case SubFunction: - { const ParamSpec_SubFunction& param = *(const ParamSpec_SubFunction*) parampair.second; - constraints = param.constraints; - if(param.data.match_type == GroupFunction) - { - if(param.data.subfunc_opcode == cNeg) - { o << "-"; DumpParams(param.data.param_list, param.data.param_count, o); } - else if(param.data.subfunc_opcode == cInv) - { o << "/"; DumpParams(param.data.param_list, param.data.param_count, o); } - else - { - std::string opcode = FP_GetOpcodeName(param.data.subfunc_opcode).substr(1); - for(size_t a=0; a'; - if(param.data.match_type == PositionalParams) o << "]"; - if(param.data.match_type == SelectedParams) o << "}"; - o << ')'; - } - break; } - } - switch( ImmedConstraint_Value(constraints & ValueMask) ) - { - case ValueMask: break; - case Value_AnyNum: break; - case Value_EvenInt: o << "@E"; break; - case Value_OddInt: o << "@O"; break; - case Value_IsInteger: o << "@I"; break; - case Value_NonInteger:o << "@F"; break; - case Value_Logical: o << "@L"; break; - } - switch( ImmedConstraint_Sign(constraints & SignMask) ) - { - case SignMask: break; - case Sign_AnySign: break; - case Sign_Positive: o << "@P"; break; - case Sign_Negative: o << "@N"; break; - } - switch( ImmedConstraint_Oneness(constraints & OnenessMask) ) - { - case OnenessMask: break; - case Oneness_Any: break; - case Oneness_One: o << "@1"; break; - case Oneness_NotOne: o << "@M"; break; - } - } - - void DumpParams(unsigned paramlist, unsigned count, std::ostream& o) - { - for(unsigned a=0; a 0) o << ' '; - const ParamSpec& param = ParamSpec_Extract(paramlist,a); - DumpParam(param, o); - unsigned depcode = ParamSpec_GetDepCode(param); - if(depcode != 0) - o << "@D" << depcode; - } - } -} - -#line 1 "fpoptimizer/fpoptimizer_grammar_data.c" -/* This file is automatically generated. Do not edit... */ -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" -#include "fpconfig.h" -#include "fptypes.h" -#include - -#define P1(a) a -#define P2(a,b) (P1(a) | (b << PARAM_INDEX_BITS)) -#define P3(a,b,c) (P2(a,b) | (c << (PARAM_INDEX_BITS*2))) - -#define grammar_optimize_abslogical grammar_optimize_abslogical_tweak -#define grammar_optimize_ignore_if_sideeffects grammar_optimize_ignore_if_sideeffects_tweak -#define grammar_optimize_nonshortcut_logical_evaluation grammar_optimize_nonshortcut_logical_evaluation_tweak -#define grammar_optimize_round1 grammar_optimize_round1_tweak -#define grammar_optimize_round2 grammar_optimize_round2_tweak -#define grammar_optimize_round3 grammar_optimize_round3_tweak -#define grammar_optimize_round4 grammar_optimize_round4_tweak -#define grammar_optimize_shortcut_logical_evaluation grammar_optimize_shortcut_logical_evaluation_tweak -// line removed for fpoptimizer.c: #include "fpoptimizer_grammar.h" -#undef grammar_optimize_abslogical -#undef grammar_optimize_ignore_if_sideeffects -#undef grammar_optimize_nonshortcut_logical_evaluation -#undef grammar_optimize_round1 -#undef grammar_optimize_round2 -#undef grammar_optimize_round3 -#undef grammar_optimize_round4 -#undef grammar_optimize_shortcut_logical_evaluation - -using namespace FPoptimizer_Grammar; -using namespace FUNCTIONPARSERTYPES; - -namespace -{ - const struct ParamSpec_List - { - ParamSpec_ParamHolder plist_p[33]; -#define P(n) (n) - ParamSpec_NumConstant plist_n[17]; -#define N(n) (n+33) - ParamSpec_SubFunction plist_s[422]; -#define S(n) (n+33+17) - } /*PACKED_GRAMMAR_ATTRIBUTE*/ plist = - { - { /* plist_p - ParamSpec_ParamHolder[33] */ - /* 0 */ {0, Sign_Negative | Constness_Const, 0x0}, /* %@N */ - /* 1 */ {0, Constness_Const, 0x0}, /* % */ - /* 2 */ {0, Sign_Positive | Constness_Const, 0x0}, /* %@P */ - /* 3 */ {0, Constness_Const, 0x1}, /* % */ - /* 4 */ {0, Value_IsInteger | Sign_Positive | Constness_Const, 0x0}, /* %@I@P */ - /* 5 */ {0, Oneness_NotOne | Constness_Const, 0x1}, /* %@M */ - /* 6 */ {0, Oneness_NotOne | Constness_Const, 0x0}, /* %@M */ - /* 7 */ {0, Oneness_One | Constness_Const, 0x0}, /* %@1 */ - /* 8 */ {0, Value_Logical | Constness_Const, 0x0}, /* %@L */ - /* 9 */ {1, Constness_Const, 0x0}, /* & */ - /* 10 */ {1, Value_EvenInt | Constness_Const, 0x0}, /* &@E */ - /* 11 */ {1, Oneness_NotOne | Constness_Const, 0x0}, /* &@M */ - /* 12 */ {1, Value_IsInteger | Constness_Const, 0x0}, /* &@I */ - /* 13 */ {1, Sign_Positive | Constness_Const, 0x0}, /* &@P */ - /* 14 */ {2, 0, 0x0}, /* x */ - /* 15 */ {2, 0, 0x4}, /* x */ - /* 16 */ {2, Value_IsInteger, 0x0}, /* x@I */ - /* 17 */ {2, Sign_Positive, 0x0}, /* x@P */ - /* 18 */ {2, Sign_NoIdea, 0x0}, /* x */ - /* 19 */ {2, Value_Logical, 0x0}, /* x@L */ - /* 20 */ {3, Sign_NoIdea, 0x0}, /* y */ - /* 21 */ {3, 0, 0x0}, /* y */ - /* 22 */ {3, Value_Logical, 0x0}, /* y@L */ - /* 23 */ {3, 0, 0x8}, /* y */ - /* 24 */ {3, Value_OddInt, 0x0}, /* y@O */ - /* 25 */ {3, Value_NonInteger, 0x0}, /* y@F */ - /* 26 */ {3, Value_EvenInt, 0x0}, /* y@E */ - /* 27 */ {3, Sign_Positive, 0x0}, /* y@P */ - /* 28 */ {4, 0, 0x0}, /* z */ - /* 29 */ {4, 0, 0x16}, /* z */ - /* 30 */ {4, Value_IsInteger, 0x0}, /* z@I */ - /* 31 */ {5, 0, 0x0}, /* a */ - /* 32 */ {6, 0, 0x0}, /* b */ - }, - - { /* plist_n - ParamSpec_NumConstant[17] */ - /* 0 */ {-2}, /* -2 */ - /* 1 */ {-CONSTANT_PIHALF}, /* -1.57079632679 */ - /* 2 */ {-1}, /* -1 */ - /* 3 */ {-0.5}, /* -0.5 */ - /* 4 */ {0}, /* 0 */ - /* 5 */ {CONSTANT_RD}, /* 0.0174532925199 */ - /* 6 */ {CONSTANT_EI}, /* 0.367879441171 */ - /* 7 */ {CONSTANT_L10I}, /* 0.434294481903 */ - /* 8 */ {0.5}, /* 0.5 */ - /* 9 */ {CONSTANT_L2}, /* 0.69314718056 */ - /* 10 */ {1}, /* 1 */ - /* 11 */ {CONSTANT_L2I}, /* 1.44269504089 */ - /* 12 */ {CONSTANT_PIHALF}, /* 1.57079632679 */ - /* 13 */ {2}, /* 2 */ - /* 14 */ {CONSTANT_L10}, /* 2.30258509299 */ - /* 15 */ {CONSTANT_E}, /* 2.71828182846 */ - /* 16 */ {CONSTANT_DR}, /* 57.2957795131 */ - }, - - { /* plist_s - ParamSpec_SubFunction[422] */ - /* 0 */ {{1,P1(P(14)) , cAbs ,PositionalParams,0}, 0, 0x0}, /* (cAbs [x]) */ - /* 1 */ {{1,P1(P(21)) , cAbs ,PositionalParams,0}, 0, 0x0}, /* (cAbs [y]) */ - /* 2 */ {{1,P1(S(283)) , cAbs ,PositionalParams,0}, 0, 0x0}, /* (cAbs [(cMul {x y})]) */ - /* 3 */ {{1,P1(P(14)) , cAcos ,PositionalParams,0}, 0, 0x0}, /* (cAcos [x]) */ - /* 4 */ {{1,P1(P(14)) , cAcosh ,PositionalParams,0}, 0, 0x0}, /* (cAcosh [x]) */ - /* 5 */ {{1,P1(P(14)) , cAsin ,PositionalParams,0}, 0, 0x0}, /* (cAsin [x]) */ - /* 6 */ {{1,P1(P(14)) , cAsinh ,PositionalParams,0}, 0, 0x0}, /* (cAsinh [x]) */ - /* 7 */ {{1,P1(S(242)) , cAsinh ,PositionalParams,0}, 0, 0x0}, /* (cAsinh [(cAdd <1>)]) */ - /* 8 */ {{1,P1(P(14)) , cAtan ,PositionalParams,0}, 0, 0x0}, /* (cAtan [x]) */ - /* 9 */ {{2,P2(P(14),P(21)) , cAtan2 ,PositionalParams,0}, 0, 0x0}, /* (cAtan2 [x y]) */ - /* 10 */ {{2,P2(P(14),S(109)) , cAtan2 ,PositionalParams,0}, 0, 0x0}, /* (cAtan2 [x (cPow [y -%])]) */ - /* 11 */ {{1,P1(P(14)) , cAtanh ,PositionalParams,0}, 0, 0x0}, /* (cAtanh [x]) */ - /* 12 */ {{1,P1(P(14)) , cCeil ,PositionalParams,0}, 0, 0x4}, /* (cCeil [x]) */ - /* 13 */ {{1,P1(S(331)) , cCeil ,PositionalParams,0}, 0, 0x0}, /* (cCeil [(cMul <1>)]) */ - /* 14 */ {{1,P1(P(14)) , cCos ,PositionalParams,0}, 0, 0x0}, /* (cCos [x]) */ - /* 15 */ {{1,P1(P(14)) , cCos ,PositionalParams,0}, 0, 0x4}, /* (cCos [x]) */ - /* 16 */ {{1,P1(P(21)) , cCos ,PositionalParams,0}, 0, 0x0}, /* (cCos [y]) */ - /* 17 */ {{1,P1(S(215)) , cCos ,PositionalParams,0}, 0, 0x0}, /* (cCos [(cAdd {x y})]) */ - /* 18 */ {{1,P1(S(221)) , cCos ,PositionalParams,0}, 0, 0x0}, /* (cCos [(cAdd {x (cMul {-1 y})})]) */ - /* 19 */ {{1,P1(S(242)) , cCos ,PositionalParams,0}, 0, 0x0}, /* (cCos [(cAdd <1>)]) */ - /* 20 */ {{1,P1(S(301)) , cCos ,PositionalParams,0}, 0, 0x0}, /* (cCos [(cMul {-% x})]) */ - /* 21 */ {{1,P1(S(358)) , cCos ,PositionalParams,0}, 0, 0x0}, /* (cCos [(cMul -% <1>)]) */ - /* 22 */ {{1,P1(P(14)) , cCosh ,PositionalParams,0}, 0, 0x4}, /* (cCosh [x]) */ - /* 23 */ {{1,P1(P(14)) , cCosh ,PositionalParams,0}, 0, 0x0}, /* (cCosh [x]) */ - /* 24 */ {{1,P1(S(50)) , cCosh ,PositionalParams,0}, 0, 0x0}, /* (cCosh [(cLog [(cPow [& x])])]) */ - /* 25 */ {{1,P1(S(295)) , cCosh ,PositionalParams,0}, 0, 0x0}, /* (cCosh [(cMul {x LOG( & )})]) */ - /* 26 */ {{1,P1(S(301)) , cCosh ,PositionalParams,0}, 0, 0x0}, /* (cCosh [(cMul {-% x})]) */ - /* 27 */ {{1,P1(P(14)) , cCot ,PositionalParams,0}, 0, 0x0}, /* (cCot [x]) */ - /* 28 */ {{1,P1(P(14)) , cCsc ,PositionalParams,0}, 0, 0x0}, /* (cCsc [x]) */ - /* 29 */ {{1,P1(P(14)) , cFloor ,PositionalParams,0}, 0, 0x4}, /* (cFloor [x]) */ - /* 30 */ {{1,P1(S(331)) , cFloor ,PositionalParams,0}, 0, 0x0}, /* (cFloor [(cMul <1>)]) */ - /* 31 */ {{3,P3(P(14),N(10),S(400)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x 1 (cNotNot [y])]) */ - /* 32 */ {{3,P3(P(14),P(21),P(28)) , cIf ,PositionalParams,0}, 0, 0x4}, /* (cIf [x y z]) */ - /* 33 */ {{3,P3(P(14),P(21),P(28)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x y z]) */ - /* 34 */ {{3,P3(P(14),P(8),S(376)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x %@L (cNot [y])]) */ - /* 35 */ {{3,P3(P(14),P(21),S(374)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x y (cNot [%])]) */ - /* 36 */ {{3,P3(P(14),P(31),P(32)) , cIf ,PositionalParams,0}, 0, 0x4}, /* (cIf [x a b]) */ - /* 37 */ {{3,P3(P(14),S(374),P(21)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cNot [%]) y]) */ - /* 38 */ {{3,P3(P(14),S(376),P(8)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cNot [y]) %@L]) */ - /* 39 */ {{3,P3(P(14),S(58),S(59)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cMax [y a]) (cMax [z b])]) */ - /* 40 */ {{3,P3(P(14),S(61),S(62)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cMin [y a]) (cMin [z b])]) */ - /* 41 */ {{3,P3(P(14),S(222),S(224)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cAdd {y a}) (cAdd {z b})]) */ - /* 42 */ {{3,P3(P(14),S(288),S(289)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cMul {y a}) (cMul {z b})]) */ - /* 43 */ {{3,P3(P(14),S(386),S(387)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cAnd {y a}) (cAnd {z b})]) */ - /* 44 */ {{3,P3(P(14),S(393),S(394)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cOr {y a}) (cOr {z b})]) */ - /* 45 */ {{3,P3(P(14),S(400),N(4)) , cIf ,PositionalParams,0}, 0, 0x0}, /* (cIf [x (cNotNot [y]) 0]) */ - /* 46 */ {{1,P1(S(242)) , cInt ,PositionalParams,0}, 0, 0x0}, /* (cInt [(cAdd <1>)]) */ - /* 47 */ {{1,P1(P(14)) , cLog ,PositionalParams,0}, 0, 0x0}, /* (cLog [x]) */ - /* 48 */ {{1,P1(P(21)) , cLog ,PositionalParams,0}, 0, 0x0}, /* (cLog [y]) */ - /* 49 */ {{1,P1(P(28)) , cLog ,PositionalParams,0}, 0, 0x0}, /* (cLog [z]) */ - /* 50 */ {{1,P1(S(83)) , cLog ,PositionalParams,0}, 0, 0x0}, /* (cLog [(cPow [& x])]) */ - /* 51 */ {{1,P1(S(283)) , cLog ,PositionalParams,0}, 0, 0x0}, /* (cLog [(cMul {x y})]) */ - /* 52 */ {{1,P1(S(331)) , cLog ,PositionalParams,0}, 0, 0x0}, /* (cLog [(cMul <1>)]) */ - /* 53 */ {{1,P1(P(1)) , cLog ,GroupFunction ,0}, Constness_Const, 0x0}, /* LOG( % ) */ - /* 54 */ {{1,P1(P(9)) , cLog ,GroupFunction ,0}, Constness_Const, 0x0}, /* LOG( & ) */ - /* 55 */ {{1,P1(P(14)) , cLog10 ,PositionalParams,0}, 0, 0x0}, /* (cLog10 [x]) */ - /* 56 */ {{1,P1(P(14)) , cLog2 ,PositionalParams,0}, 0, 0x0}, /* (cLog2 [x]) */ - /* 57 */ {{2,P2(P(14),P(21)) , cMax ,PositionalParams,0}, 0, 0x0}, /* (cMax [x y]) */ - /* 58 */ {{2,P2(P(21),P(31)) , cMax ,PositionalParams,0}, 0, 0x0}, /* (cMax [y a]) */ - /* 59 */ {{2,P2(P(28),P(32)) , cMax ,PositionalParams,0}, 0, 0x0}, /* (cMax [z b]) */ - /* 60 */ {{2,P2(P(14),P(21)) , cMin ,PositionalParams,0}, 0, 0x0}, /* (cMin [x y]) */ - /* 61 */ {{2,P2(P(21),P(31)) , cMin ,PositionalParams,0}, 0, 0x0}, /* (cMin [y a]) */ - /* 62 */ {{2,P2(P(28),P(32)) , cMin ,PositionalParams,0}, 0, 0x0}, /* (cMin [z b]) */ - /* 63 */ {{2,P2(P(1),N(10)) , cMin ,GroupFunction ,0}, Constness_Const, 0x0}, /* MIN( % 1 ) */ - /* 64 */ {{2,P2(P(1),P(9)) , cMin ,GroupFunction ,0}, Constness_Const, 0x0}, /* MIN( % & ) */ - /* 65 */ {{2,P2(N(6),P(14)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [0.367879441171 x]) */ - /* 66 */ {{2,P2(N(6),P(14)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [0.367879441171 x]) */ - /* 67 */ {{2,P2(N(15),P(14)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [2.71828182846 x]) */ - /* 68 */ {{2,P2(N(15),P(14)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [2.71828182846 x]) */ - /* 69 */ {{2,P2(N(6),S(6)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [0.367879441171 (cAsinh [x])]) */ - /* 70 */ {{2,P2(N(15),S(6)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [2.71828182846 (cAsinh [x])]) */ - /* 71 */ {{2,P2(N(6),S(7)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [0.367879441171 (cAsinh [(cAdd <1>)])]) */ - /* 72 */ {{2,P2(N(15),S(7)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [2.71828182846 (cAsinh [(cAdd <1>)])]) */ - /* 73 */ {{2,P2(N(15),S(332)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [2.71828182846 (cMul <2>)]) */ - /* 74 */ {{2,P2(P(1),P(14)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [% x]) */ - /* 75 */ {{2,P2(P(1),P(14)) , cPow ,PositionalParams,0}, 0, 0x1}, /* (cPow [% x]) */ - /* 76 */ {{2,P2(P(1),P(21)) , cPow ,PositionalParams,0}, 0, 0x1}, /* (cPow [% y]) */ - /* 77 */ {{2,P2(P(14),P(1)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x %]) */ - /* 78 */ {{2,P2(P(14),P(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x %@P]) */ - /* 79 */ {{2,P2(P(21),P(13)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [y &@P]) */ - /* 80 */ {{2,P2(P(21),P(9)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [y &]) */ - /* 81 */ {{2,P2(P(2),P(14)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [%@P x]) */ - /* 82 */ {{2,P2(P(9),P(14)) , cPow ,PositionalParams,0}, 0, 0x6}, /* (cPow [& x]) */ - /* 83 */ {{2,P2(P(9),P(14)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [& x]) */ - /* 84 */ {{2,P2(P(9),P(21)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [& y]) */ - /* 85 */ {{2,P2(P(9),S(223)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [& (cAdd {y (cMul {z (cLog [x]) /LOG( & )})})]) */ - /* 86 */ {{2,P2(P(14),P(4)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x %@I@P]) */ - /* 87 */ {{2,P2(P(14),P(12)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x &@I]) */ - /* 88 */ {{2,P2(P(1),P(21)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [% y]) */ - /* 89 */ {{2,P2(P(14),N(13)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x 2]) */ - /* 90 */ {{2,P2(P(14),P(24)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x y@O]) */ - /* 91 */ {{2,P2(P(14),P(25)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x y@F]) */ - /* 92 */ {{2,P2(P(17),P(21)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x@P y]) */ - /* 93 */ {{2,P2(P(18),P(21)) , cPow ,PositionalParams,0}, Sign_Positive, 0x0}, /* (cPow [x y])@P */ - /* 94 */ {{2,P2(P(14),P(21)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [x y]) */ - /* 95 */ {{2,P2(P(14),P(28)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x z]) */ - /* 96 */ {{2,P2(P(17),P(28)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x@P z]) */ - /* 97 */ {{2,P2(P(14),S(63)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x MIN( % 1 )]) */ - /* 98 */ {{2,P2(P(14),S(64)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x MIN( % & )]) */ - /* 99 */ {{2,P2(P(14),S(208)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x (cAdd {1 -MIN( % 1 )})]) */ - /* 100 */ {{2,P2(P(14),S(216)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x (cAdd {y z})]) */ - /* 101 */ {{2,P2(P(14),S(218)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x (cAdd {% -MIN( % 1 )})]) */ - /* 102 */ {{2,P2(P(14),S(219)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x (cAdd {% -MIN( % & )})]) */ - /* 103 */ {{2,P2(P(14),S(220)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x (cAdd {& -MIN( % & )})]) */ - /* 104 */ {{2,P2(P(21),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [y -1]) */ - /* 105 */ {{2,P2(P(14),P(21)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x y]) */ - /* 106 */ {{2,P2(P(1),S(242)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [% (cAdd <1>)]) */ - /* 107 */ {{2,P2(P(14),S(53)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [x LOG( % )]) */ - /* 108 */ {{2,P2(P(20),P(0)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [y %@N]) */ - /* 109 */ {{2,P2(P(21),S(194)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [y -%]) */ - /* 110 */ {{2,P2(P(28),S(242)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [z (cAdd <1>)]) */ - /* 111 */ {{2,P2(S(14),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cCos [x]) -1]) */ - /* 112 */ {{2,P2(S(14),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cCos [x]) -1]) */ - /* 113 */ {{2,P2(S(20),N(2)) , cPow ,PositionalParams,0}, 0, 0x5}, /* (cPow [(cCos [(cMul {-% x})]) -1]) */ - /* 114 */ {{2,P2(S(21),N(2)) , cPow ,PositionalParams,0}, 0, 0x1}, /* (cPow [(cCos [(cMul -% <1>)]) -1]) */ - /* 115 */ {{2,P2(S(23),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cCosh [x]) -1]) */ - /* 116 */ {{2,P2(S(23),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cCosh [x]) -1]) */ - /* 117 */ {{2,P2(S(14),N(13)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cCos [x]) 2]) */ - /* 118 */ {{2,P2(S(14),N(13)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cCos [x]) 2]) */ - /* 119 */ {{2,P2(S(23),P(1)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cCosh [x]) %]) */ - /* 120 */ {{2,P2(S(23),S(259)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cCosh [x]) ADD( % 1 )]) */ - /* 121 */ {{2,P2(S(26),N(2)) , cPow ,PositionalParams,0}, 0, 0x5}, /* (cPow [(cCosh [(cMul {-% x})]) -1]) */ - /* 122 */ {{2,P2(S(47),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cLog [x]) -1]) */ - /* 123 */ {{2,P2(S(49),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cLog [z]) -1]) */ - /* 124 */ {{2,P2(S(55),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cLog10 [x]) -1]) */ - /* 125 */ {{2,P2(S(56),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cLog2 [x]) -1]) */ - /* 126 */ {{2,P2(S(77),S(417)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cPow [x %]) /%]) */ - /* 127 */ {{2,P2(S(77),S(421)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cPow [x %]) /MIN( % & )]) */ - /* 128 */ {{2,P2(S(80),S(421)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cPow [y &]) /MIN( % & )]) */ - /* 129 */ {{2,P2(S(158),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cSin [x]) -1]) */ - /* 130 */ {{2,P2(S(170),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cSinh [x]) -1]) */ - /* 131 */ {{2,P2(S(177),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cTan [x]) -1]) */ - /* 132 */ {{2,P2(S(177),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cTan [x]) -1]) */ - /* 133 */ {{2,P2(S(186),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cTanh [x]) -1]) */ - /* 134 */ {{2,P2(S(186),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cTanh [x]) -1]) */ - /* 135 */ {{2,P2(S(189),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cTanh [(cMul {x LOG( % ) 0.5})]) -1]) */ - /* 136 */ {{2,P2(S(199),N(2)) , cPow ,PositionalParams,0}, 0, 0x5}, /* (cPow [(cAdd {-1 (cPow [% x])}) -1]) */ - /* 137 */ {{2,P2(S(201),N(2)) , cPow ,PositionalParams,0}, 0, 0x5}, /* (cPow [(cAdd {1 (cPow [% x])}) -1]) */ - /* 138 */ {{2,P2(S(332),N(2)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cMul <2>) -1]) */ - /* 139 */ {{2,P2(S(346),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cMul x <2>) -1]) */ - /* 140 */ {{2,P2(S(158),N(13)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cSin [x]) 2]) */ - /* 141 */ {{2,P2(S(158),N(13)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cSin [x]) 2]) */ - /* 142 */ {{2,P2(S(205),N(3)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cAdd {1 (cPow [x 2])}) -0.5]) */ - /* 143 */ {{2,P2(S(205),N(8)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cAdd {1 (cPow [x 2])}) 0.5]) */ - /* 144 */ {{2,P2(S(207),N(3)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cAdd {1 (cPow [(cAdd <1>) 2])}) -0.5]) */ - /* 145 */ {{2,P2(S(207),N(8)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cAdd {1 (cPow [(cAdd <1>) 2])}) 0.5]) */ - /* 146 */ {{2,P2(S(209),N(2)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cAdd {1 (cMul {-1 x})}) -1]) */ - /* 147 */ {{2,P2(S(203),N(8)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cAdd {-1 (cPow [x 2])}) 0.5]) */ - /* 148 */ {{2,P2(S(226),N(8)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cAdd {(cPow [x 2]) -1}) 0.5]) */ - /* 149 */ {{2,P2(S(236),N(8)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cAdd {(cPow [x 2]) 1}) 0.5]) */ - /* 150 */ {{2,P2(S(237),N(8)) , cPow ,PositionalParams,0}, 0, 0x4}, /* (cPow [(cAdd {(cMul {(cPow [x 2]) -1}) 1}) 0.5]) */ - /* 151 */ {{2,P2(S(242),N(13)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cAdd <1>) 2]) */ - /* 152 */ {{2,P2(S(331),P(9)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [(cMul <1>) &]) */ - /* 153 */ {{2,P2(S(418),P(14)) , cPow ,PositionalParams,0}, 0, 0x0}, /* (cPow [/& x]) */ - /* 154 */ {{2,P2(S(418),P(14)) , cPow ,PositionalParams,0}, 0, 0x6}, /* (cPow [/& x]) */ - /* 155 */ {{2,P2(P(1),P(9)) , cPow ,GroupFunction ,0}, Constness_Const, 0x0}, /* POW( % & ) */ - /* 156 */ {{2,P2(P(9),S(417)) , cPow ,GroupFunction ,0}, Constness_Const, 0x0}, /* POW( & /% ) */ - /* 157 */ {{1,P1(P(14)) , cSec ,PositionalParams,0}, 0, 0x0}, /* (cSec [x]) */ - /* 158 */ {{1,P1(P(14)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [x]) */ - /* 159 */ {{1,P1(P(14)) , cSin ,PositionalParams,0}, 0, 0x4}, /* (cSin [x]) */ - /* 160 */ {{1,P1(P(21)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [y]) */ - /* 161 */ {{1,P1(S(215)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [(cAdd {x y})]) */ - /* 162 */ {{1,P1(S(221)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [(cAdd {x (cMul {-1 y})})]) */ - /* 163 */ {{1,P1(S(242)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [(cAdd <1>)]) */ - /* 164 */ {{1,P1(S(279)) , cSin ,PositionalParams,0}, 0, 0x5}, /* (cSin [(cMul {% x})]) */ - /* 165 */ {{1,P1(S(331)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [(cMul <1>)]) */ - /* 166 */ {{1,P1(S(335)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [(cMul %@N <1>)]) */ - /* 167 */ {{1,P1(S(339)) , cSin ,PositionalParams,0}, 0, 0x1}, /* (cSin [(cMul % <1>)]) */ - /* 168 */ {{1,P1(S(358)) , cSin ,PositionalParams,0}, 0, 0x0}, /* (cSin [(cMul -% <1>)]) */ - /* 169 */ {{1,P1(P(14)) , cSinh ,PositionalParams,0}, 0, 0x4}, /* (cSinh [x]) */ - /* 170 */ {{1,P1(P(14)) , cSinh ,PositionalParams,0}, 0, 0x0}, /* (cSinh [x]) */ - /* 171 */ {{1,P1(S(50)) , cSinh ,PositionalParams,0}, 0, 0x0}, /* (cSinh [(cLog [(cPow [& x])])]) */ - /* 172 */ {{1,P1(S(279)) , cSinh ,PositionalParams,0}, 0, 0x5}, /* (cSinh [(cMul {% x})]) */ - /* 173 */ {{1,P1(S(295)) , cSinh ,PositionalParams,0}, 0, 0x0}, /* (cSinh [(cMul {x LOG( & )})]) */ - /* 174 */ {{1,P1(S(331)) , cSinh ,PositionalParams,0}, 0, 0x0}, /* (cSinh [(cMul <1>)]) */ - /* 175 */ {{1,P1(S(335)) , cSinh ,PositionalParams,0}, 0, 0x0}, /* (cSinh [(cMul %@N <1>)]) */ - /* 176 */ {{1,P1(S(358)) , cSinh ,PositionalParams,0}, 0, 0x0}, /* (cSinh [(cMul -% <1>)]) */ - /* 177 */ {{1,P1(P(14)) , cTan ,PositionalParams,0}, 0, 0x0}, /* (cTan [x]) */ - /* 178 */ {{1,P1(P(14)) , cTan ,PositionalParams,0}, 0, 0x4}, /* (cTan [x]) */ - /* 179 */ {{1,P1(S(210)) , cTan ,PositionalParams,0}, 0, 0x4}, /* (cTan [(cAdd {1.57079632679 (cMul {-1 x})})]) */ - /* 180 */ {{1,P1(S(213)) , cTan ,PositionalParams,0}, 0, 0x0}, /* (cTan [(cAdd {1.57079632679 (cMul -1 <1>)})]) */ - /* 181 */ {{1,P1(S(279)) , cTan ,PositionalParams,0}, 0, 0x0}, /* (cTan [(cMul {% x})]) */ - /* 182 */ {{1,P1(S(331)) , cTan ,PositionalParams,0}, 0, 0x0}, /* (cTan [(cMul <1>)]) */ - /* 183 */ {{1,P1(S(339)) , cTan ,PositionalParams,0}, 0, 0x0}, /* (cTan [(cMul % <1>)]) */ - /* 184 */ {{1,P1(S(335)) , cTan ,PositionalParams,0}, 0, 0x0}, /* (cTan [(cMul %@N <1>)]) */ - /* 185 */ {{1,P1(S(358)) , cTan ,PositionalParams,0}, 0, 0x0}, /* (cTan [(cMul -% <1>)]) */ - /* 186 */ {{1,P1(P(14)) , cTanh ,PositionalParams,0}, 0, 0x0}, /* (cTanh [x]) */ - /* 187 */ {{1,P1(P(14)) , cTanh ,PositionalParams,0}, 0, 0x4}, /* (cTanh [x]) */ - /* 188 */ {{1,P1(S(279)) , cTanh ,PositionalParams,0}, 0, 0x0}, /* (cTanh [(cMul {% x})]) */ - /* 189 */ {{1,P1(S(286)) , cTanh ,PositionalParams,0}, 0, 0x0}, /* (cTanh [(cMul {x LOG( % ) 0.5})]) */ - /* 190 */ {{1,P1(S(331)) , cTanh ,PositionalParams,0}, 0, 0x0}, /* (cTanh [(cMul <1>)]) */ - /* 191 */ {{1,P1(S(335)) , cTanh ,PositionalParams,0}, 0, 0x0}, /* (cTanh [(cMul %@N <1>)]) */ - /* 192 */ {{1,P1(S(358)) , cTanh ,PositionalParams,0}, 0, 0x0}, /* (cTanh [(cMul -% <1>)]) */ - /* 193 */ {{1,P1(P(14)) , cTrunc ,PositionalParams,0}, 0, 0x0}, /* (cTrunc [x]) */ - /* 194 */ {{1,P1(P(1)) , cNeg ,GroupFunction ,0}, Constness_Const, 0x0}, /* -% */ - /* 195 */ {{1,P1(P(1)) , cNeg ,GroupFunction ,0}, Constness_Const, 0x1}, /* -% */ - /* 196 */ {{1,P1(S(63)) , cNeg ,GroupFunction ,0}, Constness_Const, 0x0}, /* -MIN( % 1 ) */ - /* 197 */ {{1,P1(S(64)) , cNeg ,GroupFunction ,0}, Constness_Const, 0x0}, /* -MIN( % & ) */ - /* 198 */ {{2,P2(N(2),S(74)) , cAdd ,SelectedParams ,0}, 0, 0x5}, /* (cAdd {-1 (cPow [% x])}) */ - /* 199 */ {{2,P2(N(2),S(74)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {-1 (cPow [% x])}) */ - /* 200 */ {{2,P2(N(10),P(14)) , cAdd ,SelectedParams ,0}, 0, 0x4}, /* (cAdd {1 x}) */ - /* 201 */ {{2,P2(N(10),S(74)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1 (cPow [% x])}) */ - /* 202 */ {{2,P2(N(10),S(74)) , cAdd ,SelectedParams ,0}, 0, 0x5}, /* (cAdd {1 (cPow [% x])}) */ - /* 203 */ {{2,P2(N(2),S(89)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {-1 (cPow [x 2])}) */ - /* 204 */ {{2,P2(N(2),S(96)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {-1 (cPow [x@P z])}) */ - /* 205 */ {{2,P2(N(10),S(89)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1 (cPow [x 2])}) */ - /* 206 */ {{2,P2(N(10),S(96)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1 (cPow [x@P z])}) */ - /* 207 */ {{2,P2(N(10),S(151)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1 (cPow [(cAdd <1>) 2])}) */ - /* 208 */ {{2,P2(N(10),S(196)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1 -MIN( % 1 )}) */ - /* 209 */ {{2,P2(N(10),S(261)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1 (cMul {-1 x})}) */ - /* 210 */ {{2,P2(N(12),S(261)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1.57079632679 (cMul {-1 x})}) */ - /* 211 */ {{2,P2(N(10),S(303)) , cAdd ,SelectedParams ,0}, 0, 0x1}, /* (cAdd {1 (cMul {(cLog [x]) /%})}) */ - /* 212 */ {{2,P2(N(10),S(334)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1 (cMul -1 <2>)}) */ - /* 213 */ {{2,P2(N(12),S(333)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1.57079632679 (cMul -1 <1>)}) */ - /* 214 */ {{2,P2(N(12),S(335)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {1.57079632679 (cMul %@N <1>)}) */ - /* 215 */ {{2,P2(P(14),P(21)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {x y}) */ - /* 216 */ {{2,P2(P(21),P(28)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {y z}) */ - /* 217 */ {{2,P2(P(7),S(95)) , cAdd ,SelectedParams ,0}, 0, 0x4}, /* (cAdd {%@1 (cPow [x z])}) */ - /* 218 */ {{2,P2(P(1),S(196)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {% -MIN( % 1 )}) */ - /* 219 */ {{2,P2(P(1),S(197)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {% -MIN( % & )}) */ - /* 220 */ {{2,P2(P(9),S(197)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {& -MIN( % & )}) */ - /* 221 */ {{2,P2(P(14),S(262)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {x (cMul {-1 y})}) */ - /* 222 */ {{2,P2(P(21),P(31)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {y a}) */ - /* 223 */ {{2,P2(P(21),S(290)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {y (cMul {z (cLog [x]) /LOG( & )})}) */ - /* 224 */ {{2,P2(P(28),P(32)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {z b}) */ - /* 225 */ {{2,P2(S(47),P(1)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cLog [x]) %}) */ - /* 226 */ {{2,P2(S(89),N(2)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cPow [x 2]) -1}) */ - /* 227 */ {{2,P2(S(280),P(3)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul {% (cPow [x@P z])})@D1 %@D1}) */ - /* 228 */ {{2,P2(S(47),P(9)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cLog [x]) &}) */ - /* 229 */ {{2,P2(S(84),S(85)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cPow [& y]) (cPow [& (cAdd {y (cMul {z (cLog [x]) /LOG( & )})})])}) */ - /* 230 */ {{2,P2(S(147),P(15)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cPow [(cAdd {-1 (cPow [x 2])}) 0.5])@D4 x@D4}) */ - /* 231 */ {{2,P2(S(280),S(195)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul {% (cPow [x@P z])})@D1 -%@D1}) */ - /* 232 */ {{2,P2(S(298),S(85)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul {(cPow [& y]) -1}) (cPow [& (cAdd {y (cMul {z (cLog [x]) /LOG( & )})})])}) */ - /* 233 */ {{2,P2(S(300),S(100)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul {(cPow [x y]) %}) (cPow [x (cAdd {y z})])}) */ - /* 234 */ {{2,P2(S(316),S(52)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul {LOG( % ) y}) (cLog [(cMul <1>)])}) */ - /* 235 */ {{2,P2(S(52),S(53)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cLog [(cMul <1>)]) LOG( % )}) */ - /* 236 */ {{2,P2(S(89),N(10)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cPow [x 2]) 1}) */ - /* 237 */ {{2,P2(S(317),N(10)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul {(cPow [x 2]) -1}) 1}) */ - /* 238 */ {{2,P2(S(341),S(293)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul % & <1>) (cMul {& (cAdd <2>)})}) */ - /* 239 */ {{2,P2(S(362),S(294)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {MUL( % & ) (cMul {& (cAdd <1>)})}) */ - /* 240 */ {{2,P2(S(354),S(353)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul (cPow [x (cAdd {% -MIN( % 1 )})]) <1>) (cMul (cPow [x (cAdd {1 -MIN( % 1 )})]) <2>)}) */ - /* 241 */ {{2,P2(S(355),S(356)) , cAdd ,SelectedParams ,0}, 0, 0x0}, /* (cAdd {(cMul (cPow [x (cAdd {% -MIN( % & )})]) <1>) (cMul (cPow [x (cAdd {& -MIN( % & )})]) <2>)}) */ - /* 242 */ {{0,0 , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd <1>) */ - /* 243 */ {{0,0 , cAdd ,AnyParams ,2}, 0, 0x0}, /* (cAdd <2>) */ - /* 244 */ {{0,0 , cAdd ,AnyParams ,1}, Sign_Positive, 0x0}, /* (cAdd <1>)@P */ - /* 245 */ {{1,P1(N(1)) , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd -1.57079632679 <1>) */ - /* 246 */ {{1,P1(N(8)) , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd 0.5 <1>) */ - /* 247 */ {{1,P1(P(6)) , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd %@M <1>) */ - /* 248 */ {{1,P1(P(1)) , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd % <1>) */ - /* 249 */ {{1,P1(P(11)) , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd &@M <1>) */ - /* 250 */ {{1,P1(P(9)) , cAdd ,AnyParams ,2}, 0, 0x0}, /* (cAdd & <2>) */ - /* 251 */ {{1,P1(P(14)) , cAdd ,AnyParams ,1}, 0, 0x4}, /* (cAdd x <1>) */ - /* 252 */ {{1,P1(P(14)) , cAdd ,AnyParams ,2}, 0, 0x4}, /* (cAdd x <2>) */ - /* 253 */ {{1,P1(P(14)) , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd x <1>) */ - /* 254 */ {{2,P2(P(9),S(194)) , cAdd ,AnyParams ,2}, 0, 0x0}, /* (cAdd & -% <2>) */ - /* 255 */ {{1,P1(S(123)) , cAdd ,AnyParams ,1}, 0, 0x16}, /* (cAdd (cPow [(cLog [z]) -1]) <1>) */ - /* 256 */ {{1,P1(S(334)) , cAdd ,AnyParams ,1}, 0, 0x0}, /* (cAdd (cMul -1 <2>) <1>) */ - /* 257 */ {{1,P1(S(338)) , cAdd ,AnyParams ,2}, 0, 0x0}, /* (cAdd (cMul %@M <1>) <2>) */ - /* 258 */ {{1,P1(S(357)) , cAdd ,AnyParams ,1}, 0, 0x16}, /* (cAdd (cMul (cPow [(cLog [z]) -1]) <2>) <1>) */ - /* 259 */ {{2,P2(P(1),N(10)) , cAdd ,GroupFunction ,0}, Constness_Const, 0x0}, /* ADD( % 1 ) */ - /* 260 */ {{2,P2(P(9),S(194)) , cAdd ,GroupFunction ,0}, Constness_Const, 0x0}, /* ADD( & -% ) */ - /* 261 */ {{2,P2(N(2),P(14)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 x}) */ - /* 262 */ {{2,P2(N(2),P(21)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 y}) */ - /* 263 */ {{2,P2(N(2),S(13)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cCeil [(cMul <1>)])}) */ - /* 264 */ {{2,P2(N(2),S(18)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cCos [(cAdd {x (cMul {-1 y})})])}) */ - /* 265 */ {{2,P2(N(2),S(19)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cCos [(cAdd <1>)])}) */ - /* 266 */ {{2,P2(N(2),S(23)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cCosh [x])}) */ - /* 267 */ {{2,P2(N(2),S(30)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cFloor [(cMul <1>)])}) */ - /* 268 */ {{2,P2(N(2),S(83)) , cMul ,SelectedParams ,0}, 0, 0x6}, /* (cMul {-1 (cPow [& x])}) */ - /* 269 */ {{2,P2(N(2),S(118)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cPow [(cCos [x]) 2])}) */ - /* 270 */ {{2,P2(N(2),S(141)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cPow [(cSin [x]) 2])}) */ - /* 271 */ {{2,P2(N(2),S(153)) , cMul ,SelectedParams ,0}, 0, 0x6}, /* (cMul {-1 (cPow [/& x])}) */ - /* 272 */ {{2,P2(N(2),S(165)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cSin [(cMul <1>)])}) */ - /* 273 */ {{2,P2(N(2),S(170)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cSinh [x])}) */ - /* 274 */ {{2,P2(N(2),S(174)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cSinh [(cMul <1>)])}) */ - /* 275 */ {{2,P2(N(2),S(182)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cTan [(cMul <1>)])}) */ - /* 276 */ {{2,P2(N(2),S(190)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-1 (cTanh [(cMul <1>)])}) */ - /* 277 */ {{2,P2(N(15),S(110)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {2.71828182846 (cPow [z (cAdd <1>)])}) */ - /* 278 */ {{3,P3(P(14),N(8),S(417)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {x 0.5 /%}) */ - /* 279 */ {{2,P2(P(1),P(14)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {% x}) */ - /* 280 */ {{2,P2(P(1),S(96)) , cMul ,SelectedParams ,0}, 0, 0x1}, /* (cMul {% (cPow [x@P z])}) */ - /* 281 */ {{2,P2(P(1),S(212)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {% (cAdd {1 (cMul -1 <2>)})}) */ - /* 282 */ {{2,P2(P(1),S(256)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {% (cAdd (cMul -1 <2>) <1>)}) */ - /* 283 */ {{2,P2(P(14),P(21)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {x y}) */ - /* 284 */ {{2,P2(P(14),S(104)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {x (cPow [y -1])}) */ - /* 285 */ {{2,P2(P(14),S(391)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {x (cAnd <1>)}) */ - /* 286 */ {{3,P3(P(14),S(53),N(8)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {x LOG( % ) 0.5}) */ - /* 287 */ {{2,P2(P(21),P(28)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {y z}) */ - /* 288 */ {{2,P2(P(21),P(31)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {y a}) */ - /* 289 */ {{2,P2(P(28),P(32)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {z b}) */ - /* 290 */ {{3,P3(P(28),S(47),S(420)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {z (cLog [x]) /LOG( & )}) */ - /* 291 */ {{2,P2(P(1),S(83)) , cMul ,SelectedParams ,0}, 0, 0x7}, /* (cMul {% (cPow [& x])}) */ - /* 292 */ {{2,P2(P(1),S(153)) , cMul ,SelectedParams ,0}, 0, 0x7}, /* (cMul {% (cPow [/& x])}) */ - /* 293 */ {{2,P2(P(9),S(243)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {& (cAdd <2>)}) */ - /* 294 */ {{2,P2(P(9),S(242)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {& (cAdd <1>)}) */ - /* 295 */ {{2,P2(P(14),S(54)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {x LOG( & )}) */ - /* 296 */ {{2,P2(P(14),S(108)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {x (cPow [y %@N])}) */ - /* 297 */ {{2,P2(S(23),N(2)) , cMul ,SelectedParams ,0}, 0, 0x4}, /* (cMul {(cCosh [x]) -1}) */ - /* 298 */ {{2,P2(S(84),N(2)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cPow [& y]) -1}) */ - /* 299 */ {{2,P2(S(11),N(13)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cAtanh [x]) 2}) */ - /* 300 */ {{2,P2(S(105),P(1)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cPow [x y]) %}) */ - /* 301 */ {{2,P2(S(194),P(14)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {-% x}) */ - /* 302 */ {{2,P2(S(14),S(16)) , cMul ,SelectedParams ,0}, 0, 0x12}, /* (cMul {(cCos [x]) (cCos [y])}) */ - /* 303 */ {{2,P2(S(47),S(417)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cLog [x]) /%}) */ - /* 304 */ {{2,P2(S(65),N(2)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cPow [0.367879441171 x]) -1}) */ - /* 305 */ {{2,P2(S(65),N(2)) , cMul ,SelectedParams ,0}, 0, 0x4}, /* (cMul {(cPow [0.367879441171 x]) -1}) */ - /* 306 */ {{2,P2(S(67),N(2)) , cMul ,SelectedParams ,0}, 0, 0x4}, /* (cMul {(cPow [2.71828182846 x]) -1}) */ - /* 307 */ {{2,P2(S(170),N(2)) , cMul ,SelectedParams ,0}, 0, 0x4}, /* (cMul {(cSinh [x]) -1}) */ - /* 308 */ {{3,P3(S(25),N(13),P(1)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cCosh [(cMul {x LOG( & )})]) 2 %}) */ - /* 309 */ {{2,P2(S(173),N(0)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cSinh [(cMul {x LOG( & )})]) -2}) */ - /* 310 */ {{2,P2(S(24),N(13)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cCosh [(cLog [(cPow [& x])])]) 2}) */ - /* 311 */ {{2,P2(S(171),N(13)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cSinh [(cLog [(cPow [& x])])]) 2}) */ - /* 312 */ {{3,P3(S(173),N(13),P(1)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cSinh [(cMul {x LOG( & )})]) 2 %}) */ - /* 313 */ {{2,P2(S(194),S(153)) , cMul ,SelectedParams ,0}, 0, 0x7}, /* (cMul {-% (cPow [/& x])}) */ - /* 314 */ {{3,P3(S(14),S(16),N(2)) , cMul ,SelectedParams ,0}, 0, 0x12}, /* (cMul {(cCos [x]) (cCos [y]) -1}) */ - /* 315 */ {{2,P2(S(14),S(160)) , cMul ,SelectedParams ,0}, 0, 0x12}, /* (cMul {(cCos [x]) (cSin [y])}) */ - /* 316 */ {{2,P2(S(53),P(21)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {LOG( % ) y}) */ - /* 317 */ {{2,P2(S(89),N(2)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cPow [x 2]) -1}) */ - /* 318 */ {{2,P2(S(158),S(16)) , cMul ,SelectedParams ,0}, 0, 0x12}, /* (cMul {(cSin [x]) (cCos [y])}) */ - /* 319 */ {{2,P2(S(110),S(73)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cPow [z (cAdd <1>)]) (cPow [2.71828182846 (cMul <2>)])}) */ - /* 320 */ {{2,P2(S(155),S(106)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {POW( % & ) (cPow [% (cAdd <1>)])}) */ - /* 321 */ {{2,P2(S(155),S(107)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {POW( % & ) (cPow [x LOG( % )])}) */ - /* 322 */ {{2,P2(S(155),S(152)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {POW( % & ) (cPow [(cMul <1>) &])}) */ - /* 323 */ {{2,P2(S(158),S(160)) , cMul ,SelectedParams ,0}, 0, 0x12}, /* (cMul {(cSin [x]) (cSin [y])}) */ - /* 324 */ {{3,P3(S(14),S(160),N(2)) , cMul ,SelectedParams ,0}, 0, 0x12}, /* (cMul {(cCos [x]) (cSin [y]) -1}) */ - /* 325 */ {{3,P3(S(158),S(160),N(2)) , cMul ,SelectedParams ,0}, 0, 0x12}, /* (cMul {(cSin [x]) (cSin [y]) -1}) */ - /* 326 */ {{2,P2(S(97),S(240)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cPow [x MIN( % 1 )]) (cAdd {(cMul (cPow [x (cAdd {% -MIN( % 1 )})]) <1>) (cMul (cPow [x (cAdd {1 -MIN( % 1 )})]) <2>)})}) */ - /* 327 */ {{2,P2(S(98),S(241)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cPow [x MIN( % & )]) (cAdd {(cMul (cPow [x (cAdd {% -MIN( % & )})]) <1>) (cMul (cPow [x (cAdd {& -MIN( % & )})]) <2>)})}) */ - /* 328 */ {{2,P2(S(200),S(146)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cAdd {1 x})@D4 (cPow [(cAdd {1 (cMul {-1 x})}) -1])@D4}) */ - /* 329 */ {{2,P2(S(375),P(21)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cNot [x]) y}) */ - /* 330 */ {{2,P2(S(399),P(21)) , cMul ,SelectedParams ,0}, 0, 0x0}, /* (cMul {(cNotNot [x]) y}) */ - /* 331 */ {{0,0 , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul <1>) */ - /* 332 */ {{0,0 , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul <2>) */ - /* 333 */ {{1,P1(N(2)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul -1 <1>) */ - /* 334 */ {{1,P1(N(2)) , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul -1 <2>) */ - /* 335 */ {{1,P1(P(0)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul %@N <1>) */ - /* 336 */ {{1,P1(P(2)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul %@P <1>) */ - /* 337 */ {{1,P1(P(2)) , cMul ,AnyParams ,1}, 0, 0x1}, /* (cMul %@P <1>) */ - /* 338 */ {{1,P1(P(6)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul %@M <1>) */ - /* 339 */ {{1,P1(P(1)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul % <1>) */ - /* 340 */ {{1,P1(P(9)) , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul & <2>) */ - /* 341 */ {{2,P2(P(1),P(9)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul % & <1>) */ - /* 342 */ {{2,P2(P(9),S(417)) , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul & /% <2>) */ - /* 343 */ {{1,P1(P(14)) , cMul ,AnyParams ,1}, 0, 0x4}, /* (cMul x <1>) */ - /* 344 */ {{1,P1(P(14)) , cMul ,AnyParams ,2}, 0, 0x4}, /* (cMul x <2>) */ - /* 345 */ {{1,P1(P(14)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul x <1>) */ - /* 346 */ {{1,P1(P(14)) , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul x <2>) */ - /* 347 */ {{1,P1(S(0)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul (cAbs [x]) <1>) */ - /* 348 */ {{1,P1(S(47)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul (cLog [x]) <1>) */ - /* 349 */ {{1,P1(S(53)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul LOG( % ) <1>) */ - /* 350 */ {{1,P1(S(86)) , cMul ,AnyParams ,1}, 0, 0x4}, /* (cMul (cPow [x %@I@P]) <1>) */ - /* 351 */ {{1,P1(S(87)) , cMul ,AnyParams ,2}, 0, 0x4}, /* (cMul (cPow [x &@I]) <2>) */ - /* 352 */ {{1,P1(S(88)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul (cPow [% y]) <1>) */ - /* 353 */ {{1,P1(S(99)) , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul (cPow [x (cAdd {1 -MIN( % 1 )})]) <2>) */ - /* 354 */ {{1,P1(S(101)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul (cPow [x (cAdd {% -MIN( % 1 )})]) <1>) */ - /* 355 */ {{1,P1(S(102)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul (cPow [x (cAdd {% -MIN( % & )})]) <1>) */ - /* 356 */ {{1,P1(S(103)) , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul (cPow [x (cAdd {& -MIN( % & )})]) <2>) */ - /* 357 */ {{1,P1(S(123)) , cMul ,AnyParams ,2}, 0, 0x0}, /* (cMul (cPow [(cLog [z]) -1]) <2>) */ - /* 358 */ {{1,P1(S(194)) , cMul ,AnyParams ,1}, 0, 0x0}, /* (cMul -% <1>) */ - /* 359 */ {{1,P1(S(194)) , cMul ,AnyParams ,2}, 0, 0x1}, /* (cMul -% <2>) */ - /* 360 */ {{2,P2(S(123),S(47)) , cMul ,AnyParams ,1}, 0, 0x16}, /* (cMul (cPow [(cLog [z]) -1]) (cLog [x]) <1>) */ - /* 361 */ {{2,P2(S(419),S(47)) , cMul ,AnyParams ,1}, 0, 0x1}, /* (cMul /LOG( % ) (cLog [x]) <1>) */ - /* 362 */ {{2,P2(P(1),P(9)) , cMul ,GroupFunction ,0}, Constness_Const, 0x0}, /* MUL( % & ) */ - /* 363 */ {{2,P2(P(9),S(417)) , cMul ,GroupFunction ,0}, Constness_Const, 0x0}, /* MUL( & /% ) */ - /* 364 */ {{2,P2(S(54),S(419)) , cMul ,GroupFunction ,0}, Constness_Const, 0x0}, /* MUL( LOG( & ) /LOG( % ) ) */ - /* 365 */ {{2,P2(P(14),P(21)) , cEqual ,PositionalParams,0}, 0, 0x12}, /* (cEqual [x y]) */ - /* 366 */ {{2,P2(P(14),P(21)) , cEqual ,PositionalParams,0}, 0, 0x0}, /* (cEqual [x y]) */ - /* 367 */ {{2,P2(P(14),P(28)) , cEqual ,PositionalParams,0}, 0, 0x20}, /* (cEqual [x z]) */ - /* 368 */ {{2,P2(P(21),P(28)) , cEqual ,PositionalParams,0}, 0, 0x24}, /* (cEqual [y z]) */ - /* 369 */ {{2,P2(P(21),P(28)) , cEqual ,PositionalParams,0}, 0, 0x0}, /* (cEqual [y z]) */ - /* 370 */ {{2,P2(N(4),P(14)) , cLess ,PositionalParams,0}, 0, 0x4}, /* (cLess [0 x]) */ - /* 371 */ {{2,P2(P(21),P(14)) , cLess ,PositionalParams,0}, 0, 0x0}, /* (cLess [y x]) */ - /* 372 */ {{2,P2(P(14),P(21)) , cLess ,PositionalParams,0}, 0, 0x12}, /* (cLess [x y]) */ - /* 373 */ {{2,P2(P(14),P(21)) , cLessOrEq ,PositionalParams,0}, 0, 0x0}, /* (cLessOrEq [x y]) */ - /* 374 */ {{1,P1(P(1)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [%]) */ - /* 375 */ {{1,P1(P(14)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [x]) */ - /* 376 */ {{1,P1(P(21)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [y]) */ - /* 377 */ {{1,P1(P(28)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [z]) */ - /* 378 */ {{1,P1(S(278)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [(cMul {x 0.5 /%})]) */ - /* 379 */ {{1,P1(S(385)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [(cAnd {x y})]) */ - /* 380 */ {{1,P1(S(388)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [(cAnd {z (cIf [x y (cNot [%])])})]) */ - /* 381 */ {{1,P1(S(389)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [(cAnd {z (cIf [x (cNot [%]) y])})]) */ - /* 382 */ {{1,P1(S(392)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [(cOr {x y})]) */ - /* 383 */ {{1,P1(S(395)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [(cOr {z (cIf [x y (cNot [%])])})]) */ - /* 384 */ {{1,P1(S(396)) , cNot ,PositionalParams,0}, 0, 0x0}, /* (cNot [(cOr {z (cIf [x (cNot [%]) y])})]) */ - /* 385 */ {{2,P2(P(14),P(21)) , cAnd ,SelectedParams ,0}, 0, 0x0}, /* (cAnd {x y}) */ - /* 386 */ {{2,P2(P(21),P(31)) , cAnd ,SelectedParams ,0}, 0, 0x0}, /* (cAnd {y a}) */ - /* 387 */ {{2,P2(P(28),P(32)) , cAnd ,SelectedParams ,0}, 0, 0x0}, /* (cAnd {z b}) */ - /* 388 */ {{2,P2(P(28),S(35)) , cAnd ,SelectedParams ,0}, 0, 0x0}, /* (cAnd {z (cIf [x y (cNot [%])])}) */ - /* 389 */ {{2,P2(P(28),S(37)) , cAnd ,SelectedParams ,0}, 0, 0x0}, /* (cAnd {z (cIf [x (cNot [%]) y])}) */ - /* 390 */ {{2,P2(S(375),P(21)) , cAnd ,SelectedParams ,0}, 0, 0x0}, /* (cAnd {(cNot [x]) y}) */ - /* 391 */ {{0,0 , cAnd ,AnyParams ,1}, 0, 0x0}, /* (cAnd <1>) */ - /* 392 */ {{2,P2(P(14),P(21)) , cOr ,SelectedParams ,0}, 0, 0x0}, /* (cOr {x y}) */ - /* 393 */ {{2,P2(P(21),P(31)) , cOr ,SelectedParams ,0}, 0, 0x0}, /* (cOr {y a}) */ - /* 394 */ {{2,P2(P(28),P(32)) , cOr ,SelectedParams ,0}, 0, 0x0}, /* (cOr {z b}) */ - /* 395 */ {{2,P2(P(28),S(35)) , cOr ,SelectedParams ,0}, 0, 0x0}, /* (cOr {z (cIf [x y (cNot [%])])}) */ - /* 396 */ {{2,P2(P(28),S(37)) , cOr ,SelectedParams ,0}, 0, 0x0}, /* (cOr {z (cIf [x (cNot [%]) y])}) */ - /* 397 */ {{2,P2(S(375),P(21)) , cOr ,SelectedParams ,0}, 0, 0x0}, /* (cOr {(cNot [x]) y}) */ - /* 398 */ {{0,0 , cOr ,AnyParams ,1}, 0, 0x0}, /* (cOr <1>) */ - /* 399 */ {{1,P1(P(14)) , cNotNot ,PositionalParams,0}, 0, 0x0}, /* (cNotNot [x]) */ - /* 400 */ {{1,P1(P(21)) , cNotNot ,PositionalParams,0}, 0, 0x0}, /* (cNotNot [y]) */ - /* 401 */ {{1,P1(S(215)) , cNotNot ,PositionalParams,0}, 0, 0x0}, /* (cNotNot [(cAdd {x y})]) */ - /* 402 */ {{1,P1(S(253)) , cNotNot ,PositionalParams,0}, 0, 0x0}, /* (cNotNot [(cAdd x <1>)]) */ - /* 403 */ {{1,P1(S(278)) , cNotNot ,PositionalParams,0}, 0, 0x0}, /* (cNotNot [(cMul {x 0.5 /%})]) */ - /* 404 */ {{1,P1(S(285)) , cNotNot ,PositionalParams,0}, 0, 0x0}, /* (cNotNot [(cMul {x (cAnd <1>)})]) */ - /* 405 */ {{1,P1(S(331)) , cDeg ,PositionalParams,0}, 0, 0x0}, /* (cDeg [(cMul <1>)]) */ - /* 406 */ {{1,P1(S(331)) , cRad ,PositionalParams,0}, 0, 0x0}, /* (cRad [(cMul <1>)]) */ - /* 407 */ {{3,P3(P(14),P(21),S(391)) , cAbsAnd ,SelectedParams ,0}, 0, 0x0}, /* (cAbsAnd {x y (cAnd <1>)}) */ - /* 408 */ {{3,P3(P(14),P(21),S(398)) , cAbsOr ,SelectedParams ,0}, 0, 0x0}, /* (cAbsOr {x y (cOr <1>)}) */ - /* 409 */ {{1,P1(P(14)) , cAbsNot ,PositionalParams,0}, 0, 0x0}, /* (cAbsNot [x]) */ - /* 410 */ {{1,P1(P(14)) , cAbsNotNot ,PositionalParams,0}, 0, 0x0}, /* (cAbsNotNot [x]) */ - /* 411 */ {{1,P1(P(21)) , cAbsNotNot ,PositionalParams,0}, 0, 0x0}, /* (cAbsNotNot [y]) */ - /* 412 */ {{1,P1(P(28)) , cAbsNotNot ,PositionalParams,0}, 0, 0x0}, /* (cAbsNotNot [z]) */ - /* 413 */ {{3,P3(P(14),N(10),S(411)) , cAbsIf ,PositionalParams,0}, 0, 0x0}, /* (cAbsIf [x 1 (cAbsNotNot [y])]) */ - /* 414 */ {{3,P3(P(14),P(21),P(28)) , cAbsIf ,PositionalParams,0}, 0, 0x0}, /* (cAbsIf [x y z]) */ - /* 415 */ {{3,P3(P(14),S(331),N(4)) , cAbsIf ,PositionalParams,0}, 0, 0x0}, /* (cAbsIf [x (cMul <1>) 0]) */ - /* 416 */ {{3,P3(P(14),S(411),N(4)) , cAbsIf ,PositionalParams,0}, 0, 0x0}, /* (cAbsIf [x (cAbsNotNot [y]) 0]) */ - /* 417 */ {{1,P1(P(1)) , cInv ,GroupFunction ,0}, Constness_Const, 0x0}, /* /% */ - /* 418 */ {{1,P1(P(9)) , cInv ,GroupFunction ,0}, Constness_Const, 0x0}, /* /& */ - /* 419 */ {{1,P1(S(53)) , cInv ,GroupFunction ,0}, Constness_Const, 0x0}, /* /LOG( % ) */ - /* 420 */ {{1,P1(S(54)) , cInv ,GroupFunction ,0}, Constness_Const, 0x0}, /* /LOG( & ) */ - /* 421 */ {{1,P1(S(64)) , cInv ,GroupFunction ,0}, Constness_Const, 0x0}, /* /MIN( % & ) */ - }, - - }; -} -namespace FPoptimizer_Grammar -{ - const Rule grammar_rules[241] = - { - /* 0: @L (cAbs [x]) - * -> x - */ {ProduceNewTree, true , 1,P1(P(14)) , {1,P1(P(14)) , cAbs ,PositionalParams,0}}, - /* 1: (cAtan [(cMul {x (cPow [y %@N])})]) - * -> (cAtan2 [x (cPow [y -%])]) - */ {ProduceNewTree, false, 1,P1(S(10)) , {1,P1(S(296)) , cAtan ,PositionalParams,0}}, - /* 2: (cAtan2 [(cPow [(cAdd {(cMul {(cPow [x 2]) -1}) 1}) 0.5])@D4 x@D4]) - * -> (cAcos [x]) - */ {ProduceNewTree, false, 1,P1(S(3)) , {2,P2(S(150),P(15)) , cAtan2 ,PositionalParams,0}}, - /* 3: (cAtan2 [x@D4 (cPow [(cAdd {(cMul {(cPow [x 2]) -1}) 1}) 0.5])@D4]) - * -> (cAsin [x]) - */ {ProduceNewTree, false, 1,P1(S(5)) , {2,P2(P(15),S(150)) , cAtan2 ,PositionalParams,0}}, - /* 4: (cAtan2 [(cMul x <1>)@D4 (cMul x <2>)@D4]) - * : (cMul <1>) (cMul <2>) - */ {ReplaceParams , false, 2,P2(S(331),S(332)) , {2,P2(S(343),S(344)) , cAtan2 ,PositionalParams,0}}, - /* 5: (cCeil [x@I]) - * -> x - */ {ProduceNewTree, false, 1,P1(P(14)) , {1,P1(P(16)) , cCeil ,PositionalParams,0}}, - /* 6: (cCeil [(cMul -1 <1>)]) - * -> (cMul {-1 (cFloor [(cMul <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(267)) , {1,P1(S(333)) , cCeil ,PositionalParams,0}}, - /* 7: (cCos [(cAdd {1.57079632679 (cMul %@N <1>)})]) - * -> (cSin [(cMul -% <1>)]) - */ {ProduceNewTree, false, 1,P1(S(168)) , {1,P1(S(214)) , cCos ,PositionalParams,0}}, - /* 8: (cCos [(cAdd -1.57079632679 <1>)]) - * -> (cSin [(cAdd <1>)]) - */ {ProduceNewTree, false, 1,P1(S(163)) , {1,P1(S(245)) , cCos ,PositionalParams,0}}, - /* 9: (cCos [(cAcos [x])]) - * -> x - */ {ProduceNewTree, false, 1,P1(P(14)) , {1,P1(S(3)) , cCos ,PositionalParams,0}}, - /* 10: (cCos [(cAbs [x])]) - * : x - */ {ReplaceParams , false, 1,P1(P(14)) , {1,P1(S(0)) , cCos ,PositionalParams,0}}, - /* 11: (cCos [(cMul -1 <1>)]) - * : (cMul <1>) - */ {ReplaceParams , false, 1,P1(S(331)) , {1,P1(S(333)) , cCos ,PositionalParams,0}}, - /* 12: (cCosh [(cAsinh [x])]) - * -> (cPow [(cAdd {(cPow [x 2]) 1}) 0.5]) - */ {ProduceNewTree, false, 1,P1(S(149)) , {1,P1(S(6)) , cCosh ,PositionalParams,0}}, - /* 13: (cCosh [(cAbs [x])]) - * : x - */ {ReplaceParams , false, 1,P1(P(14)) , {1,P1(S(0)) , cCosh ,PositionalParams,0}}, - /* 14: (cCosh [(cMul -1 <1>)]) - * : (cMul <1>) - */ {ReplaceParams , false, 1,P1(S(331)) , {1,P1(S(333)) , cCosh ,PositionalParams,0}}, - /* 15: (cFloor [x@I]) - * -> x - */ {ProduceNewTree, false, 1,P1(P(14)) , {1,P1(P(16)) , cFloor ,PositionalParams,0}}, - /* 16: (cFloor [(cMul -1 <1>)]) - * -> (cMul {-1 (cCeil [(cMul <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(263)) , {1,P1(S(333)) , cFloor ,PositionalParams,0}}, - /* 17: (cFloor [(cAdd 0.5 <1>)]) - * -> (cInt [(cAdd <1>)]) - */ {ProduceNewTree, false, 1,P1(S(46)) , {1,P1(S(246)) , cFloor ,PositionalParams,0}}, - /* 18: (cIf [x 0 y]) - * -> (cMul {(cNot [x]) y}) - */ {ProduceNewTree, false, 1,P1(S(329)) , {3,P3(P(14),N(4),P(21)) , cIf ,PositionalParams,0}}, - /* 19: (cIf [x@P y z]) - * -> (cAbsIf [x y z]) - */ {ProduceNewTree, false, 1,P1(S(414)) , {3,P3(P(17),P(21),P(28)) , cIf ,PositionalParams,0}}, - /* 20: (cIf [x 0 y@L]) - * -> (cAnd {(cNot [x]) y}) - */ {ProduceNewTree, false, 1,P1(S(390)) , {3,P3(P(14),N(4),P(22)) , cIf ,PositionalParams,0}}, - /* 21: (cIf [x 1 y@L]) - * -> (cOr {x y}) - */ {ProduceNewTree, false, 1,P1(S(392)) , {3,P3(P(14),N(10),P(22)) , cIf ,PositionalParams,0}}, - /* 22: (cIf [x y 0]) - * -> (cMul {(cNotNot [x]) y}) - */ {ProduceNewTree, false, 1,P1(S(330)) , {3,P3(P(14),P(21),N(4)) , cIf ,PositionalParams,0}}, - /* 23: (cIf [x y@L 0]) - * -> (cAnd {x y}) - */ {ProduceNewTree, false, 1,P1(S(385)) , {3,P3(P(14),P(22),N(4)) , cIf ,PositionalParams,0}}, - /* 24: (cIf [x y@L 1]) - * -> (cOr {(cNot [x]) y}) - */ {ProduceNewTree, false, 1,P1(S(397)) , {3,P3(P(14),P(22),N(10)) , cIf ,PositionalParams,0}}, - /* 25: (cIf [(cLess [x y])@D12 y@D8 x@D4]) - * -> (cMax [x y]) - */ {ProduceNewTree, false, 1,P1(S(57)) , {3,P3(S(372),P(23),P(15)) , cIf ,PositionalParams,0}}, - /* 26: (cIf [(cLess [x y])@D12 x@D4 y@D8]) - * -> (cMin [x y]) - */ {ProduceNewTree, false, 1,P1(S(60)) , {3,P3(S(372),P(15),P(23)) , cIf ,PositionalParams,0}}, - /* 27: (cIf [(cLess [0 x])@D4 (cFloor [x])@D4 (cCeil [x])@D4]) - * -> (cTrunc [x]) - */ {ProduceNewTree, false, 1,P1(S(193)) , {3,P3(S(370),S(29),S(12)) , cIf ,PositionalParams,0}}, - /* 28: (cIf [(cLessOrEq [x y]) z a]) - * : (cLess [y x]) a z - */ {ReplaceParams , false, 3,P3(S(371),P(31),P(28)) , {3,P3(S(373),P(28),P(31)) , cIf ,PositionalParams,0}}, - /* 29: @L (cIf [x (cAbsNotNot [y]) z]) - * : x y z - */ {ReplaceParams , true , 3,P3(P(14),P(21),P(28)) , {3,P3(P(14),S(411),P(28)) , cIf ,PositionalParams,0}}, - /* 30: @L (cIf [x y (cAbsNotNot [z])]) - * : x y z - */ {ReplaceParams , true , 3,P3(P(14),P(21),P(28)) , {3,P3(P(14),P(21),S(412)) , cIf ,PositionalParams,0}}, - /* 31: (cInt [x@I]) - * -> x - */ {ProduceNewTree, false, 1,P1(P(14)) , {1,P1(P(16)) , cInt ,PositionalParams,0}}, - /* 32: (cLog [(cMul %@P <1>)]) - * -> (cAdd {(cLog [(cMul <1>)]) LOG( % )}) - */ {ProduceNewTree, false, 1,P1(S(235)) , {1,P1(S(336)) , cLog ,PositionalParams,0}}, - /* 33: (cLog [(cMul (cPow [% y]) <1>)]) - * -> (cAdd {(cMul {LOG( % ) y}) (cLog [(cMul <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(234)) , {1,P1(S(352)) , cLog ,PositionalParams,0}}, - /* 34: (cLog [(cAdd {(cPow [(cAdd {-1 (cPow [x 2])}) 0.5])@D4 x@D4})]) - * -> (cAcosh [x]) - */ {ProduceNewTree, false, 1,P1(S(4)) , {1,P1(S(230)) , cLog ,PositionalParams,0}}, - /* 35: (cLog [(cMul {(cAdd {1 x})@D4 (cPow [(cAdd {1 (cMul {-1 x})}) -1])@D4})]) - * -> (cMul {(cAtanh [x]) 2}) - */ {ProduceNewTree, false, 1,P1(S(299)) , {1,P1(S(328)) , cLog ,PositionalParams,0}}, - /* 36: (cMax x@D4 x@D4) - * : x - */ {ReplaceParams , false, 1,P1(P(14)) , {2,P2(P(15),P(15)) , cMax ,AnyParams ,0}}, - /* 37: (cMax (cIf [x y z])@D4 (cIf [x a b])@D4) - * : (cIf [x (cMax [y a]) (cMax [z b])]) - */ {ReplaceParams , false, 1,P1(S(39)) , {2,P2(S(32),S(36)) , cMax ,AnyParams ,0}}, - /* 38: (cMin x@D4 x@D4) - * : x - */ {ReplaceParams , false, 1,P1(P(14)) , {2,P2(P(15),P(15)) , cMin ,AnyParams ,0}}, - /* 39: (cMin (cIf [x y z])@D4 (cIf [x a b])@D4) - * : (cIf [x (cMin [y a]) (cMin [z b])]) - */ {ReplaceParams , false, 1,P1(S(40)) , {2,P2(S(32),S(36)) , cMin ,AnyParams ,0}}, - /* 40: (cPow [(cMul %@P <1>) &]) - * -> (cMul {POW( % & ) (cPow [(cMul <1>) &])}) - */ {ProduceNewTree, false, 1,P1(S(322)) , {2,P2(S(336),P(9)) , cPow ,PositionalParams,0}}, - /* 41: (cPow [% (cAdd {(cLog [x]) &})]) - * -> (cMul {POW( % & ) (cPow [x LOG( % )])}) - */ {ProduceNewTree, false, 1,P1(S(321)) , {2,P2(P(1),S(228)) , cPow ,PositionalParams,0}}, - /* 42: (cPow [(cMul %@N <1>) &@E]) - * -> (cMul {POW( % & ) (cPow [(cMul <1>) &])}) - */ {ProduceNewTree, false, 1,P1(S(322)) , {2,P2(S(335),P(10)) , cPow ,PositionalParams,0}}, - /* 43: (cPow [z@D16 (cAdd (cMul (cPow [(cLog [z]) -1]) <2>) <1>)@D16]) - * -> (cMul {(cPow [z (cAdd <1>)]) (cPow [2.71828182846 (cMul <2>)])}) - */ {ProduceNewTree, false, 1,P1(S(319)) , {2,P2(P(29),S(258)) , cPow ,PositionalParams,0}}, - /* 44: (cPow [z@D16 (cAdd (cPow [(cLog [z]) -1]) <1>)@D16]) - * -> (cMul {2.71828182846 (cPow [z (cAdd <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(277)) , {2,P2(P(29),S(255)) , cPow ,PositionalParams,0}}, - /* 45: (cPow [% (cAdd &@M <1>)]) - * -> (cMul {POW( % & ) (cPow [% (cAdd <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(320)) , {2,P2(P(1),S(249)) , cPow ,PositionalParams,0}}, - /* 46: (cPow [(cPow [x y@O]) z]) - * : x (cMul {y z}) - */ {ReplaceParams , false, 2,P2(P(14),S(287)) , {2,P2(S(90),P(28)) , cPow ,PositionalParams,0}}, - /* 47: (cPow [(cPow [x y@F]) z]) - * : x (cMul {y z}) - */ {ReplaceParams , false, 2,P2(P(14),S(287)) , {2,P2(S(91),P(28)) , cPow ,PositionalParams,0}}, - /* 48: (cPow [(cPow [x@P y]) z]) - * : x (cMul {y z}) - */ {ReplaceParams , false, 2,P2(P(14),S(287)) , {2,P2(S(92),P(28)) , cPow ,PositionalParams,0}}, - /* 49: (cPow [(cPow [x y])@P z]) - * : (cAbs [x]) (cMul {y z}) - */ {ReplaceParams , false, 2,P2(S(0),S(287)) , {2,P2(S(93),P(28)) , cPow ,PositionalParams,0}}, - /* 50: (cPow [(cSin [x]) %@N]) - * : (cCsc [x]) -% - */ {ReplaceParams , false, 2,P2(S(28),S(194)) , {2,P2(S(158),P(0)) , cPow ,PositionalParams,0}}, - /* 51: (cPow [(cCos [x]) %@N]) - * : (cSec [x]) -% - */ {ReplaceParams , false, 2,P2(S(157),S(194)) , {2,P2(S(14),P(0)) , cPow ,PositionalParams,0}}, - /* 52: (cPow [(cTan [x]) %@N]) - * : (cCot [x]) -% - */ {ReplaceParams , false, 2,P2(S(27),S(194)) , {2,P2(S(177),P(0)) , cPow ,PositionalParams,0}}, - /* 53: (cPow [% (cLog [x])]) - * : x LOG( % ) - */ {ReplaceParams , false, 2,P2(P(14),S(53)) , {2,P2(P(1),S(47)) , cPow ,PositionalParams,0}}, - /* 54: (cPow [% (cMul (cLog [x]) <1>)]) - * : x (cMul LOG( % ) <1>) - */ {ReplaceParams , false, 2,P2(P(14),S(349)) , {2,P2(P(1),S(348)) , cPow ,PositionalParams,0}}, - /* 55: (cPow [z@D16 (cMul (cPow [(cLog [z]) -1]) (cLog [x]) <1>)@D16]) - * : x (cMul <1>) - */ {ReplaceParams , false, 2,P2(P(14),S(331)) , {2,P2(P(29),S(360)) , cPow ,PositionalParams,0}}, - /* 56: (cPow [%@D1 (cMul /LOG( % ) (cLog [x]) <1>)@D1]) - * : x (cMul <1>) - */ {ReplaceParams , false, 2,P2(P(14),S(331)) , {2,P2(P(3),S(361)) , cPow ,PositionalParams,0}}, - /* 57: (cPow [(cPow [x y]) z@I]) - * : x (cMul {y z}) - */ {ReplaceParams , false, 2,P2(P(14),S(287)) , {2,P2(S(105),P(30)) , cPow ,PositionalParams,0}}, - /* 58: (cPow [(cAbs [x]) y@E]) - * : x y - */ {ReplaceParams , false, 2,P2(P(14),P(21)) , {2,P2(S(0),P(26)) , cPow ,PositionalParams,0}}, - /* 59: (cPow [(cMul (cAbs [x]) <1>) y@E]) - * : (cMul x <1>) y - */ {ReplaceParams , false, 2,P2(S(345),P(21)) , {2,P2(S(347),P(26)) , cPow ,PositionalParams,0}}, - /* 60: (cSin [(cMul -1 <1>)]) - * -> (cMul {-1 (cSin [(cMul <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(272)) , {1,P1(S(333)) , cSin ,PositionalParams,0}}, - /* 61: (cSin [(cAdd {1.57079632679 (cMul %@N <1>)})]) - * -> (cCos [(cMul -% <1>)]) - */ {ProduceNewTree, false, 1,P1(S(21)) , {1,P1(S(214)) , cSin ,PositionalParams,0}}, - /* 62: (cSin [(cAdd -1.57079632679 <1>)]) - * -> (cMul {-1 (cCos [(cAdd <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(265)) , {1,P1(S(245)) , cSin ,PositionalParams,0}}, - /* 63: (cSin [(cAsin [x])]) - * -> x - */ {ProduceNewTree, false, 1,P1(P(14)) , {1,P1(S(5)) , cSin ,PositionalParams,0}}, - /* 64: (cSinh [(cMul -1 <1>)]) - * -> (cMul {-1 (cSinh [(cMul <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(274)) , {1,P1(S(333)) , cSinh ,PositionalParams,0}}, - /* 65: (cSinh [(cAcosh [x])]) - * -> (cPow [(cAdd {(cPow [x 2]) -1}) 0.5]) - */ {ProduceNewTree, false, 1,P1(S(148)) , {1,P1(S(4)) , cSinh ,PositionalParams,0}}, - /* 66: (cTan [(cMul -1 <1>)]) - * -> (cMul {-1 (cTan [(cMul <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(275)) , {1,P1(S(333)) , cTan ,PositionalParams,0}}, - /* 67: (cTan [(cAtan [x])]) - * -> x - */ {ProduceNewTree, false, 1,P1(P(14)) , {1,P1(S(8)) , cTan ,PositionalParams,0}}, - /* 68: (cTan [(cAtan2 [x y])]) - * -> (cMul {x (cPow [y -1])}) - */ {ProduceNewTree, false, 1,P1(S(284)) , {1,P1(S(9)) , cTan ,PositionalParams,0}}, - /* 69: (cTanh [(cMul -1 <1>)]) - * -> (cMul {-1 (cTanh [(cMul <1>)])}) - */ {ProduceNewTree, false, 1,P1(S(276)) , {1,P1(S(333)) , cTanh ,PositionalParams,0}}, - /* 70: (cTrunc [x@I]) - * -> x - */ {ProduceNewTree, false, 1,P1(P(14)) , {1,P1(P(16)) , cTrunc ,PositionalParams,0}}, - /* 71: (cAdd (cPow [(cAdd {1 (cPow [(cAdd <1>) 2])}) 0.5]) <1>) - * -> (cPow [2.71828182846 (cAsinh [(cAdd <1>)])]) - */ {ProduceNewTree, false, 1,P1(S(72)) , {1,P1(S(145)) , cAdd ,AnyParams ,1}}, - /* 72: (cAdd (cPow [(cAdd {1 (cPow [(cAdd <1>) 2])}) -0.5]) <1>) - * -> (cPow [0.367879441171 (cAsinh [(cAdd <1>)])]) - */ {ProduceNewTree, false, 1,P1(S(71)) , {1,P1(S(144)) , cAdd ,AnyParams ,1}}, - /* 73: (cAdd (cPow [(cAdd {1 (cPow [x 2])}) 0.5])@D4 x@D4) - * : (cPow [2.71828182846 (cAsinh [x])]) - */ {ReplaceParams , false, 1,P1(S(70)) , {2,P2(S(143),P(15)) , cAdd ,AnyParams ,0}}, - /* 74: (cAdd (cPow [(cAdd {1 (cPow [x 2])}) -0.5])@D4 x@D4) - * : (cPow [0.367879441171 (cAsinh [x])]) - */ {ReplaceParams , false, 1,P1(S(69)) , {2,P2(S(142),P(15)) , cAdd ,AnyParams ,0}}, - /* 75: (cAdd (cIf [x y z])@D4 (cIf [x a b])@D4) - * : (cIf [x (cAdd {y a}) (cAdd {z b})]) - */ {ReplaceParams , false, 1,P1(S(41)) , {2,P2(S(32),S(36)) , cAdd ,AnyParams ,0}}, - /* 76: (cAdd (cLog [x]) (cLog [y])) - * : (cLog [(cMul {x y})]) - */ {ReplaceParams , false, 1,P1(S(51)) , {2,P2(S(47),S(48)) , cAdd ,AnyParams ,0}}, - /* 77: (cAdd (cMul (cPow [x %@I@P]) <1>)@D4 (cMul (cPow [x &@I]) <2>)@D4) - * : (cMul {(cPow [x MIN( % & )]) (cAdd {(cMul (cPow [x (cAdd {% -MIN( % & )})]) <1>) (cMul (cPow [x (cAdd {& -MIN( % & )})]) <2>)})}) - */ {ReplaceParams , false, 1,P1(S(327)) , {2,P2(S(350),S(351)) , cAdd ,AnyParams ,0}}, - /* 78: (cAdd (cMul (cPow [x %@I@P]) <1>)@D4 (cMul x <2>)@D4) - * : (cMul {(cPow [x MIN( % 1 )]) (cAdd {(cMul (cPow [x (cAdd {% -MIN( % 1 )})]) <1>) (cMul (cPow [x (cAdd {1 -MIN( % 1 )})]) <2>)})}) - */ {ReplaceParams , false, 1,P1(S(326)) , {2,P2(S(350),S(344)) , cAdd ,AnyParams ,0}}, - /* 79: (cAdd (cMul %@P <1>)@D1 (cMul -% <2>)@D1) - * : (cMul {% (cAdd (cMul -1 <2>) <1>)}) - */ {ReplaceParams , false, 1,P1(S(282)) , {2,P2(S(337),S(359)) , cAdd ,AnyParams ,0}}, - /* 80: (cAdd %@M@D1 (cMul -% <2>)@D1) - * : (cMul {% (cAdd {1 (cMul -1 <2>)})}) - */ {ReplaceParams , false, 1,P1(S(281)) , {2,P2(P(5),S(359)) , cAdd ,AnyParams ,0}}, - /* 81: (cAdd (cPow [(cSin [x]) 2])@D4 (cPow [(cCos [x]) 2])@D4) - * : 1 - */ {ReplaceParams , false, 1,P1(N(10)) , {2,P2(S(140),S(117)) , cAdd ,AnyParams ,0}}, - /* 82: (cAdd 1 (cMul {-1 (cPow [(cSin [x]) 2])})) - * : (cPow [(cCos [x]) 2]) - */ {ReplaceParams , false, 1,P1(S(118)) , {2,P2(N(10),S(270)) , cAdd ,AnyParams ,0}}, - /* 83: (cAdd 1 (cMul {-1 (cPow [(cCos [x]) 2])})) - * : (cPow [(cSin [x]) 2]) - */ {ReplaceParams , false, 1,P1(S(141)) , {2,P2(N(10),S(269)) , cAdd ,AnyParams ,0}}, - /* 84: (cAdd (cMul {(cSin [x]) (cCos [y])})@D12 (cMul {(cCos [x]) (cSin [y])})@D12) - * : (cSin [(cAdd {x y})]) - */ {ReplaceParams , false, 1,P1(S(161)) , {2,P2(S(318),S(315)) , cAdd ,AnyParams ,0}}, - /* 85: (cAdd (cMul {(cSin [x]) (cCos [y])})@D12 (cMul {(cCos [x]) (cSin [y]) -1})@D12) - * : (cSin [(cAdd {x (cMul {-1 y})})]) - */ {ReplaceParams , false, 1,P1(S(162)) , {2,P2(S(318),S(324)) , cAdd ,AnyParams ,0}}, - /* 86: (cAdd (cMul {(cCos [x]) (cCos [y])})@D12 (cMul {(cSin [x]) (cSin [y])})@D12) - * : (cCos [(cAdd {x y})]) - */ {ReplaceParams , false, 1,P1(S(17)) , {2,P2(S(302),S(323)) , cAdd ,AnyParams ,0}}, - /* 87: (cAdd (cMul {(cCos [x]) (cCos [y]) -1})@D12 (cMul {(cSin [x]) (cSin [y])})@D12) - * : (cMul {-1 (cCos [(cAdd {x (cMul {-1 y})})])}) - */ {ReplaceParams , false, 1,P1(S(264)) , {2,P2(S(314),S(323)) , cAdd ,AnyParams ,0}}, - /* 88: (cAdd (cMul {(cCos [x]) (cCos [y])})@D12 (cMul {(cSin [x]) (cSin [y]) -1})@D12) - * : (cCos [(cAdd {x (cMul {-1 y})})]) - */ {ReplaceParams , false, 1,P1(S(18)) , {2,P2(S(302),S(325)) , cAdd ,AnyParams ,0}}, - /* 89: (cAdd (cPow [& x])@D6 (cMul {-1 (cPow [/& x])})@D6) - * : (cMul {(cSinh [(cLog [(cPow [& x])])]) 2}) - */ {ReplaceParams , false, 1,P1(S(311)) , {2,P2(S(82),S(271)) , cAdd ,AnyParams ,0}}, - /* 90: (cAdd (cPow [& x])@D6 (cPow [/& x])@D6) - * : (cMul {(cCosh [(cLog [(cPow [& x])])]) 2}) - */ {ReplaceParams , false, 1,P1(S(310)) , {2,P2(S(82),S(154)) , cAdd ,AnyParams ,0}}, - /* 91: (cAdd (cMul {-1 (cPow [& x])})@D6 (cPow [/& x])@D6) - * : (cMul {(cSinh [(cMul {x LOG( & )})]) -2}) - */ {ReplaceParams , false, 1,P1(S(309)) , {2,P2(S(268),S(154)) , cAdd ,AnyParams ,0}}, - /* 92: (cAdd (cMul {% (cPow [& x])})@D7 (cMul {-% (cPow [/& x])})@D7) - * : (cMul {(cSinh [(cMul {x LOG( & )})]) 2 %}) - */ {ReplaceParams , false, 1,P1(S(312)) , {2,P2(S(291),S(313)) , cAdd ,AnyParams ,0}}, - /* 93: (cAdd (cMul {% (cPow [& x])})@D7 (cMul {% (cPow [/& x])})@D7) - * : (cMul {(cCosh [(cMul {x LOG( & )})]) 2 %}) - */ {ReplaceParams , false, 1,P1(S(308)) , {2,P2(S(291),S(292)) , cAdd ,AnyParams ,0}}, - /* 94: (cAdd (cCosh [x])@D4 (cSinh [x])@D4) - * : (cPow [2.71828182846 x]) - */ {ReplaceParams , false, 1,P1(S(67)) , {2,P2(S(22),S(169)) , cAdd ,AnyParams ,0}}, - /* 95: (cAdd (cMul {(cCosh [x]) -1})@D4 (cSinh [x])@D4) - * : (cMul {(cPow [0.367879441171 x]) -1}) - */ {ReplaceParams , false, 1,P1(S(304)) , {2,P2(S(297),S(169)) , cAdd ,AnyParams ,0}}, - /* 96: (cAdd (cCosh [x])@D4 (cMul {(cPow [2.71828182846 x]) -1})@D4) - * : (cMul {-1 (cSinh [x])}) - */ {ReplaceParams , false, 1,P1(S(273)) , {2,P2(S(22),S(306)) , cAdd ,AnyParams ,0}}, - /* 97: (cAdd (cSinh [x])@D4 (cMul {(cPow [2.71828182846 x]) -1})@D4) - * : (cMul {-1 (cCosh [x])}) - */ {ReplaceParams , false, 1,P1(S(266)) , {2,P2(S(169),S(306)) , cAdd ,AnyParams ,0}}, - /* 98: (cAdd (cCosh [x])@D4 (cMul {(cSinh [x]) -1})@D4) - * : (cPow [0.367879441171 x]) - */ {ReplaceParams , false, 1,P1(S(65)) , {2,P2(S(22),S(307)) , cAdd ,AnyParams ,0}}, - /* 99: (cAdd (cMul {(cSinh [x]) -1})@D4 (cPow [2.71828182846 x])@D4) - * : (cCosh [x]) - */ {ReplaceParams , false, 1,P1(S(23)) , {2,P2(S(307),S(68)) , cAdd ,AnyParams ,0}}, - /* 100: (cAdd (cMul {(cCosh [x]) -1})@D4 (cPow [2.71828182846 x])@D4) - * : (cSinh [x]) - */ {ReplaceParams , false, 1,P1(S(170)) , {2,P2(S(297),S(68)) , cAdd ,AnyParams ,0}}, - /* 101: (cAdd (cCosh [x])@D4 (cMul {(cPow [0.367879441171 x]) -1})@D4) - * : (cSinh [x]) - */ {ReplaceParams , false, 1,P1(S(170)) , {2,P2(S(22),S(305)) , cAdd ,AnyParams ,0}}, - /* 102: (cAdd (cSinh [x])@D4 (cPow [0.367879441171 x])@D4) - * : (cCosh [x]) - */ {ReplaceParams , false, 1,P1(S(23)) , {2,P2(S(169),S(66)) , cAdd ,AnyParams ,0}}, - /* 103: (cAdd (cMul {(cCosh [x]) -1})@D4 (cPow [0.367879441171 x])@D4) - * : (cMul {-1 (cSinh [x])}) - */ {ReplaceParams , false, 1,P1(S(273)) , {2,P2(S(297),S(66)) , cAdd ,AnyParams ,0}}, - /* 104: (cMul {%@D1 (cAdd {1 (cMul {(cLog [x]) /%})})@D1}) - * -> (cAdd {(cLog [x]) %}) - */ {ProduceNewTree, false, 1,P1(S(225)) , {2,P2(P(3),S(211)) , cMul ,SelectedParams ,0}}, - /* 105: (cMul x@L <1>) - * -> (cAbsIf [x (cMul <1>) 0]) - */ {ProduceNewTree, false, 1,P1(S(415)) , {1,P1(P(19)) , cMul ,AnyParams ,1}}, - /* 106: (cMul 57.2957795131 <1>) - * -> (cDeg [(cMul <1>)]) - */ {ProduceNewTree, false, 1,P1(S(405)) , {1,P1(N(16)) , cMul ,AnyParams ,1}}, - /* 107: (cMul 0.0174532925199 <1>) - * -> (cRad [(cMul <1>)]) - */ {ProduceNewTree, false, 1,P1(S(406)) , {1,P1(N(5)) , cMul ,AnyParams ,1}}, - /* 108: (cMul (cPow [(cMul x <2>) -1])@D4 x@D4) - * : (cPow [(cMul <2>) -1]) - */ {ReplaceParams , false, 1,P1(S(138)) , {2,P2(S(139),P(15)) , cMul ,AnyParams ,0}}, - /* 109: (cMul (cIf [x y z])@D4 (cIf [x a b])@D4) - * : (cIf [x (cMul {y a}) (cMul {z b})]) - */ {ReplaceParams , false, 1,P1(S(42)) , {2,P2(S(32),S(36)) , cMul ,AnyParams ,0}}, - /* 110: (cMul (cNot [x]) (cNot [y])) - * : (cNot [(cOr {x y})]) - */ {ReplaceParams , false, 1,P1(S(382)) , {2,P2(S(375),S(376)) , cMul ,AnyParams ,0}}, - /* 111: (cMul (cNotNot [x]) (cNotNot [y])) - * : (cAnd {x y}) - */ {ReplaceParams , false, 1,P1(S(385)) , {2,P2(S(399),S(400)) , cMul ,AnyParams ,0}}, - /* 112: (cMul (cNot [x]) (cNotNot [y])) - * : (cAnd {(cNot [x]) y}) - */ {ReplaceParams , false, 1,P1(S(390)) , {2,P2(S(375),S(400)) , cMul ,AnyParams ,0}}, - /* 113: (cMul (cAbs [x]) (cAbs [y])) - * : (cAbs [(cMul {x y})]) - */ {ReplaceParams , false, 1,P1(S(2)) , {2,P2(S(0),S(1)) , cMul ,AnyParams ,0}}, - /* 114: (cMul (cAdd (cMul %@M <1>) <2>) &) - * : (cAdd {(cMul % & <1>) (cMul {& (cAdd <2>)})}) - */ {ReplaceParams , false, 1,P1(S(238)) , {2,P2(S(257),P(9)) , cMul ,AnyParams ,0}}, - /* 115: (cMul (cAdd %@M <1>) &) - * : (cAdd {MUL( % & ) (cMul {& (cAdd <1>)})}) - */ {ReplaceParams , false, 1,P1(S(239)) , {2,P2(S(247),P(9)) , cMul ,AnyParams ,0}}, - /* 116: (cMul (cPow [x y])@D4 (cAdd {%@1 (cPow [x z])})@D4) - * : (cAdd {(cMul {(cPow [x y]) %}) (cPow [x (cAdd {y z})])}) - */ {ReplaceParams , false, 1,P1(S(233)) , {2,P2(S(94),S(217)) , cMul ,AnyParams ,0}}, - /* 117: (cMul (cPow [& y]) (cAdd {1 (cPow [x@P z])})) - * : (cAdd {(cPow [& y]) (cPow [& (cAdd {y (cMul {z (cLog [x]) /LOG( & )})})])}) - */ {ReplaceParams , false, 1,P1(S(229)) , {2,P2(S(84),S(206)) , cMul ,AnyParams ,0}}, - /* 118: (cMul (cPow [& y]) (cAdd {-1 (cPow [x@P z])})) - * : (cAdd {(cMul {(cPow [& y]) -1}) (cPow [& (cAdd {y (cMul {z (cLog [x]) /LOG( & )})})])}) - */ {ReplaceParams , false, 1,P1(S(232)) , {2,P2(S(84),S(204)) , cMul ,AnyParams ,0}}, - /* 119: (cMul -1 (cSin [(cMul %@N <1>)])) - * : (cSin [(cMul -% <1>)]) - */ {ReplaceParams , false, 1,P1(S(168)) , {2,P2(N(2),S(166)) , cMul ,AnyParams ,0}}, - /* 120: (cMul -1 (cSinh [(cMul %@N <1>)])) - * : (cSinh [(cMul -% <1>)]) - */ {ReplaceParams , false, 1,P1(S(176)) , {2,P2(N(2),S(175)) , cMul ,AnyParams ,0}}, - /* 121: (cMul (cPow [(cSinh [x]) -1])@D4 (cCosh [x])@D4) - * : (cPow [(cTanh [x]) -1]) - */ {ReplaceParams , false, 1,P1(S(133)) , {2,P2(S(130),S(22)) , cMul ,AnyParams ,0}}, - /* 122: (cMul (cTanh [x])@D4 (cCosh [x])@D4) - * : (cSinh [x]) - */ {ReplaceParams , false, 1,P1(S(170)) , {2,P2(S(187),S(22)) , cMul ,AnyParams ,0}}, - /* 123: (cMul (cPow [(cTanh [x]) -1])@D4 (cSinh [x])@D4) - * : (cCosh [x]) - */ {ReplaceParams , false, 1,P1(S(23)) , {2,P2(S(134),S(169)) , cMul ,AnyParams ,0}}, - /* 124: (cMul (cPow [(cTan [x]) -1])@D4 (cSin [x])@D4) - * : (cCos [x]) - */ {ReplaceParams , false, 1,P1(S(14)) , {2,P2(S(131),S(159)) , cMul ,AnyParams ,0}}, - /* 125: (cMul (cSin [x])@D4 (cPow [(cCos [x]) -1])@D4) - * : (cTan [x]) - */ {ReplaceParams , false, 1,P1(S(177)) , {2,P2(S(159),S(111)) , cMul ,AnyParams ,0}}, - /* 126: (cMul (cTan [x])@D4 (cPow [(cSin [x]) -1])@D4) - * : (cPow [(cCos [x]) -1]) - */ {ReplaceParams , false, 1,P1(S(112)) , {2,P2(S(178),S(129)) , cMul ,AnyParams ,0}}, - /* 127: (cMul (cPow [(cSin [x]) -1])@D4 (cCos [x])@D4) - * : (cPow [(cTan [x]) -1]) - */ {ReplaceParams , false, 1,P1(S(132)) , {2,P2(S(129),S(15)) , cMul ,AnyParams ,0}}, - /* 128: (cMul (cTan [x])@D4 (cCos [x])@D4) - * : (cSin [x]) - */ {ReplaceParams , false, 1,P1(S(158)) , {2,P2(S(178),S(15)) , cMul ,AnyParams ,0}}, - /* 129: (cMul (cTan [(cAdd {1.57079632679 (cMul {-1 x})})])@D4 (cTan [x])@D4) - * : 1 - */ {ReplaceParams , false, 1,P1(N(10)) , {2,P2(S(179),S(178)) , cMul ,AnyParams ,0}}, - /* 130: (cMul (cSin [(cMul % <1>)])@D1 (cPow [(cCos [(cMul -% <1>)]) -1])@D1) - * : (cTan [(cMul % <1>)]) - */ {ReplaceParams , false, 1,P1(S(183)) , {2,P2(S(167),S(114)) , cMul ,AnyParams ,0}}, - /* 131: (cMul (cTan [(cAdd {1.57079632679 (cMul -1 <1>)})]) (cTan [(cMul <1>)])) - * : 1 - */ {ReplaceParams , false, 1,P1(N(10)) , {2,P2(S(180),S(182)) , cMul ,AnyParams ,0}}, - /* 132: (cMul -1 (cTan [(cMul %@N <1>)])) - * : (cTan [(cMul -% <1>)]) - */ {ReplaceParams , false, 1,P1(S(185)) , {2,P2(N(2),S(184)) , cMul ,AnyParams ,0}}, - /* 133: (cMul (cSinh [x])@D4 (cPow [(cCosh [x]) -1])@D4) - * : (cTanh [x]) - */ {ReplaceParams , false, 1,P1(S(186)) , {2,P2(S(169),S(115)) , cMul ,AnyParams ,0}}, - /* 134: (cMul (cTanh [x])@D4 (cPow [(cSinh [x]) -1])@D4) - * : (cPow [(cCosh [x]) -1]) - */ {ReplaceParams , false, 1,P1(S(116)) , {2,P2(S(187),S(130)) , cMul ,AnyParams ,0}}, - /* 135: (cMul (cSinh [(cMul {% x})])@D5 (cPow [(cCosh [(cMul {-% x})]) -1])@D5) - * : (cTanh [(cMul {% x})]) - */ {ReplaceParams , false, 1,P1(S(188)) , {2,P2(S(172),S(121)) , cMul ,AnyParams ,0}}, - /* 136: (cMul (cSin [(cMul {% x})])@D5 (cPow [(cCos [(cMul {-% x})]) -1])@D5) - * : (cTan [(cMul {% x})]) - */ {ReplaceParams , false, 1,P1(S(181)) , {2,P2(S(164),S(113)) , cMul ,AnyParams ,0}}, - /* 137: (cMul -1 (cTanh [(cMul %@N <1>)])) - * : (cTanh [(cMul -% <1>)]) - */ {ReplaceParams , false, 1,P1(S(192)) , {2,P2(N(2),S(191)) , cMul ,AnyParams ,0}}, - /* 138: (cMul (cAdd {-1 (cPow [% x])})@D5 (cPow [(cAdd {1 (cPow [% x])}) -1])@D5) - * : (cTanh [(cMul {x LOG( % ) 0.5})]) - */ {ReplaceParams , false, 1,P1(S(189)) , {2,P2(S(198),S(137)) , cMul ,AnyParams ,0}}, - /* 139: (cMul (cAdd {1 (cPow [% x])})@D5 (cPow [(cAdd {-1 (cPow [% x])}) -1])@D5) - * : (cPow [(cTanh [(cMul {x LOG( % ) 0.5})]) -1]) - */ {ReplaceParams , false, 1,P1(S(135)) , {2,P2(S(202),S(136)) , cMul ,AnyParams ,0}}, - /* 140: (cMul (cLog [x]) 0.434294481903) - * : (cLog10 [x]) - */ {ReplaceParams , false, 1,P1(S(55)) , {2,P2(S(47),N(7)) , cMul ,AnyParams ,0}}, - /* 141: (cMul (cPow [(cLog [x]) -1]) 2.30258509299) - * : (cPow [(cLog10 [x]) -1]) - */ {ReplaceParams , false, 1,P1(S(124)) , {2,P2(S(122),N(14)) , cMul ,AnyParams ,0}}, - /* 142: (cMul (cLog [x]) 1.44269504089) - * : (cLog2 [x]) - */ {ReplaceParams , false, 1,P1(S(56)) , {2,P2(S(47),N(11)) , cMul ,AnyParams ,0}}, - /* 143: (cMul (cPow [(cLog [x]) -1]) 0.69314718056) - * : (cPow [(cLog2 [x]) -1]) - */ {ReplaceParams , false, 1,P1(S(125)) , {2,P2(S(122),N(9)) , cMul ,AnyParams ,0}}, - /* 144: (cMul (cPow [& y]) (cAdd {(cMul {% (cPow [x@P z])})@D1 %@D1})) - * : % (cAdd {(cPow [& y]) (cPow [& (cAdd {y (cMul {z (cLog [x]) /LOG( & )})})])}) - */ {ReplaceParams , false, 2,P2(P(1),S(229)) , {2,P2(S(84),S(227)) , cMul ,AnyParams ,0}}, - /* 145: (cMul (cPow [& y]) (cAdd {(cMul {% (cPow [x@P z])})@D1 -%@D1})) - * : % (cAdd {(cMul {(cPow [& y]) -1}) (cPow [& (cAdd {y (cMul {z (cLog [x]) /LOG( & )})})])}) - */ {ReplaceParams , false, 2,P2(P(1),S(232)) , {2,P2(S(84),S(231)) , cMul ,AnyParams ,0}}, - /* 146: (cMul (cSinh [x])@D4 (cPow [(cCosh [x]) %])@D4) - * : (cTanh [x]) (cPow [(cCosh [x]) ADD( % 1 )]) - */ {ReplaceParams , false, 2,P2(S(186),S(120)) , {2,P2(S(169),S(119)) , cMul ,AnyParams ,0}}, - /* 147: @L (cMul (cAbs [x])) - * : x - */ {ReplaceParams , true , 1,P1(P(14)) , {1,P1(S(0)) , cMul ,AnyParams ,0}}, - /* 148: @L (cMul %@N) - * : -% - */ {ReplaceParams , true , 1,P1(S(194)) , {1,P1(P(0)) , cMul ,AnyParams ,0}}, - /* 149: (cEqual [(cAbs [x]) 0]) - * : x 0 - */ {ReplaceParams , false, 2,P2(P(14),N(4)) , {2,P2(S(0),N(4)) , cEqual ,PositionalParams,0}}, - /* 150: (cEqual [(cAdd % <1>) &]) - * : (cAdd <1>) ADD( & -% ) - */ {ReplaceParams , false, 2,P2(S(242),S(260)) , {2,P2(S(248),P(9)) , cEqual ,PositionalParams,0}}, - /* 151: (cEqual [(cMul % <1>) &]) - * : (cMul <1>) MUL( & /% ) - */ {ReplaceParams , false, 2,P2(S(331),S(363)) , {2,P2(S(339),P(9)) , cEqual ,PositionalParams,0}}, - /* 152: (cEqual [(cPow [x %]) &]) - * : (cPow [(cPow [x %]) /%]) POW( & /% ) - */ {ReplaceParams , false, 2,P2(S(126),S(156)) , {2,P2(S(77),P(9)) , cEqual ,PositionalParams,0}}, - /* 153: (cEqual [(cAdd % <1>) (cAdd & <2>)]) - * : (cAdd <1>) (cAdd & -% <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(254)) , {2,P2(S(248),S(250)) , cEqual ,PositionalParams,0}}, - /* 154: (cEqual [(cAdd x <1>)@D4 (cAdd x <2>)@D4]) - * : (cAdd <1>) (cAdd <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(243)) , {2,P2(S(251),S(252)) , cEqual ,PositionalParams,0}}, - /* 155: (cEqual [(cMul % <1>) (cMul & <2>)]) - * : (cMul <1>) (cMul & /% <2>) - */ {ReplaceParams , false, 2,P2(S(331),S(342)) , {2,P2(S(339),S(340)) , cEqual ,PositionalParams,0}}, - /* 156: (cEqual [(cPow [%@P x]) &@P]) - * : x MUL( LOG( & ) /LOG( % ) ) - */ {ReplaceParams , false, 2,P2(P(14),S(364)) , {2,P2(S(81),P(13)) , cEqual ,PositionalParams,0}}, - /* 157: (cEqual [(cPow [x %@P]) (cPow [y &@P])]) - * : (cPow [(cPow [x %]) /MIN( % & )]) (cPow [(cPow [y &]) /MIN( % & )]) - */ {ReplaceParams , false, 2,P2(S(127),S(128)) , {2,P2(S(78),S(79)) , cEqual ,PositionalParams,0}}, - /* 158: (cEqual [(cPow [% x])@D1 (cPow [% y])@D1]) - * : x y - */ {ReplaceParams , false, 2,P2(P(14),P(21)) , {2,P2(S(75),S(76)) , cEqual ,PositionalParams,0}}, - /* 159: (cNEqual [(cAbs [x]) 0]) - * : x 0 - */ {ReplaceParams , false, 2,P2(P(14),N(4)) , {2,P2(S(0),N(4)) , cNEqual ,PositionalParams,0}}, - /* 160: (cNEqual [(cAdd % <1>) &]) - * : (cAdd <1>) ADD( & -% ) - */ {ReplaceParams , false, 2,P2(S(242),S(260)) , {2,P2(S(248),P(9)) , cNEqual ,PositionalParams,0}}, - /* 161: (cNEqual [(cMul % <1>) &]) - * : (cMul <1>) MUL( & /% ) - */ {ReplaceParams , false, 2,P2(S(331),S(363)) , {2,P2(S(339),P(9)) , cNEqual ,PositionalParams,0}}, - /* 162: (cNEqual [(cPow [x %]) &]) - * : (cPow [(cPow [x %]) /%]) POW( & /% ) - */ {ReplaceParams , false, 2,P2(S(126),S(156)) , {2,P2(S(77),P(9)) , cNEqual ,PositionalParams,0}}, - /* 163: (cNEqual [(cAdd % <1>) (cAdd & <2>)]) - * : (cAdd <1>) (cAdd & -% <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(254)) , {2,P2(S(248),S(250)) , cNEqual ,PositionalParams,0}}, - /* 164: (cNEqual [(cAdd x <1>)@D4 (cAdd x <2>)@D4]) - * : (cAdd <1>) (cAdd <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(243)) , {2,P2(S(251),S(252)) , cNEqual ,PositionalParams,0}}, - /* 165: (cNEqual [(cMul % <1>) (cMul & <2>)]) - * : (cMul <1>) (cMul & /% <2>) - */ {ReplaceParams , false, 2,P2(S(331),S(342)) , {2,P2(S(339),S(340)) , cNEqual ,PositionalParams,0}}, - /* 166: (cNEqual [(cPow [%@P x]) &@P]) - * : x MUL( LOG( & ) /LOG( % ) ) - */ {ReplaceParams , false, 2,P2(P(14),S(364)) , {2,P2(S(81),P(13)) , cNEqual ,PositionalParams,0}}, - /* 167: (cNEqual [(cPow [x %@P]) (cPow [y &@P])]) - * : (cPow [(cPow [x %]) /MIN( % & )]) (cPow [(cPow [y &]) /MIN( % & )]) - */ {ReplaceParams , false, 2,P2(S(127),S(128)) , {2,P2(S(78),S(79)) , cNEqual ,PositionalParams,0}}, - /* 168: (cNEqual [(cPow [% x])@D1 (cPow [% y])@D1]) - * : x y - */ {ReplaceParams , false, 2,P2(P(14),P(21)) , {2,P2(S(75),S(76)) , cNEqual ,PositionalParams,0}}, - /* 169: (cLess [x 0.5]) - * -> (cAbsNot [x]) - */ {ProduceNewTree, false, 1,P1(S(409)) , {2,P2(P(14),N(8)) , cLess ,PositionalParams,0}}, - /* 170: (cLess [(cAbs [x]) %]) - * -> (cNot [(cMul {x 0.5 /%})]) - */ {ProduceNewTree, false, 1,P1(S(378)) , {2,P2(S(0),P(1)) , cLess ,PositionalParams,0}}, - /* 171: (cLess [(cMul %@P <1>) &]) - * : (cMul <1>) MUL( & /% ) - */ {ReplaceParams , false, 2,P2(S(331),S(363)) , {2,P2(S(336),P(9)) , cLess ,PositionalParams,0}}, - /* 172: (cLess [(cMul %@N <1>) &]) - * : MUL( & /% ) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(363),S(331)) , {2,P2(S(335),P(9)) , cLess ,PositionalParams,0}}, - /* 173: (cLess [(cAdd % <1>) &]) - * : (cAdd <1>) ADD( & -% ) - */ {ReplaceParams , false, 2,P2(S(242),S(260)) , {2,P2(S(248),P(9)) , cLess ,PositionalParams,0}}, - /* 174: (cLess [(cPow [x %]) &]) - * : (cPow [(cPow [x %]) /%]) POW( & /% ) - */ {ReplaceParams , false, 2,P2(S(126),S(156)) , {2,P2(S(77),P(9)) , cLess ,PositionalParams,0}}, - /* 175: (cLess [(cAdd % <1>) (cAdd & <2>)]) - * : (cAdd <1>) (cAdd & -% <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(254)) , {2,P2(S(248),S(250)) , cLess ,PositionalParams,0}}, - /* 176: (cLess [(cAdd x <1>)@D4 (cAdd x <2>)@D4]) - * : (cAdd <1>) (cAdd <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(243)) , {2,P2(S(251),S(252)) , cLess ,PositionalParams,0}}, - /* 177: (cLess [(cMul %@P <1>) (cMul & <2>)]) - * : (cMul <1>) (cMul & /% <2>) - */ {ReplaceParams , false, 2,P2(S(331),S(342)) , {2,P2(S(336),S(340)) , cLess ,PositionalParams,0}}, - /* 178: (cLess [(cMul %@N <1>) (cMul & <2>)]) - * : (cMul & /% <2>) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(342),S(331)) , {2,P2(S(335),S(340)) , cLess ,PositionalParams,0}}, - /* 179: (cLess [(cPow [%@P x]) &@P]) - * : x MUL( LOG( & ) /LOG( % ) ) - */ {ReplaceParams , false, 2,P2(P(14),S(364)) , {2,P2(S(81),P(13)) , cLess ,PositionalParams,0}}, - /* 180: (cLess [(cPow [x %@P]) (cPow [y &@P])]) - * : (cPow [(cPow [x %]) /MIN( % & )]) (cPow [(cPow [y &]) /MIN( % & )]) - */ {ReplaceParams , false, 2,P2(S(127),S(128)) , {2,P2(S(78),S(79)) , cLess ,PositionalParams,0}}, - /* 181: (cLess [(cPow [% x])@D1 (cPow [% y])@D1]) - * : x y - */ {ReplaceParams , false, 2,P2(P(14),P(21)) , {2,P2(S(75),S(76)) , cLess ,PositionalParams,0}}, - /* 182: (cLessOrEq [% (cAbs [x])]) - * -> (cNotNot [(cMul {x 0.5 /%})]) - */ {ProduceNewTree, false, 1,P1(S(403)) , {2,P2(P(1),S(0)) , cLessOrEq ,PositionalParams,0}}, - /* 183: (cLessOrEq [(cMul %@P <1>) &]) - * : (cMul <1>) MUL( & /% ) - */ {ReplaceParams , false, 2,P2(S(331),S(363)) , {2,P2(S(336),P(9)) , cLessOrEq ,PositionalParams,0}}, - /* 184: (cLessOrEq [(cMul %@N <1>) &]) - * : MUL( & /% ) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(363),S(331)) , {2,P2(S(335),P(9)) , cLessOrEq ,PositionalParams,0}}, - /* 185: (cLessOrEq [(cAdd % <1>) &]) - * : (cAdd <1>) ADD( & -% ) - */ {ReplaceParams , false, 2,P2(S(242),S(260)) , {2,P2(S(248),P(9)) , cLessOrEq ,PositionalParams,0}}, - /* 186: (cLessOrEq [(cPow [x %]) &]) - * : (cPow [(cPow [x %]) /%]) POW( & /% ) - */ {ReplaceParams , false, 2,P2(S(126),S(156)) , {2,P2(S(77),P(9)) , cLessOrEq ,PositionalParams,0}}, - /* 187: (cLessOrEq [(cAdd % <1>) (cAdd & <2>)]) - * : (cAdd <1>) (cAdd & -% <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(254)) , {2,P2(S(248),S(250)) , cLessOrEq ,PositionalParams,0}}, - /* 188: (cLessOrEq [(cAdd x <1>)@D4 (cAdd x <2>)@D4]) - * : (cAdd <1>) (cAdd <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(243)) , {2,P2(S(251),S(252)) , cLessOrEq ,PositionalParams,0}}, - /* 189: (cLessOrEq [(cMul %@P <1>) (cMul & <2>)]) - * : (cMul <1>) (cMul & /% <2>) - */ {ReplaceParams , false, 2,P2(S(331),S(342)) , {2,P2(S(336),S(340)) , cLessOrEq ,PositionalParams,0}}, - /* 190: (cLessOrEq [(cMul %@N <1>) (cMul & <2>)]) - * : (cMul & /% <2>) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(342),S(331)) , {2,P2(S(335),S(340)) , cLessOrEq ,PositionalParams,0}}, - /* 191: (cLessOrEq [(cPow [%@P x]) &@P]) - * : x MUL( LOG( & ) /LOG( % ) ) - */ {ReplaceParams , false, 2,P2(P(14),S(364)) , {2,P2(S(81),P(13)) , cLessOrEq ,PositionalParams,0}}, - /* 192: (cLessOrEq [(cPow [x %@P]) (cPow [y &@P])]) - * : (cPow [(cPow [x %]) /MIN( % & )]) (cPow [(cPow [y &]) /MIN( % & )]) - */ {ReplaceParams , false, 2,P2(S(127),S(128)) , {2,P2(S(78),S(79)) , cLessOrEq ,PositionalParams,0}}, - /* 193: (cLessOrEq [(cPow [% x])@D1 (cPow [% y])@D1]) - * : x y - */ {ReplaceParams , false, 2,P2(P(14),P(21)) , {2,P2(S(75),S(76)) , cLessOrEq ,PositionalParams,0}}, - /* 194: (cGreater [(cMul %@P <1>) &]) - * : (cMul <1>) MUL( & /% ) - */ {ReplaceParams , false, 2,P2(S(331),S(363)) , {2,P2(S(336),P(9)) , cGreater ,PositionalParams,0}}, - /* 195: (cGreater [(cMul %@N <1>) &]) - * : MUL( & /% ) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(363),S(331)) , {2,P2(S(335),P(9)) , cGreater ,PositionalParams,0}}, - /* 196: (cGreater [(cAdd % <1>) &]) - * : (cAdd <1>) ADD( & -% ) - */ {ReplaceParams , false, 2,P2(S(242),S(260)) , {2,P2(S(248),P(9)) , cGreater ,PositionalParams,0}}, - /* 197: (cGreater [(cPow [x %]) &]) - * : (cPow [(cPow [x %]) /%]) POW( & /% ) - */ {ReplaceParams , false, 2,P2(S(126),S(156)) , {2,P2(S(77),P(9)) , cGreater ,PositionalParams,0}}, - /* 198: (cGreater [(cAdd % <1>) (cAdd & <2>)]) - * : (cAdd <1>) (cAdd & -% <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(254)) , {2,P2(S(248),S(250)) , cGreater ,PositionalParams,0}}, - /* 199: (cGreater [(cAdd x <1>)@D4 (cAdd x <2>)@D4]) - * : (cAdd <1>) (cAdd <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(243)) , {2,P2(S(251),S(252)) , cGreater ,PositionalParams,0}}, - /* 200: (cGreater [(cMul %@P <1>) (cMul & <2>)]) - * : (cMul <1>) (cMul & /% <2>) - */ {ReplaceParams , false, 2,P2(S(331),S(342)) , {2,P2(S(336),S(340)) , cGreater ,PositionalParams,0}}, - /* 201: (cGreater [(cMul %@N <1>) (cMul & <2>)]) - * : (cMul & /% <2>) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(342),S(331)) , {2,P2(S(335),S(340)) , cGreater ,PositionalParams,0}}, - /* 202: (cGreater [(cPow [%@P x]) &@P]) - * : x MUL( LOG( & ) /LOG( % ) ) - */ {ReplaceParams , false, 2,P2(P(14),S(364)) , {2,P2(S(81),P(13)) , cGreater ,PositionalParams,0}}, - /* 203: (cGreater [(cPow [x %@P]) (cPow [y &@P])]) - * : (cPow [(cPow [x %]) /MIN( % & )]) (cPow [(cPow [y &]) /MIN( % & )]) - */ {ReplaceParams , false, 2,P2(S(127),S(128)) , {2,P2(S(78),S(79)) , cGreater ,PositionalParams,0}}, - /* 204: (cGreater [(cPow [% x])@D1 (cPow [% y])@D1]) - * : x y - */ {ReplaceParams , false, 2,P2(P(14),P(21)) , {2,P2(S(75),S(76)) , cGreater ,PositionalParams,0}}, - /* 205: (cGreaterOrEq [x 0.5]) - * -> (cAbsNotNot [x]) - */ {ProduceNewTree, false, 1,P1(S(410)) , {2,P2(P(14),N(8)) , cGreaterOrEq,PositionalParams,0}}, - /* 206: (cGreaterOrEq [(cMul %@P <1>) &]) - * : (cMul <1>) MUL( & /% ) - */ {ReplaceParams , false, 2,P2(S(331),S(363)) , {2,P2(S(336),P(9)) , cGreaterOrEq,PositionalParams,0}}, - /* 207: (cGreaterOrEq [(cMul %@N <1>) &]) - * : MUL( & /% ) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(363),S(331)) , {2,P2(S(335),P(9)) , cGreaterOrEq,PositionalParams,0}}, - /* 208: (cGreaterOrEq [(cAdd % <1>) &]) - * : (cAdd <1>) ADD( & -% ) - */ {ReplaceParams , false, 2,P2(S(242),S(260)) , {2,P2(S(248),P(9)) , cGreaterOrEq,PositionalParams,0}}, - /* 209: (cGreaterOrEq [(cPow [x %]) &]) - * : (cPow [(cPow [x %]) /%]) POW( & /% ) - */ {ReplaceParams , false, 2,P2(S(126),S(156)) , {2,P2(S(77),P(9)) , cGreaterOrEq,PositionalParams,0}}, - /* 210: (cGreaterOrEq [(cAdd % <1>) (cAdd & <2>)]) - * : (cAdd <1>) (cAdd & -% <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(254)) , {2,P2(S(248),S(250)) , cGreaterOrEq,PositionalParams,0}}, - /* 211: (cGreaterOrEq [(cAdd x <1>)@D4 (cAdd x <2>)@D4]) - * : (cAdd <1>) (cAdd <2>) - */ {ReplaceParams , false, 2,P2(S(242),S(243)) , {2,P2(S(251),S(252)) , cGreaterOrEq,PositionalParams,0}}, - /* 212: (cGreaterOrEq [(cMul %@P <1>) (cMul & <2>)]) - * : (cMul <1>) (cMul & /% <2>) - */ {ReplaceParams , false, 2,P2(S(331),S(342)) , {2,P2(S(336),S(340)) , cGreaterOrEq,PositionalParams,0}}, - /* 213: (cGreaterOrEq [(cMul %@N <1>) (cMul & <2>)]) - * : (cMul & /% <2>) (cMul <1>) - */ {ReplaceParams , false, 2,P2(S(342),S(331)) , {2,P2(S(335),S(340)) , cGreaterOrEq,PositionalParams,0}}, - /* 214: (cGreaterOrEq [(cPow [%@P x]) &@P]) - * : x MUL( LOG( & ) /LOG( % ) ) - */ {ReplaceParams , false, 2,P2(P(14),S(364)) , {2,P2(S(81),P(13)) , cGreaterOrEq,PositionalParams,0}}, - /* 215: (cGreaterOrEq [(cPow [x %@P]) (cPow [y &@P])]) - * : (cPow [(cPow [x %]) /MIN( % & )]) (cPow [(cPow [y &]) /MIN( % & )]) - */ {ReplaceParams , false, 2,P2(S(127),S(128)) , {2,P2(S(78),S(79)) , cGreaterOrEq,PositionalParams,0}}, - /* 216: (cGreaterOrEq [(cPow [% x])@D1 (cPow [% y])@D1]) - * : x y - */ {ReplaceParams , false, 2,P2(P(14),P(21)) , {2,P2(S(75),S(76)) , cGreaterOrEq,PositionalParams,0}}, - /* 217: (cNot [x@P]) - * -> (cAbsNot [x]) - */ {ProduceNewTree, false, 1,P1(S(409)) , {1,P1(P(17)) , cNot ,PositionalParams,0}}, - /* 218: (cAnd x@L <1>) - * -> (cNotNot [(cMul {x (cAnd <1>)})]) - */ {ProduceNewTree, false, 1,P1(S(404)) , {1,P1(P(19)) , cAnd ,AnyParams ,1}}, - /* 219: (cAnd x@P y@P <1>) - * -> (cAbsAnd {x y (cAnd <1>)}) - */ {ProduceNewTree, false, 1,P1(S(407)) , {2,P2(P(17),P(27)) , cAnd ,AnyParams ,1}}, - /* 220: (cAnd x y) - * -> (cIf [x (cNotNot [y]) 0]) - */ {ProduceNewTree, false, 1,P1(S(45)) , {2,P2(P(14),P(21)) , cAnd ,AnyParams ,0}}, - /* 221: (cAnd (cIf [x y z])@D4 (cIf [x a b])@D4) - * : (cIf [x (cAnd {y a}) (cAnd {z b})]) - */ {ReplaceParams , false, 1,P1(S(43)) , {2,P2(S(32),S(36)) , cAnd ,AnyParams ,0}}, - /* 222: (cAnd (cNot [x]) (cNot [y])) - * : (cNot [(cOr {x y})]) - */ {ReplaceParams , false, 1,P1(S(382)) , {2,P2(S(375),S(376)) , cAnd ,AnyParams ,0}}, - /* 223: (cAnd (cNot [z]) (cIf [x (cNot [y]) %@L])) - * : (cNot [(cOr {z (cIf [x y (cNot [%])])})]) - */ {ReplaceParams , false, 1,P1(S(383)) , {2,P2(S(377),S(38)) , cAnd ,AnyParams ,0}}, - /* 224: (cAnd (cNot [z]) (cIf [x %@L (cNot [y])])) - * : (cNot [(cOr {z (cIf [x (cNot [%]) y])})]) - */ {ReplaceParams , false, 1,P1(S(384)) , {2,P2(S(377),S(34)) , cAnd ,AnyParams ,0}}, - /* 225: (cAnd (cEqual [x y])@D12 (cEqual [y z])@D24 (cEqual [x z])@D20) - * : (cEqual [x y]) (cEqual [y z]) - */ {ReplaceParams , false, 2,P2(S(366),S(369)) , {3,P3(S(365),S(368),S(367)), cAnd ,AnyParams ,0}}, - /* 226: (cOr x@P y@P <1>) - * -> (cAbsOr {x y (cOr <1>)}) - */ {ProduceNewTree, false, 1,P1(S(408)) , {2,P2(P(17),P(27)) , cOr ,AnyParams ,1}}, - /* 227: (cOr x y) - * -> (cIf [x 1 (cNotNot [y])]) - */ {ProduceNewTree, false, 1,P1(S(31)) , {2,P2(P(14),P(21)) , cOr ,AnyParams ,0}}, - /* 228: (cOr x@L y@L) - * : (cNotNot [(cAdd {x y})]) - */ {ReplaceParams , false, 1,P1(S(401)) , {2,P2(P(19),P(22)) , cOr ,AnyParams ,0}}, - /* 229: (cOr (cIf [x y z])@D4 (cIf [x a b])@D4) - * : (cIf [x (cOr {y a}) (cOr {z b})]) - */ {ReplaceParams , false, 1,P1(S(44)) , {2,P2(S(32),S(36)) , cOr ,AnyParams ,0}}, - /* 230: (cOr (cNot [x]) (cNot [y])) - * : (cNot [(cAnd {x y})]) - */ {ReplaceParams , false, 1,P1(S(379)) , {2,P2(S(375),S(376)) , cOr ,AnyParams ,0}}, - /* 231: (cOr (cNot [z]) (cIf [x (cNot [y]) %@L])) - * : (cNot [(cAnd {z (cIf [x y (cNot [%])])})]) - */ {ReplaceParams , false, 1,P1(S(380)) , {2,P2(S(377),S(38)) , cOr ,AnyParams ,0}}, - /* 232: (cOr (cNot [z]) (cIf [x %@L (cNot [y])])) - * : (cNot [(cAnd {z (cIf [x (cNot [%]) y])})]) - */ {ReplaceParams , false, 1,P1(S(381)) , {2,P2(S(377),S(34)) , cOr ,AnyParams ,0}}, - /* 233: (cOr x@L (cAdd <1>)@P) - * : (cNotNot [(cAdd x <1>)]) - */ {ReplaceParams , false, 1,P1(S(402)) , {2,P2(P(19),S(244)) , cOr ,AnyParams ,0}}, - /* 234: (cNotNot [x@P]) - * -> (cAbsNotNot [x]) - */ {ProduceNewTree, false, 1,P1(S(410)) , {1,P1(P(17)) , cNotNot ,PositionalParams,0}}, - /* 235: @L (cNotNot [x]) - * -> x - */ {ProduceNewTree, true , 1,P1(P(14)) , {1,P1(P(14)) , cNotNot ,PositionalParams,0}}, - /* 236: (cAbsAnd x y) - * -> (cAbsIf [x (cAbsNotNot [y]) 0]) - */ {ProduceNewTree, false, 1,P1(S(416)) , {2,P2(P(14),P(21)) , cAbsAnd ,AnyParams ,0}}, - /* 237: (cAbsOr x y) - * -> (cAbsIf [x 1 (cAbsNotNot [y])]) - */ {ProduceNewTree, false, 1,P1(S(413)) , {2,P2(P(14),P(21)) , cAbsOr ,AnyParams ,0}}, - /* 238: @L (cAbsNotNot [x]) - * -> x - */ {ProduceNewTree, true , 1,P1(P(14)) , {1,P1(P(14)) , cAbsNotNot ,PositionalParams,0}}, - /* 239: (cAbsIf [(cNotNot [x]) y z]) - * -> (cIf [x y z]) - */ {ProduceNewTree, false, 1,P1(S(33)) , {3,P3(S(399),P(21),P(28)) , cAbsIf ,PositionalParams,0}}, - /* 240: (cAbsIf [(cLessOrEq [x y]) z a]) - * : (cLess [y x]) a z - */ {ReplaceParams , false, 3,P3(S(371),P(31),P(28)) , {3,P3(S(373),P(28),P(31)) , cAbsIf ,PositionalParams,0}}, - }; -#undef P -#undef N -#undef S - - struct grammar_optimize_abslogical_type - { - unsigned c; - unsigned char l[12]; - }; - extern "C" - { - grammar_optimize_abslogical_type grammar_optimize_abslogical = - { - 12, - { 19,29,30,169,205,217,219,226,234,238, - 239,240 - } }; } - struct grammar_optimize_ignore_if_sideeffects_type - { - unsigned c; - unsigned char l[34]; - }; - extern "C" - { - grammar_optimize_ignore_if_sideeffects_type grammar_optimize_ignore_if_sideeffects = - { - 34, - { 0,18,20,21,22,23,24,25,26,27, - 28,37,39,75,109,110,111,112,147,148, - 149,159,170,182,221,222,223,224,225,229, - 230,231,232,235 - } }; } - struct grammar_optimize_nonshortcut_logical_evaluation_type - { - unsigned c; - unsigned char l[31]; - }; - extern "C" - { - grammar_optimize_nonshortcut_logical_evaluation_type grammar_optimize_nonshortcut_logical_evaluation = - { - 31, - { 0,25,26,27,28,37,39,75,109,110, - 111,112,147,148,149,159,170,182,218,221, - 222,223,224,225,228,229,230,231,232,233, - 235 - } }; } - struct grammar_optimize_round1_type - { - unsigned c; - unsigned char l[92]; - }; - extern "C" - { - grammar_optimize_round1_type grammar_optimize_round1 = - { - 92, - { 0,1,2,3,4,5,6,7,8,9, - 10,11,15,16,25,26,27,28,31,32, - 33,36,37,38,39,40,41,42,43,44, - 45,46,47,48,49,53,54,55,56,57, - 58,59,60,61,62,63,70,75,76,77, - 78,79,80,81,82,83,84,85,86,87, - 88,104,108,109,110,111,112,113,114,115, - 116,117,118,119,144,145,147,148,149,159, - 170,182,221,222,223,224,225,229,230,231, - 232,235 - } }; } - struct grammar_optimize_round2_type - { - unsigned c; - unsigned char l[81]; - }; - extern "C" - { - grammar_optimize_round2_type grammar_optimize_round2 = - { - 81, - { 0,5,12,13,14,15,25,26,27,28, - 31,34,35,36,37,38,39,40,42,43, - 44,45,46,47,48,49,57,58,59,64, - 65,70,71,72,73,74,75,89,90,91, - 92,93,94,95,96,97,98,99,100,101, - 102,103,108,109,110,111,112,113,116,117, - 118,120,144,145,146,147,148,149,159,170, - 182,221,222,223,224,225,229,230,231,232, - 235 - } }; } - struct grammar_optimize_round3_type - { - unsigned c; - unsigned char l[85]; - }; - extern "C" - { - grammar_optimize_round3_type grammar_optimize_round3 = - { - 85, - { 66,67,68,69,121,122,123,124,125,126, - 127,128,129,130,131,132,133,134,135,136, - 137,138,139,150,151,152,153,154,155,156, - 157,158,160,161,162,163,164,165,166,167, - 168,171,172,173,174,175,176,177,178,179, - 180,181,183,184,185,186,187,188,189,190, - 191,192,193,194,195,196,197,198,199,200, - 201,202,203,204,206,207,208,209,210,211, - 212,213,214,215,216 - } }; } - struct grammar_optimize_round4_type - { - unsigned c; - unsigned char l[10]; - }; - extern "C" - { - grammar_optimize_round4_type grammar_optimize_round4 = - { - 10, - { 17,50,51,52,106,107,140,141,142,143 - } }; } - struct grammar_optimize_shortcut_logical_evaluation_type - { - unsigned c; - unsigned char l[33]; - }; - extern "C" - { - grammar_optimize_shortcut_logical_evaluation_type grammar_optimize_shortcut_logical_evaluation = - { - 33, - { 0,25,26,27,28,37,39,75,105,109, - 110,111,112,147,148,149,159,170,182,220, - 221,222,223,224,225,227,229,230,231,232, - 235,236,237 - } }; } -} -#undef P1 -#undef P2 -#undef P3 - -namespace FPoptimizer_Grammar -{ - ParamSpec ParamSpec_Extract(unsigned paramlist, unsigned index) - { - index = (paramlist >> (index * PARAM_INDEX_BITS)) % (1 << PARAM_INDEX_BITS); - const unsigned p_begin = 0; - const unsigned n_begin = p_begin + sizeof(plist.plist_p)/sizeof(*plist.plist_p); - const unsigned s_begin = n_begin + sizeof(plist.plist_n)/sizeof(*plist.plist_n); - /*const unsigned end = s_begin + sizeof(plist.plist_s)/sizeof(*plist.plist_s);*/ - if(index < s_begin) - { - if(index < n_begin) - return ParamSpec(ParamHolder,(const void*)&plist.plist_p[index-p_begin]); - else - return ParamSpec(NumConstant,(const void*)&plist.plist_n[index-n_begin]); - } - else - return ParamSpec(SubFunction,(const void*)&plist.plist_s[index-s_begin]); - } -} - -#line 1 "fpoptimizer/fpoptimizer_optimize.c" -#include "fpconfig.h" -#include "fparser.h" -#include "fptypes.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -// line removed for fpoptimizer.c: #include "fpoptimizer_grammar.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_opcodename.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" - -#include - -#include -#include -#include - -using namespace FUNCTIONPARSERTYPES; -using namespace FPoptimizer_Grammar; -using namespace FPoptimizer_CodeTree; -using namespace FPoptimizer_Optimize; - -namespace -{ - /* I have heard that std::equal_range() is practically worthless - * due to the insane limitation that the two parameters for Comp() must - * be of the same type. Hence we must reinvent the wheel and implement - * our own here. This is practically identical to the one from - * GNU libstdc++, except rewritten. -Bisqwit - */ - template - std::pair - MyEqualRange(It first, It last, const T& val, Comp comp) - { - size_t len = last-first; - while(len > 0) - { - size_t half = len/2; - It middle(first); middle += half; - if(comp(*middle, val)) - { - first = middle; - ++first; - len = len - half - 1; - } - else if(comp(val, *middle)) - { - len = half; - } - else - { - // The following implements this: - // // left = lower_bound(first, middle, val, comp); - It left(first); - {/// - It& first2 = left; - It last2(middle); - size_t len2 = last2-first2; - while(len2 > 0) - { - size_t half2 = len2 / 2; - It middle2(first2); middle2 += half2; - if(comp(*middle2, val)) - { - first2 = middle2; - ++first2; - len2 = len2 - half2 - 1; - } - else - len2 = half2; - } - // left = first2; - not needed, already happens due to reference - }/// - first += len; - // The following implements this: - // // right = upper_bound(++middle, first, val, comp); - It right(++middle); - {/// - It& first2 = right; - It& last2 = first; - size_t len2 = last2-first2; - while(len2 > 0) - { - size_t half2 = len2 / 2; - It middle2(first2); middle2 += half2; - if(comp(val, *middle2)) - len2 = half2; - else - { - first2 = middle2; - ++first2; - len2 = len2 - half2 - 1; - } - } - // right = first2; - not needed, already happens due to reference - }/// - return std::pair (left,right); - } - } - return std::pair (first,first); - } - - /* A helper for std::equal_range */ - struct OpcodeRuleCompare - { - bool operator() (const CodeTree& tree, - unsigned rulenumber) const - { - /* If this function returns true, len=half. - */ - const Rule& rule = grammar_rules[rulenumber]; - return tree.GetOpcode() < rule.match_tree.subfunc_opcode; - } - bool operator() (unsigned rulenumber, - const CodeTree& tree) const - { - /* If this function returns true, rule will be excluded from the equal_range - */ - const Rule& rule = grammar_rules[rulenumber]; - return rule.match_tree.subfunc_opcode < tree.GetOpcode(); - } - }; - - /* Test and apply a rule to a given CodeTree */ - bool TestRuleAndApplyIfMatch( - const Rule& rule, - CodeTree& tree, - bool from_logical_context) - { - MatchInfo info; - - MatchResultType found(false, MatchPositionSpecBaseP()); - - if(rule.logical_context && !from_logical_context) - { - /* If the rule only applies in logical contexts, - * but we do not have a logical context, fail the rule - */ - goto fail; - } - - /*std::cout << "TESTING: "; - DumpMatch(rule, *tree, info, false);*/ - - for(;;) - { - #ifdef DEBUG_SUBSTITUTIONS - //DumpMatch(rule, tree, info, "Testing"); - #endif - found = TestParams(rule.match_tree, tree, found.specs, info, true); - if(found.found) break; - if(!&*found.specs) - { - fail:; - // Did not match - #ifdef DEBUG_SUBSTITUTIONS - DumpMatch(rule, tree, info, false); - #endif - return false; - } - } - // Matched - #ifdef DEBUG_SUBSTITUTIONS - DumpMatch(rule, tree, info, true); - #endif - SynthesizeRule(rule, tree, info); - return true; - } -} - -namespace FPoptimizer_Optimize -{ - /* Apply the grammar to a given CodeTree */ - bool ApplyGrammar( - const Grammar& grammar, - CodeTree& tree, - bool from_logical_context) - { - if(tree.GetOptimizedUsing() == &grammar) - { -#ifdef DEBUG_SUBSTITUTIONS - std::cout << "Already optimized: "; - DumpTree(tree); - std::cout << "\n" << std::flush; -#endif - return false; - } - - /* First optimize all children */ - if(true) - { - bool changed = false; - - switch(tree.GetOpcode()) - { - case cNot: - case cNotNot: - case cAnd: - case cOr: - for(size_t a=0; a range = - MyEqualRange(grammar.rule_list, - grammar.rule_list + grammar.rule_count, - tree, - OpcodeRuleCompare()); - - if(range.first != range.second) - { -#ifdef DEBUG_SUBSTITUTIONS - std::vector rules; - rules.reserve(range.second - range.first); - for(rulenumit r = range.first; r != range.second; ++r) - { - //if(grammar_rules[*r].match_tree.subfunc_opcode != tree.GetOpcode()) continue; - if(IsLogisticallyPlausibleParamsMatch(grammar_rules[*r].match_tree, tree)) - rules.push_back(*r); - } - range.first = &rules[0]; - range.second = &rules[rules.size()-1]+1; - - if(range.first != range.second) - { - std::cout << "Input (" << FP_GetOpcodeName(tree.GetOpcode()) - << ")[" << tree.GetParamCount() - << "]"; - if(from_logical_context) - std::cout << "(Logical)"; - - unsigned first=~unsigned(0), prev=~unsigned(0); - const char* sep = ", rules "; - for(rulenumit r = range.first; r != range.second; ++r) - { - if(first==~unsigned(0)) first=prev=*r; - else if(*r == prev+1) prev=*r; - else - { - std::cout << sep << first; sep=","; - if(prev != first) std::cout << '-' << prev; - first = prev = *r; - } - } - if(first != ~unsigned(0)) - { - std::cout << sep << first; - if(prev != first) std::cout << '-' << prev; - } - std::cout << ": "; - DumpTree(tree); - std::cout << "\n" << std::flush; - } -#endif - - bool changed = false; - - for(rulenumit r = range.first; r != range.second; ++r) - { - #ifndef DEBUG_SUBSTITUTIONS - if(!IsLogisticallyPlausibleParamsMatch(grammar_rules[*r].match_tree, tree)) - continue; - #endif - if(TestRuleAndApplyIfMatch(grammar_rules[*r], tree, from_logical_context)) - { - changed = true; - break; - } - } - - if(changed) - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Changed." << std::endl; - std::cout << "Output: "; - DumpTree(tree); - std::cout << "\n" << std::flush; - #endif - // Give the parent node a rerun at optimization - tree.Mark_Incompletely_Hashed(); - return true; - } - } - - // No changes, consider the tree properly optimized. - tree.SetOptimizedUsing(&grammar); - return false; - } - - void ApplyGrammars(FPoptimizer_CodeTree::CodeTree& tree) - { - #ifdef FPOPTIMIZER_MERGED_FILE - #define C *(const Grammar*)& - #else - #define C - #endif - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_round1\n"; - #endif - while(ApplyGrammar(C grammar_optimize_round1, tree)) - { //std::cout << "Rerunning 1\n"; - tree.FixIncompleteHashes(); - } - - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_round2\n"; - #endif - while(ApplyGrammar(C grammar_optimize_round2, tree)) - { //std::cout << "Rerunning 2\n"; - tree.FixIncompleteHashes(); - } - - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_round3\n"; - #endif - while(ApplyGrammar(C grammar_optimize_round3, tree)) - { //std::cout << "Rerunning 3\n"; - tree.FixIncompleteHashes(); - } - - #ifndef FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_nonshortcut_logical_evaluation\n"; - #endif - while(ApplyGrammar(C grammar_optimize_nonshortcut_logical_evaluation, tree)) - { //std::cout << "Rerunning 3\n"; - tree.FixIncompleteHashes(); - } - #endif - - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_round4\n"; - #endif - while(ApplyGrammar(C grammar_optimize_round4, tree)) - { //std::cout << "Rerunning 4\n"; - tree.FixIncompleteHashes(); - } - - #ifdef FP_ENABLE_SHORTCUT_LOGICAL_EVALUATION - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_shortcut_logical_evaluation\n"; - #endif - while(ApplyGrammar(C grammar_optimize_shortcut_logical_evaluation, tree)) - { //std::cout << "Rerunning 3\n"; - tree.FixIncompleteHashes(); - } - #endif - - #ifdef FP_ENABLE_IGNORE_IF_SIDEEFFECTS - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_ignore_if_sideeffects\n"; - #endif - while(ApplyGrammar(C grammar_optimize_ignore_if_sideeffects, tree)) - { //std::cout << "Rerunning 3\n"; - tree.FixIncompleteHashes(); - } - #endif - - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Applying grammar_optimize_abslogical\n"; - #endif - while(ApplyGrammar(C grammar_optimize_abslogical, tree)) - { //std::cout << "Rerunning 3\n"; - tree.FixIncompleteHashes(); - } - - #undef C - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_optimize_match.c" -#include "fpconfig.h" -#include "fparser.h" -#include "fptypes.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -#include -#include -#include -#include - -#include /* for auto_ptr */ - -// line removed for fpoptimizer.c: #include "fpoptimizer_grammar.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" - -using namespace FUNCTIONPARSERTYPES; -using namespace FPoptimizer_Grammar; -using namespace FPoptimizer_CodeTree; -using namespace FPoptimizer_Optimize; - -namespace -{ - /* Test the given constraints to a given CodeTree */ - bool TestImmedConstraints(unsigned bitmask, const CodeTree& tree) - { - switch(bitmask & ValueMask) - { - case Value_AnyNum: case ValueMask: break; - case Value_EvenInt: - if(tree.GetEvennessInfo() != CodeTree::IsAlways) - return false; - break; - case Value_OddInt: - if(tree.GetEvennessInfo() != CodeTree::IsNever) - return false; - break; - case Value_IsInteger: - if(!tree.IsAlwaysInteger(true)) return false; - break; - case Value_NonInteger: - if(!tree.IsAlwaysInteger(false)) return false; - break; - case Value_Logical: - if(!tree.IsLogicalValue()) return false; - break; - } - switch(bitmask & SignMask) - { - case Sign_AnySign: /*case SignMask:*/ break; - case Sign_Positive: - if(!tree.IsAlwaysSigned(true)) return false; - break; - case Sign_Negative: - if(!tree.IsAlwaysSigned(false)) return false; - break; - case Sign_NoIdea: - if(tree.IsAlwaysSigned(true)) return false; - if(tree.IsAlwaysSigned(false)) return false; - break; - } - switch(bitmask & OnenessMask) - { - case Oneness_Any: case OnenessMask: break; - case Oneness_One: - if(!tree.IsImmed()) return false; - if(!FloatEqual(fabs(tree.GetImmed()), 1.0)) return false; - break; - case Oneness_NotOne: - if(!tree.IsImmed()) return false; - if(FloatEqual(fabs(tree.GetImmed()), 1.0)) return false; - break; - } - switch(bitmask & ConstnessMask) - { - case Constness_Any: /*case ConstnessMask:*/ break; - case Constness_Const: - if(!tree.IsImmed()) return false; - break; - } - return true; - } - - template - struct nbitmap - { - private: - static const unsigned bits_in_char = 8; - static const unsigned per_item = (sizeof(item_type)*bits_in_char)/nbits; - item_type data[(extent+per_item-1) / per_item]; - public: - void inc(unsigned index, int by=1) - { - data[pos(index)] += by * item_type(1 << shift(index)); - } - inline void dec(unsigned index) { inc(index, -1); } - int get(unsigned index) const { return (data[pos(index)] >> shift(index)) & mask(); } - - static inline unsigned pos(unsigned index) { return index/per_item; } - static inline unsigned shift(unsigned index) { return nbits * (index%per_item); } - static inline unsigned mask() { return (1 << nbits)-1; } - static inline unsigned mask(unsigned index) { return mask() << shift(index); } - }; - - struct Needs - { - int SubTrees : 8; // This many subtrees - int Others : 8; // This many others (namedholder) - int minimum_need : 8; // At least this many leaves (restholder may require more) - int Immeds : 8; // This many immeds - - nbitmap SubTreesDetail; // This many subtrees of each opcode type - - Needs() - { - std::memset(this, 0, sizeof(*this)); - } - Needs(const Needs& b) - { - std::memcpy(this, &b, sizeof(b)); - } - Needs& operator= (const Needs& b) - { - std::memcpy(this, &b, sizeof(b)); - return *this; - } - }; - - Needs CreateNeedList_uncached(const ParamSpec_SubFunctionData& params) - { - Needs NeedList; - - // Figure out what we need - for(unsigned a = 0; a < params.param_count; ++a) - { - const ParamSpec& parampair = ParamSpec_Extract(params.param_list, a); - switch(parampair.first) - { - case SubFunction: - { - const ParamSpec_SubFunction& param = *(const ParamSpec_SubFunction*) parampair.second; - if(param.data.match_type == GroupFunction) - ++NeedList.Immeds; - else - { - ++NeedList.SubTrees; - assert( param.data.subfunc_opcode < VarBegin ); - NeedList.SubTreesDetail.inc(param.data.subfunc_opcode); - } - ++NeedList.minimum_need; - break; - } - case NumConstant: - case ParamHolder: - ++NeedList.Others; - ++NeedList.minimum_need; - break; - } - } - - return NeedList; - } - - Needs& CreateNeedList(const ParamSpec_SubFunctionData& params) - { - typedef std::map needlist_cached_t; - static needlist_cached_t needlist_cached; - - needlist_cached_t::iterator i = needlist_cached.lower_bound(¶ms); - if(i != needlist_cached.end() && i->first == ¶ms) - return i->second; - - return - needlist_cached.insert(i, - std::make_pair(¶ms, CreateNeedList_uncached(params)) - )->second; - } - /* Construct CodeTree from a GroupFunction, hopefully evaluating to a constant value */ - CodeTree CalculateGroupFunction( - const ParamSpec& parampair, - const MatchInfo& info) - { - switch( parampair.first ) - { - case NumConstant: - { - const ParamSpec_NumConstant& param = *(const ParamSpec_NumConstant*) parampair.second; - return CodeTree( param.constvalue ); // Note: calculates hash too. - } - case ParamHolder: - { - const ParamSpec_ParamHolder& param = *(const ParamSpec_ParamHolder*) parampair.second; - return info.GetParamHolderValueIfFound( param.index ); - // If the ParamHolder is not defined, it will simply - // return an Undefined tree. This is ok. - } - case SubFunction: - { - const ParamSpec_SubFunction& param = *(const ParamSpec_SubFunction*) parampair.second; - /* Synthesize a CodeTree which will take care of - * constant-folding our expression. It will also - * indicate whether the result is, in fact, - * a constant at all. */ - CodeTree result; - result.SetOpcode( param.data.subfunc_opcode ); - result.GetParams().reserve(param.data.param_count); - for(unsigned a=0; a 0) --NeedList.Immeds; - else --NeedList.Others; - break; - case VarBegin: - case cFCall: - case cPCall: - --NeedList.Others; - break; - default: - assert( opcode < VarBegin ); - if(NeedList.SubTrees > 0 - && NeedList.SubTreesDetail.get(opcode) > 0) - { - --NeedList.SubTrees; - NeedList.SubTreesDetail.dec(opcode); - } - else --NeedList.Others; - } - } - - // Check whether all needs were satisfied - if(NeedList.Immeds > 0 - || NeedList.SubTrees > 0 - || NeedList.Others > 0) - { - // Something came short, impossible to satisfy. - return false; - } - - if(params.match_type != AnyParams) - { - if(0 - //|| NeedList.Immeds < 0 - already checked - || NeedList.SubTrees < 0 - || NeedList.Others < 0 - //|| params.count != nparams - already checked - ) - { - // Something was too much. - return false; - } - } - return true; - } - - /* Test the given parameter to a given CodeTree */ - MatchResultType TestParam( - const ParamSpec& parampair, - const CodeTree& tree, - const MatchPositionSpecBaseP& start_at, - MatchInfo& info) - { - /*std::cout << "TestParam("; - DumpParam(parampair); - std::cout << ", "; - DumpTree(tree); - std::cout << ")\n";*/ - - /* What kind of param are we expecting */ - switch( parampair.first ) - { - case NumConstant: /* A particular numeric value */ - { - const ParamSpec_NumConstant& param = *(const ParamSpec_NumConstant*) parampair.second; - if(!tree.IsImmed()) return false; - return FloatEqual(tree.GetImmed(), param.constvalue); - } - case ParamHolder: /* Any arbitrary node */ - { - const ParamSpec_ParamHolder& param = *(const ParamSpec_ParamHolder*) parampair.second; - if(!TestImmedConstraints(param.constraints, tree)) return false; - return info.SaveOrTestParamHolder(param.index, tree); - } - case SubFunction: - { - const ParamSpec_SubFunction& param = *(const ParamSpec_SubFunction*) parampair.second; - if(param.data.match_type == GroupFunction) - { /* A constant value acquired from this formula */ - if(!TestImmedConstraints(param.constraints, tree)) return false; - /* Construct the formula */ - CodeTree grammar_func = CalculateGroupFunction(parampair, info); - #ifdef DEBUG_SUBSTITUTIONS - DumpHashes(grammar_func); - std::cout << *(const void**)&grammar_func.GetImmed(); - std::cout << "\n"; - std::cout << *(const void**)&tree.GetImmed(); - std::cout << "\n"; - DumpHashes(tree); - std::cout << "Comparing "; - DumpTree(grammar_func); - std::cout << " and "; - DumpTree(tree); - std::cout << ": "; - std::cout << (grammar_func.IsIdenticalTo(tree) ? "true" : "false"); - std::cout << "\n"; - #endif - /* Evaluate it and compare */ - return grammar_func.IsIdenticalTo(tree); - } - else /* A subtree conforming these specs */ - { - if(!&*start_at) - { - if(!TestImmedConstraints(param.constraints, tree)) return false; - if(tree.GetOpcode() != param.data.subfunc_opcode) return false; - } - return TestParams(param.data, tree, start_at, info, false); - } - } - } - return false; - } - - struct PositionalParams_Rec - { - MatchPositionSpecBaseP start_at; /* child's start_at */ - MatchInfo info; /* backup of "info" at start */ - - PositionalParams_Rec(): start_at(), info() { } - }; - class MatchPositionSpec_PositionalParams - : public MatchPositionSpecBase, - public std::vector - { - public: - explicit MatchPositionSpec_PositionalParams(size_t n) - : MatchPositionSpecBase(), - std::vector (n) - { } - }; - - struct AnyWhere_Rec - { - MatchPositionSpecBaseP start_at; /* child's start_at */ - AnyWhere_Rec() : start_at() { } - }; - class MatchPositionSpec_AnyWhere - : public MatchPositionSpecBase, - public std::vector - { - public: - unsigned trypos; /* which param index to try next */ - - explicit MatchPositionSpec_AnyWhere(size_t n) - : MatchPositionSpecBase(), - std::vector (n), - trypos(0) - { } - }; - - MatchResultType TestParam_AnyWhere( - const ParamSpec& parampair, - const CodeTree& tree, - const MatchPositionSpecBaseP& start_at, - MatchInfo& info, - std::vector& used, - bool TopLevel) - { - FPOPT_autoptr position; - unsigned a; - if(&*start_at) - { - position = (MatchPositionSpec_AnyWhere*) &*start_at; - a = position->trypos; - goto retry_anywhere_2; - } - else - { - position = new MatchPositionSpec_AnyWhere(tree.GetParamCount()); - a = 0; - } - for(; a < tree.GetParamCount(); ++a) - { - if(used[a]) continue; - - retry_anywhere: - { MatchResultType r = TestParam( - parampair, - tree.GetParam(a), - (*position)[a].start_at, - info); - - (*position)[a].start_at = r.specs; - if(r.found) - { - used[a] = true; // matched - if(TopLevel) info.SaveMatchedParamIndex(a); - - position->trypos = a; // in case of backtrack, try a again - return MatchResultType(true, &*position); - } } - retry_anywhere_2: - if(&*(*position)[a].start_at) // is there another try? - { - goto retry_anywhere; - } - // no, move on - } - return false; - } - - struct AnyParams_Rec - { - MatchPositionSpecBaseP start_at; /* child's start_at */ - MatchInfo info; /* backup of "info" at start */ - std::vector used; /* which params are remaining */ - - explicit AnyParams_Rec(size_t nparams) - : start_at(), info(), used(nparams) { } - }; - class MatchPositionSpec_AnyParams - : public MatchPositionSpecBase, - public std::vector - { - public: - explicit MatchPositionSpec_AnyParams(size_t n, size_t m) - : MatchPositionSpecBase(), - std::vector (n, AnyParams_Rec(m)) - { } - }; - - /* Test the list of parameters to a given CodeTree */ - MatchResultType TestParams( - const ParamSpec_SubFunctionData& model_tree, - const CodeTree& tree, - const MatchPositionSpecBaseP& start_at, - MatchInfo& info, - bool TopLevel) - { - /* When PositionalParams or SelectedParams, verify that - * the number of parameters is exactly as expected. - */ - if(model_tree.match_type != AnyParams) - { - if(model_tree.param_count != tree.GetParamCount()) - return false; - } - - /* Verify that the tree basically conforms the shape we are expecting */ - /* This test is not necessary; it may just save us some work. */ - if(!IsLogisticallyPlausibleParamsMatch(model_tree, tree)) - { - return false; - } - - /* Verify each parameter that they are found in the tree as expected. */ - switch(model_tree.match_type) - { - case PositionalParams: - { - /* Simple: Test all given parameters in succession. */ - FPOPT_autoptr position; - unsigned a; - if(&*start_at) - { - position = (MatchPositionSpec_PositionalParams*) &*start_at; - a = model_tree.param_count - 1; - goto retry_positionalparams_2; - } - else - { - position = new MatchPositionSpec_PositionalParams(model_tree.param_count); - a = 0; - } - - for(; a < model_tree.param_count; ++a) - { - (*position)[a].info = info; - retry_positionalparams: - { MatchResultType r = TestParam( - ParamSpec_Extract(model_tree.param_list, a), - tree.GetParam(a), - (*position)[a].start_at, - info); - - (*position)[a].start_at = r.specs; - if(r.found) - { - continue; - } } - retry_positionalparams_2: - // doesn't match - if(&*(*position)[a].start_at) // is there another try? - { - info = (*position)[a].info; - goto retry_positionalparams; - } - // no, backtrack - if(a > 0) - { - --a; - goto retry_positionalparams_2; - } - // cannot backtrack - info = (*position)[0].info; - return false; - } - if(TopLevel) - for(unsigned a = 0; a < model_tree.param_count; ++a) - info.SaveMatchedParamIndex(a); - return MatchResultType(true, &*position); - } - case SelectedParams: - // same as AnyParams, except that model_tree.count==tree.GetParamCount() - // and that there are no RestHolders - case AnyParams: - { - /* Ensure that all given parameters are found somewhere, in any order */ - - FPOPT_autoptr position; - std::vector used( tree.GetParamCount() ); - std::vector depcodes( model_tree.param_count ); - std::vector test_order( model_tree.param_count ); - for(unsigned a=0; a 0) // this test is not necessary, but it saves from doing - { // duplicate work, because [0] was already saved above. - (*position)[a].info = info; - (*position)[a].used = used; - } - retry_anyparams: - { MatchResultType r = TestParam_AnyWhere( - ParamSpec_Extract(model_tree.param_list, test_order[a]), - tree, - (*position)[a].start_at, - info, - used, - TopLevel); - (*position)[a].start_at = r.specs; - if(r.found) - { - continue; - } } - retry_anyparams_2: - // doesn't match - if(&*(*position)[a].start_at) // is there another try? - { - info = (*position)[a].info; - used = (*position)[a].used; - goto retry_anyparams; - } - // no, backtrack - retry_anyparams_3: - if(a > 0) - { - --a; - goto retry_anyparams_2; - } - // cannot backtrack - info = (*position)[0].info; - return false; - } - retry_anyparams_4: - // Capture anything remaining in the restholder - if(model_tree.restholder_index != 0) - { - //std::vector used_backup(used); - //MatchInfo info_backup(info); - - if(!TopLevel - || !info.HasRestHolder(model_tree.restholder_index)) - { - std::vector matches; - matches.reserve(tree.GetParamCount()); - for(unsigned b = 0; b < tree.GetParamCount(); ++b) - { - if(used[b]) continue; // Ignore subtrees that were already used - // Save this tree to this restholder - - matches.push_back(tree.GetParam(b)); - used[b] = true; - if(TopLevel) info.SaveMatchedParamIndex(b); - } - if(!info.SaveOrTestRestHolder(model_tree.restholder_index, matches)) - { - // Failure at restholder matching. Backtrack if possible. - //used.swap(used_backup); - //info.swap(info_backup); - goto retry_anyparams_3; - } - //std::cout << "Saved restholder " << model_tree.restholder_index << "\n"; - } - else - { - const std::vector& matches - = info.GetRestHolderValues(model_tree.restholder_index); - //std::cout << "Testing restholder " << model_tree.restholder_index << std::flush; - for(size_t a=0; a -#include - -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" - -namespace FPoptimizer_Optimize -{ - /* Synthesize the given grammatic parameter into the codetree */ - void SynthesizeParam( - const ParamSpec& parampair, - CodeTree& tree, - MatchInfo& info, - bool inner = true) - { - switch( parampair.first ) - { - case NumConstant: - { const ParamSpec_NumConstant& param = *(const ParamSpec_NumConstant*) parampair.second; - tree.SetImmed( param.constvalue ); - if(inner) tree.Rehash(false); - break; } - case ParamHolder: - { const ParamSpec_ParamHolder& param = *(const ParamSpec_ParamHolder*) parampair.second; - tree.Become( info.GetParamHolderValue( param.index ) ); - break; } - case SubFunction: - { const ParamSpec_SubFunction& param = *(const ParamSpec_SubFunction*) parampair.second; - tree.SetOpcode( param.data.subfunc_opcode ); - for(unsigned a=0; a < param.data.param_count; ++a) - { - CodeTree nparam; - SynthesizeParam( ParamSpec_Extract(param.data.param_list, a), nparam, info, true ); - tree.AddParamMove(nparam); - } - if(param.data.restholder_index != 0) - { - std::vector trees - ( info.GetRestHolderValues( param.data.restholder_index ) ); - tree.AddParamsMove(trees); - // ^note: this fails if the same restholder is synth'd twice - if(tree.GetParamCount() == 1) - { - /* Convert cMul <1> into <1> when <1> only contains one operand. - * This is redundant code; it is also done in ConstantFolding(), - * but it might be better for performance to do it here, too. - */ - assert(tree.GetOpcode() == cAdd || tree.GetOpcode() == cMul - || tree.GetOpcode() == cMin || tree.GetOpcode() == cMax - || tree.GetOpcode() == cAnd || tree.GetOpcode() == cOr); - tree.Become(tree.GetParam(0)); - } - } - if(inner) - tree.Rehash(); - break; } - } - } - - void SynthesizeRule( - const Rule& rule, - CodeTree& tree, - MatchInfo& info) - { - switch(rule.ruletype) - { - case ProduceNewTree: - { - tree.DelParams(); - SynthesizeParam( ParamSpec_Extract(rule.repl_param_list, 0), tree, info, false ); - break; - } - case ReplaceParams: - default: - { - /* Delete the matched parameters from the source tree */ - std::vector list = info.GetMatchedParamIndexes(); - std::sort(list.begin(), list.end()); - for(size_t a=list.size(); a-->0; ) - tree.DelParam( list[a] ); - - /* Synthesize the replacement params */ - for(unsigned a=0; a < rule.repl_param_count; ++a) - { - CodeTree nparam; - SynthesizeParam( ParamSpec_Extract(rule.repl_param_list, a), nparam, info, true ); - tree.AddParamMove(nparam); - } - break; - } - } - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_optimize_debug.c" -// line removed for fpoptimizer.c: #include "fpoptimizer_grammar.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_opcodename.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" - -#ifdef DEBUG_SUBSTITUTIONS - -#include -#include - -using namespace FUNCTIONPARSERTYPES; -using namespace FPoptimizer_Grammar; -using namespace FPoptimizer_CodeTree; -using namespace FPoptimizer_Optimize; - -namespace FPoptimizer_Grammar -{ - void DumpMatch(const Rule& rule, - const CodeTree& tree, - const MatchInfo& info, - bool DidMatch, - std::ostream& o) - { - DumpMatch(rule,tree,info,DidMatch?"Found match":"Found mismatch",o); - } - - void DumpMatch(const Rule& rule, - const CodeTree& tree, - const MatchInfo& info, - const char* whydump, - std::ostream& o) - { - static const char ParamHolderNames[][2] = {"%","&","x","y","z","a","b","c"}; - - o << whydump - << " (rule " << (&rule - grammar_rules) << ")" - << ":\n" - " Pattern : "; - { ParamSpec tmp; - tmp.first = SubFunction; - ParamSpec_SubFunction tmp2; - tmp2.data = rule.match_tree; - tmp.second = (const void*) &tmp2; - DumpParam(tmp, o); - } - o << "\n" - " Replacement: "; - DumpParams(rule.repl_param_list, rule.repl_param_count, o); - o << "\n"; - - o << - " Tree : "; - DumpTree(tree, o); - o << "\n"; - if(!std::strcmp(whydump,"Found match")) DumpHashes(tree, o); - - for(size_t a=0; a = "; - DumpTree(info.restholder_matches[b].second[a], o); - o << std::endl; - } - } - o << std::flush; - } - -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_hash.c" -#include -#include - -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -#include "fptypes.h" -// line removed for fpoptimizer.c: #include "crc32.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; -//using namespace FPoptimizer_Grammar; - -namespace -{ - bool MarkIncompletes(FPoptimizer_CodeTree::CodeTree& tree) - { - if(tree.Is_Incompletely_Hashed()) - return true; - - bool needs_rehash = false; - for(size_t a=0; aSort(); - data->Recalculate_Hash_NoRecursion(); - } - - void CodeTreeData::Recalculate_Hash_NoRecursion() - { - fphash_t NewHash = { Opcode * FPHASH_CONST(0x3A83A83A83A83A0), - Opcode * FPHASH_CONST(0x1131462E270012B)}; - Depth = 1; - switch(Opcode) - { - case cImmed: - if(Value != 0.0) - { - crc32_t crc = crc32::calc( (const unsigned char*) &Value, - sizeof(Value) ); - NewHash.hash1 ^= crc | (fphash_value_t(crc) << FPHASH_CONST(32)); - NewHash.hash2 += ((~fphash_value_t(crc)) * 3) ^ 1234567; - } - break; // no params - case VarBegin: - NewHash.hash1 ^= (Var<<24) | (Var>>24); - NewHash.hash2 += (fphash_value_t(Var)*5) ^ 2345678; - break; // no params - case cFCall: case cPCall: - { - crc32_t crc = crc32::calc( (const unsigned char*) &Funcno, sizeof(Funcno) ); - NewHash.hash1 ^= (crc<<24) | (crc>>24); - NewHash.hash2 += ((~fphash_value_t(crc)) * 7) ^ 3456789; - /* passthru */ - } - default: - { - size_t MaxChildDepth = 0; - for(size_t a=0; a MaxChildDepth) - MaxChildDepth = Params[a].GetDepth(); - - NewHash.hash1 += (1)*FPHASH_CONST(0x2492492492492492); - NewHash.hash1 *= FPHASH_CONST(1099511628211); - //assert(&*Params[a] != this); - NewHash.hash1 += Params[a].GetHash().hash1; - - NewHash.hash2 += (3)*FPHASH_CONST(0x9ABCD801357); - NewHash.hash2 *= FPHASH_CONST(0xECADB912345); - NewHash.hash2 += (~Params[a].GetHash().hash1) ^ 4567890; - } - Depth += MaxChildDepth; - } - } - if(Hash != NewHash) - { - Hash = NewHash; - OptimizedUsing = 0; - } - } - - void CodeTree::FixIncompleteHashes() - { - MarkIncompletes(*this); - FixIncompletes(*this); - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_makebytecode.c" -#include -#include -#include - -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -#include "fptypes.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_bytecodesynth.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; -//using namespace FPoptimizer_Grammar; - -namespace -{ - using namespace FPoptimizer_CodeTree; - - bool AssembleSequence( - const CodeTree& tree, long count, - const FPoptimizer_ByteCode::SequenceOpCode& sequencing, - FPoptimizer_ByteCode::ByteCodeSynth& synth, - size_t max_bytecode_grow_length); -} - -namespace FPoptimizer_CodeTree -{ - void CodeTree::SynthesizeByteCode( - std::vector& ByteCode, - std::vector& Immed, - size_t& stacktop_max) - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Making bytecode for:\n"; - DumpTreeWithIndent(*this); - #endif - while(RecreateInversionsAndNegations()) - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "One change issued, produced:\n"; - DumpTreeWithIndent(*this); - #endif - FixIncompleteHashes(); - } - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Actually synthesizing, after recreating inv/neg:\n"; - DumpTreeWithIndent(*this); - #endif - - FPoptimizer_ByteCode::ByteCodeSynth synth; - - /* Then synthesize the actual expression */ - SynthesizeByteCode(synth, false); - /* The "false" parameters tells SynthesizeByteCode - * that at the outermost synthesizing level, it does - * not matter if leftover temps are left in the stack. - */ - synth.Pull(ByteCode, Immed, stacktop_max); - } - - void CodeTree::SynthesizeByteCode( - FPoptimizer_ByteCode::ByteCodeSynth& synth, - bool MustPopTemps) const - { - // If the synth can already locate our operand in the stack, - // never mind synthesizing it again, just dup it. - if(synth.FindAndDup(*this)) - { - return; - } - - size_t n_subexpressions_synthesized = SynthCommonSubExpressions(synth); - - switch(GetOpcode()) - { - case VarBegin: - synth.PushVar(GetVar()); - break; - case cImmed: - synth.PushImmed(GetImmed()); - break; - case cAdd: - case cMul: - case cMin: - case cMax: - case cAnd: - case cOr: - case cAbsAnd: - case cAbsOr: - { - if(GetOpcode() == cMul) // Special treatment for cMul sequences - { - // If the paramlist contains an Immed, and that Immed - // fits in a long-integer, try to synthesize it - // as add-sequences instead. - bool did_muli = false; - for(size_t a=0; a 1) - { - // Cumulate at the earliest opportunity. - synth.AddOperation(GetOpcode(), 2); // stack state: -2+1 = -1 - n_stacked = n_stacked - 2 + 1; - } - } - if(n_stacked == 0) - { - // Uh, we got an empty cAdd/cMul/whatever... - // Synthesize a default value. - // This should never happen. - switch(GetOpcode()) - { - case cAdd: - case cOr: - case cAbsOr: - synth.PushImmed(0); - break; - case cMul: - case cAnd: - case cAbsAnd: - synth.PushImmed(1); - break; - case cMin: - case cMax: - //synth.PushImmed(NaN); - synth.PushImmed(0); - break; - default: - break; - } - ++n_stacked; - } - assert(n_stacked == 1); - break; - } - case cPow: - { - const CodeTree& p0 = GetParam(0); - const CodeTree& p1 = GetParam(1); - - if(!p1.IsLongIntegerImmed() - || !AssembleSequence( /* Optimize integer exponents */ - p0, p1.GetLongIntegerImmed(), - FPoptimizer_ByteCode::MulSequence, - synth, - MAX_POWI_BYTECODE_LENGTH) - ) - { - p0.SynthesizeByteCode(synth); - p1.SynthesizeByteCode(synth); - synth.AddOperation(GetOpcode(), 2); // Create a vanilla cPow. - } - break; - } - case cIf: - case cAbsIf: - { - // Assume that the parameter count is 3 as it should. - FPoptimizer_ByteCode::ByteCodeSynth::IfData ifdata; - - GetParam(0).SynthesizeByteCode(synth); // expression - - synth.SynthIfStep1(ifdata, GetOpcode()); - - GetParam(1).SynthesizeByteCode(synth); // true branch - - synth.SynthIfStep2(ifdata); - - GetParam(2).SynthesizeByteCode(synth); // false branch - - synth.SynthIfStep3(ifdata); - break; - } - case cFCall: - case cPCall: - { - // Assume that the parameter count is as it should. - for(size_t a=0; a 0) - { - size_t top = synth.GetStackTop(); - synth.DoPopNMov(top-1-n_subexpressions_synthesized, top-1); - } - } -} - -namespace -{ - bool AssembleSequence( - const CodeTree& tree, long count, - const FPoptimizer_ByteCode::SequenceOpCode& sequencing, - FPoptimizer_ByteCode::ByteCodeSynth& synth, - size_t max_bytecode_grow_length) - { - if(count != 0) - { - FPoptimizer_ByteCode::ByteCodeSynth backup = synth; - - tree.SynthesizeByteCode(synth); - - // Ignore the size generated by subtree - size_t bytecodesize_backup = synth.GetByteCodeSize(); - - FPoptimizer_ByteCode::AssembleSequence(count, sequencing, synth); - - size_t bytecode_grow_amount = synth.GetByteCodeSize() - bytecodesize_backup; - if(bytecode_grow_amount > max_bytecode_grow_length) - { - synth = backup; - return false; - } - return true; - } - else - { - FPoptimizer_ByteCode::AssembleSequence(count, sequencing, synth); - return true; - } - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_readbytecode.c" -#include -#include - -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_opcodename.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_grammar.h" -#include "fptypes.h" - -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" -#include "fparser.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; -//using namespace FPoptimizer_Grammar; - -namespace -{ - using namespace FPoptimizer_CodeTree; - - typedef std::vector FactorStack; - - const struct PowiMuliType - { - unsigned opcode_square; - unsigned opcode_cumulate; - unsigned opcode_invert; - unsigned opcode_half; - unsigned opcode_invhalf; - } iseq_powi = {cSqr,cMul,cInv,cSqrt,cRSqrt}, - iseq_muli = {~unsigned(0), cAdd,cNeg, ~unsigned(0),~unsigned(0) }; - - double ParsePowiMuli( - const PowiMuliType& opcodes, - const std::vector& ByteCode, size_t& IP, - size_t limit, - size_t factor_stack_base, - FactorStack& stack) - { - double result = 1; - while(IP < limit) - { - if(ByteCode[IP] == opcodes.opcode_square) - { - if(!IsIntegerConst(result)) break; - result *= 2; - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invert) - { - result = -result; - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_half) - { - if(IsIntegerConst(result) && result > 0 && ((long)result) % 2 == 0) - break; - result *= 0.5; - ++IP; - continue; - } - if(ByteCode[IP] == opcodes.opcode_invhalf) - { - if(IsIntegerConst(result) && result > 0 && ((long)result) % 2 == 0) - break; - result *= -0.5; - ++IP; - continue; - } - - size_t dup_fetch_pos = IP; - double lhs = 1.0; - - if(ByteCode[IP] == cFetch) - { - unsigned index = ByteCode[++IP]; - if(index < factor_stack_base - || size_t(index-factor_stack_base) >= stack.size()) - { - // It wasn't a powi-fetch after all - IP = dup_fetch_pos; - break; - } - lhs = stack[index - factor_stack_base]; - // Note: ^This assumes that cFetch of recentmost - // is always converted into cDup. - goto dup_or_fetch; - } - if(ByteCode[IP] == cDup) - { - lhs = result; - goto dup_or_fetch; - - dup_or_fetch: - stack.push_back(result); - ++IP; - double subexponent = ParsePowiMuli - (opcodes, - ByteCode, IP, limit, - factor_stack_base, stack); - if(IP >= limit || ByteCode[IP] != opcodes.opcode_cumulate) - { - // It wasn't a powi-dup after all - IP = dup_fetch_pos; - break; - } - ++IP; // skip opcode_cumulate - stack.pop_back(); - result += lhs*subexponent; - continue; - } - break; - } - return result; - } - - double ParsePowiSequence(const std::vector& ByteCode, size_t& IP, - size_t limit, - size_t factor_stack_base) - { - FactorStack stack; - stack.push_back(1.0); - return ParsePowiMuli(iseq_powi, ByteCode, IP, limit, factor_stack_base, stack); - } - - double ParseMuliSequence(const std::vector& ByteCode, size_t& IP, - size_t limit, - size_t factor_stack_base) - { - FactorStack stack; - stack.push_back(1.0); - return ParsePowiMuli(iseq_muli, ByteCode, IP, limit, factor_stack_base, stack); - } - - class CodeTreeParserData - { - public: - explicit CodeTreeParserData(bool k_powi) - : stack(), keep_powi(k_powi) { } - - void Eat(size_t nparams, OPCODE opcode) - { - CodeTree newnode; - newnode.SetOpcode(opcode); - - std::vector params = Pop(nparams); - newnode.SetParamsMove(params); - - if(!keep_powi) - switch(opcode) - { - // asinh: log(x + sqrt(x*x + 1)) - //cAsinh [x] -> cLog (cAdd x (cPow (cAdd (cPow x 2) 1) 0.5)) - // Note: ^ Replacement function refers to x twice - - // acosh: log(x + sqrt(x*x - 1)) - //cAcosh [x] -> cLog (cAdd x (cPow (cAdd (cPow x 2) -1) 0.5)) - - // atanh: log( (1+x) / (1-x)) / 2 - //cAtanh [x] -> cMul (cLog (cMul (cAdd 1 x) (cPow (cAdd 1 (cMul -1 x)) -1))) 0.5 - - // asin: atan2(x, sqrt(1-x*x)) - //cAsin[x] -> cAtan2 [x (cPow [(cAdd 1 (cMul (cPow [x 2] -1)) 0.5])] - - // acos: atan2(sqrt(1-x*x), x) - //cAcos[x] -> cAtan2 [(cPow [(cAdd 1 (cMul (cPow [x 2] -1)) 0.5]) x] - - // The hyperbolic functions themselves are: - // sinh: (exp(x)-exp(-x)) / 2 = exp(-x) * (exp(2*x)-1) / 2 - //cSinh [x] -> cMul 0.5 (cPow [CONSTANT_EI x]) (cAdd [-1 (cPow [CONSTANT_2E x])]) - - // cosh: (exp(x)+exp(-x)) / 2 = exp(-x) * (exp(2*x)+1) / 2 - // cosh(-x) = cosh(x) - //cCosh [x] -> cMul 0.5 (cPow [CONSTANT_EI x]) (cAdd [ 1 (cPow [CONSTANT_2E x])]) - - // tanh: sinh/cosh = (exp(2*x)-1) / (exp(2*x)+1) - //cTanh [x] -> (cMul (cAdd {(cPow [CONSTANT_2E x]) -1}) (cPow [(cAdd {(cPow [CONSTANT_2E x]) 1}) -1])) - case cTanh: - { - CodeTree sinh, cosh; - sinh.SetOpcode(cSinh); sinh.AddParam(newnode.GetParam(0)); sinh.Rehash(); - cosh.SetOpcode(cCosh); cosh.AddParamMove(newnode.GetParam(0)); cosh.Rehash(); - CodeTree pow; - pow.SetOpcode(cPow); - pow.AddParamMove(cosh); - pow.AddParam(CodeTree(-1.0)); - pow.Rehash(); - newnode.SetOpcode(cMul); - newnode.SetParamMove(0, sinh); - newnode.AddParamMove(pow); - break; - } - - // tan: sin/cos - //cTan [x] -> (cMul (cSin [x]) (cPow [(cCos [x]) -1])) - case cTan: - { - CodeTree sin, cos; - sin.SetOpcode(cSin); sin.AddParam(newnode.GetParam(0)); sin.Rehash(); - cos.SetOpcode(cCos); cos.AddParamMove(newnode.GetParam(0)); cos.Rehash(); - CodeTree pow; - pow.SetOpcode(cPow); - pow.AddParamMove(cos); - pow.AddParam(CodeTree(-1.0)); - pow.Rehash(); - newnode.SetOpcode(cMul); - newnode.SetParamMove(0, sin); - newnode.AddParamMove(pow); - break; - } - - case cPow: - { - const CodeTree& p0 = newnode.GetParam(0); - const CodeTree& p1 = newnode.GetParam(1); - if(p1.GetOpcode() == cAdd) - { - // convert x^(a + b) into x^a * x^b just so that - // some optimizations can be run on it. - // For instance, exp(log(x)*-61.1 + log(z)*-59.1) - // won't be changed into exp(log(x*z)*-61.1)*z^2 - // unless we do this. - std::vector mulgroup(p1.GetParamCount()); - for(size_t a=0; a" << FP_GetOpcodeName(newnode.GetOpcode()) - << ": PUSH "; - DumpTree(newnode); - std::cout < params = Pop(nparams); - newnode.SetParamsMove(params); - newnode.Rehash(false); - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "POP " << nparams << ", PUSH "; - DumpTree(newnode); - std::cout << std::endl; - #endif - FindClone(newnode); - stack.push_back(newnode); - } - - void AddConst(double value) - { - CodeTree newnode(value); - FindClone(newnode); - Push(newnode); - } - - void AddVar(unsigned varno) - { - CodeTree newnode(varno, CodeTree::VarTag()); - FindClone(newnode); - Push(newnode); - } - - void SwapLastTwoInStack() - { - stack[stack.size()-1].swap( stack[stack.size()-2] ); - } - - void Dup() - { - Fetch(stack.size()-1); - } - - void Fetch(size_t which) - { - Push(stack[which]); - } - - template - void Push(T tree) - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "PUSH "; - DumpTree(tree); - std::cout << std::endl; - #endif - stack.push_back(tree); - } - - void PopNMov(size_t target, size_t source) - { - stack[target] = stack[source]; - stack.resize(target+1); - } - - CodeTree PullResult() - { - clones.clear(); - CodeTree result(stack.back()); - stack.resize(stack.size()-1); - return result; - } - std::vector Pop(unsigned n_pop) - { - std::vector result(n_pop); - for(unsigned n=0; n::const_iterator - i = clones.lower_bound(tree.GetHash()); - for(; i != clones.end() && i->first == tree.GetHash(); ++i) - { - if(i->second.IsIdenticalTo(tree)) - tree.Become(i->second); - } - if(recurse) - for(size_t a=0; a stack; - std::multimap clones; - - bool keep_powi; - - private: - CodeTreeParserData(const CodeTreeParserData&); - CodeTreeParserData& operator=(const CodeTreeParserData&); - }; - - struct IfInfo - { - CodeTree condition; - CodeTree thenbranch; - size_t endif_location; - }; -} - -namespace FPoptimizer_CodeTree -{ - void CodeTree::GenerateFrom( - const std::vector& ByteCode, - const std::vector& Immed, - const FunctionParser::Data& fpdata, - bool keep_powi) - { - std::vector var_trees; - var_trees.reserve(fpdata.numVariables); - for(unsigned n=0; n& ByteCode, - const std::vector& Immed, - const FunctionParser::Data& fpdata, - const std::vector& var_trees, - bool keep_powi) - { - CodeTreeParserData sim(keep_powi); - std::vector if_stack; - - for(size_t IP=0, DP=0; ; ++IP) - { - after_powi: - while(!if_stack.empty() && - ( // Normal If termination rule: - if_stack.back().endif_location == IP - // This rule matches when cJumps are threaded: - || (IP < ByteCode.size() && ByteCode[IP] == cJump - && if_stack.back().thenbranch.IsDefined()) - )) - { - // The "else" of an "if" ends here - CodeTree elsebranch = sim.PullResult(); - sim.Push(if_stack.back().condition); - sim.Push(if_stack.back().thenbranch); - sim.Push(elsebranch); - sim.Eat(3, cIf); - if_stack.pop_back(); - } - if(IP >= ByteCode.size()) break; - - unsigned opcode = ByteCode[IP]; - if((opcode == cSqr || opcode == cDup - || opcode == cInv || opcode == cNeg - || opcode == cSqrt || opcode == cRSqrt - || opcode == cFetch)) - { - // Parse a powi sequence - size_t was_ip = IP; - double exponent = ParsePowiSequence( - ByteCode, IP, if_stack.empty() ? ByteCode.size() : if_stack.back().endif_location, - sim.GetStackTop()-1); - if(exponent != 1.0) - { - //std::cout << "Found exponent at " << was_ip << ": " << exponent << "\n"; - sim.AddConst(exponent); - sim.Eat(2, cPow); - goto after_powi; - } - if(opcode == cDup - || opcode == cFetch - || opcode == cNeg) - { - double factor = ParseMuliSequence( - ByteCode, IP, if_stack.empty() ? ByteCode.size() : if_stack.back().endif_location, - sim.GetStackTop()-1); - if(factor != 1.0) - { - //std::cout << "Found factor at " << was_ip << ": " << factor << "\n"; - sim.AddConst(factor); - sim.Eat(2, cMul); - goto after_powi; - } - } - IP = was_ip; - } - if(OPCODE(opcode) >= VarBegin) - { - sim.Push(var_trees[opcode-VarBegin]); - } - else - { - switch( OPCODE(opcode) ) - { - // Specials - case cIf: - case cAbsIf: - { - if_stack.resize(if_stack.size() + 1); - CodeTree res( sim.PullResult() ); - if_stack.back().condition.swap( res ); - if_stack.back().endif_location = ByteCode.size(); - IP += 2; // dp,sp for elsebranch are irrelevant. - continue; - } - case cJump: - { - CodeTree res( sim.PullResult() ); - if_stack.back().thenbranch.swap( res ); - if_stack.back().endif_location = ByteCode[IP+1]+1; - IP += 2; - continue; - } - case cImmed: - sim.AddConst(Immed[DP++]); - break; - case cDup: - sim.Dup(); - break; - case cNop: - break; - case cFCall: - { - unsigned funcno = ByteCode[++IP]; - assert(funcno < fpdata.FuncPtrs.size()); - unsigned params = fpdata.FuncPtrs[funcno].params; - sim.EatFunc(params, OPCODE(opcode), funcno); - break; - } - case cPCall: - { - unsigned funcno = ByteCode[++IP]; - assert(funcno < fpdata.FuncParsers.size()); - const FunctionParserBase& p = - *fpdata.FuncParsers[funcno].parserPtr; - unsigned params = fpdata.FuncParsers[funcno].params; - - /* Inline the procedure call */ - /* Works because cPCalls can never recurse */ - std::vector paramlist = sim.Pop(params); - CodeTree pcall_tree; - pcall_tree.GenerateFrom(p.data->ByteCode, p.data->Immed, *p.data, - paramlist); - sim.Push(pcall_tree); - break; - } - // Unary operators requiring special attention - case cInv: // already handled by powi_opt - //sim.Eat(1, cInv); - //break; - sim.AddConst(1); - sim.SwapLastTwoInStack(); - sim.Eat(2, cDiv); - break; - case cNeg: // already handled by powi_opt - sim.Eat(1, cNeg); - break; - sim.AddConst(0); - sim.SwapLastTwoInStack(); - sim.Eat(2, cSub); - break; - case cSqr: // already handled by powi_opt - //sim.Eat(1, cSqr); - //break; - sim.AddConst(2); - sim.Eat(2, cPow); - break; - // Unary functions requiring special attention - case cSqrt: // already handled by powi_opt - sim.AddConst(0.5); - sim.Eat(2, cPow); - break; - case cRSqrt: // already handled by powi_opt - sim.AddConst(-0.5); - sim.Eat(2, cPow); - break; - case cCbrt: - sim.AddConst(1.0 / 3.0); - sim.Eat(2, cPow); - break; - case cDeg: - sim.AddConst(CONSTANT_DR); - sim.Eat(2, cMul); - break; - case cRad: - sim.AddConst(CONSTANT_RD); - sim.Eat(2, cMul); - break; - case cExp: - if(keep_powi) goto default_function_handling; - sim.AddConst(CONSTANT_E); - sim.SwapLastTwoInStack(); - sim.Eat(2, cPow); - break; - case cExp2: // from fpoptimizer - if(keep_powi) goto default_function_handling; - sim.AddConst(2.0); - sim.SwapLastTwoInStack(); - sim.Eat(2, cPow); - break; - case cCot: - sim.Eat(1, cTan); - if(keep_powi) { sim.Eat(1, cInv); break; } - sim.AddConst(-1); - sim.Eat(2, cPow); - break; - case cCsc: - sim.Eat(1, cSin); - if(keep_powi) { sim.Eat(1, cInv); break; } - sim.AddConst(-1); - sim.Eat(2, cPow); - break; - case cSec: - sim.Eat(1, cCos); - if(keep_powi) { sim.Eat(1, cInv); break; } - sim.AddConst(-1); - sim.Eat(2, cPow); - break; - case cInt: // int(x) = floor(x + 0.5) - #ifndef __x86_64 - if(keep_powi) { sim.Eat(1, cInt); break; } - #endif - sim.AddConst(0.5); - sim.Eat(2, cAdd); - sim.Eat(1, cFloor); - break; - case cLog10: - sim.Eat(1, cLog); - sim.AddConst(CONSTANT_L10I); - sim.Eat(2, cMul); - break; - case cLog2: - sim.Eat(1, cLog); - sim.AddConst(CONSTANT_L2I); - sim.Eat(2, cMul); - break; - case cLog2by: // x y -> log(x)*CONSTANT_L2I*y - sim.SwapLastTwoInStack(); // y x - sim.Eat(1, cLog); // y log(x) - sim.AddConst(CONSTANT_L2I); // y log(x) CONSTANT_L2I - sim.Eat(3, cMul); // y*log(x)*CONSTANT_L2I - break; - //case cLog: - // sim.Eat(1, cLog2); - // sim.AddConst(CONSTANT_L2); - // sim.Eat(2, cMul); - // break; - // Binary operators requiring special attention - case cSub: - if(keep_powi) { sim.Eat(2, cSub); break; } - sim.AddConst(-1); - sim.Eat(2, cMul); // -x is x*-1 - sim.Eat(2, cAdd); // Minus is negative adding - break; - case cRSub: // from fpoptimizer - sim.SwapLastTwoInStack(); - if(keep_powi) { sim.Eat(2, cSub); break; } - sim.AddConst(-1); - sim.Eat(2, cMul); // -x is x*-1 - sim.Eat(2, cAdd); - break; - case cDiv: - if(keep_powi) { sim.Eat(2, cDiv); break; } - sim.AddConst(-1); - sim.Eat(2, cPow); // 1/x is x^-1 - sim.Eat(2, cMul); // Divide is inverse multiply - break; - case cRDiv: // from fpoptimizer - sim.SwapLastTwoInStack(); - if(keep_powi) { sim.Eat(2, cDiv); break; } - sim.AddConst(-1); - sim.Eat(2, cPow); // 1/x is x^-1 - sim.Eat(2, cMul); // Divide is inverse multiply - break; - // Binary operators not requiring special attention - case cAdd: case cMul: - case cMod: case cPow: - case cEqual: case cLess: case cGreater: - case cNEqual: case cLessOrEq: case cGreaterOrEq: - case cAnd: case cOr: - case cAbsAnd: case cAbsOr: - sim.Eat(2, OPCODE(opcode)); - break; - // Unary operators not requiring special attention - case cNot: - case cNotNot: // from fpoptimizer - case cAbsNot: - case cAbsNotNot: - sim.Eat(1, OPCODE(opcode)); - break; - // Special opcodes generated by fpoptimizer itself - case cFetch: - sim.Fetch(ByteCode[++IP]); - break; - case cPopNMov: - { - unsigned stackOffs_target = ByteCode[++IP]; - unsigned stackOffs_source = ByteCode[++IP]; - sim.PopNMov(stackOffs_target, stackOffs_source); - break; - } - // Other functions -#ifndef FP_DISABLE_EVAL - case cEval: - { - size_t paramcount = fpdata.numVariables; - sim.Eat(paramcount, OPCODE(opcode)); - break; - } -#endif - - default: - default_function_handling:; - unsigned funcno = opcode-cAbs; - assert(funcno < FUNC_AMOUNT); - const FuncDefinition& func = Functions[funcno]; - sim.Eat(func.params, OPCODE(opcode)); - break; - } - } - } - Become(sim.PullResult()); - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Produced tree:\n"; - DumpTreeWithIndent(*this); - #endif - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_constantfolding.c" -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" - -#include /* for CalculateResultBoundaries() */ -#include - -#include "fpconfig.h" -#include "fparser.h" -#include "fptypes.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; -using namespace FPoptimizer_CodeTree; - -#define FP_MUL_COMBINE_EXPONENTS - -#ifdef _MSC_VER -#include -#define isinf(x) (!_finite(x)) -#endif - -namespace -{ - bool IsLogicalTrueValue(const MinMaxTree& p, bool abs) - { - if(p.has_min && p.min >= 0.5) return true; - if(!abs && p.has_max && p.max <= -0.5) return true; - return false; - } - bool IsLogicalFalseValue(const MinMaxTree& p, bool abs) - { - if(abs) - return p.has_max && p.max < 0.5; - else - return p.has_min && p.has_max - && p.min > -0.5 && p.max < 0.5; - } - int GetLogicalValue(const MinMaxTree& p, bool abs) - { - if(IsLogicalTrueValue(p, abs)) return 1; - if(IsLogicalFalseValue(p, abs)) return 0; - return -1; - } - - struct ComparisonSet /* For optimizing And, Or */ - { - static const int Lt_Mask = 0x1; // 1=less - static const int Eq_Mask = 0x2; // 2=equal - static const int Le_Mask = 0x3; // 1+2 = Less or Equal - static const int Gt_Mask = 0x4; // 4=greater - static const int Ne_Mask = 0x5; // 4+1 = Greater or Less, i.e. Not equal - static const int Ge_Mask = 0x6; // 4+2 = Greater or Equal - static int Swap_Mask(int m) { return (m&Eq_Mask) - | ((m&Lt_Mask) ? Gt_Mask : 0) - | ((m&Gt_Mask) ? Lt_Mask : 0); } - struct Comparison - { - CodeTree a; - CodeTree b; - int relationship; - }; - std::vector relationships; - struct Item - { - CodeTree value; - bool negated; - }; - std::vector plain_set; - int const_offset; - - enum RelationshipResult - { - Ok, - BecomeZero, - BecomeOne, - Suboptimal - }; - enum ConditionType - { - cond_or, - cond_and, - cond_mul, - cond_add - }; - - ComparisonSet(): - relationships(), - plain_set(), - const_offset(0) - { - } - - RelationshipResult AddItem(const CodeTree& a, bool negated, ConditionType type) - { - for(size_t c=0; c - && newrel_and == 0) - { - // (xy) = x!=y - relationships[c].relationship = Ne_Mask; - return Suboptimal; - } - if(newrel_or == 7 - && newrel_and == 0) - { - // (x=y) = 1 - // (x<=y) + (x>y) = 1 - // (x=y) + (x!=y) = 1 - const_offset += 1; - relationships.erase(relationships.begin()+c); - return Suboptimal; - } - if(newrel_or == 7 - && newrel_and == Eq_Mask) - { - // (x<=y) + (x>=y) = 1 + (x=y) - relationships[c].relationship = Eq_Mask; - const_offset += 1; - return Suboptimal; - } - continue; - } - } - return Suboptimal; - } - } - Comparison comp; - comp.a = a; - comp.b = b; - comp.relationship = reltype; - relationships.push_back(comp); - return Ok; - } - }; - - struct CollectionSet /* For optimizing Add, Mul */ - { - struct Collection - { - CodeTree value; - CodeTree factor; - bool factor_needs_rehashing; - - Collection() : value(),factor(), factor_needs_rehashing(false) { } - Collection(const CodeTree& v, const CodeTree& f) - : value(v), factor(f), factor_needs_rehashing(false) { } - }; - std::multimap collections; - - enum CollectionResult - { - Ok, - Suboptimal - }; - - typedef std::multimap::iterator PositionType; - - PositionType FindIdenticalValueTo(const CodeTree& value) - { - fphash_t hash = value.GetHash(); - for(PositionType - i = collections.lower_bound(hash); - i != collections.end() && i->first == hash; - ++i) - { - if(value.IsIdenticalTo(i->second.value)) - return i; - } - return collections.end(); - } - bool Found(const PositionType& b) { return b != collections.end(); } - - CollectionResult AddCollectionTo(const CodeTree& factor, - const PositionType& into_which) - { - Collection& c = into_which->second; - if(c.factor_needs_rehashing) - c.factor.AddParam(factor); - else - { - CodeTree add; - add.SetOpcode(cAdd); - add.AddParamMove(c.factor); - add.AddParam(factor); - c.factor.swap(add); - c.factor_needs_rehashing = true; - } - return Suboptimal; - } - - CollectionResult AddCollection(const CodeTree& value, const CodeTree& factor) - { - const fphash_t hash = value.GetHash(); - PositionType i = collections.lower_bound(hash); - for(; i != collections.end() && i->first == hash; ++i) - { - if(i->second.value.IsIdenticalTo(value)) - return AddCollectionTo(factor, i); - } - collections.insert( - i, - std::make_pair( hash, Collection(value, factor) ) ); - return Ok; - } - - CollectionResult AddCollection(const CodeTree& a) - { - return AddCollection(a, CodeTree(1.0) ); - } - }; - - struct Select2ndRev - { - template - inline bool operator() (const T& a, const T& b) const - { - return a.second > b.second; - } - }; - struct Select1st - { - template - inline bool operator() (const std::pair& a, - const std::pair& b) const - { - return a.first < b.first; - } - - template - inline bool operator() (const std::pair& a, T1 b) const - { - return a.first < b; - } - - template - inline bool operator() (T1 a, const std::pair& b) const - { - return a < b.first; - } - }; - - bool IsEvenIntegerConst(double v) - { - return IsIntegerConst(v) && ((long)v % 2) == 0; - } - - struct ConstantExponentCollection - { - typedef std::pair > ExponentInfo; - std::vector data; - - void MoveToSet_Unique(double exponent, std::vector& source_set) - { - data.push_back( std::pair > - (exponent, std::vector() ) ); - data.back().second.swap(source_set); - } - void MoveToSet_NonUnique(double exponent, std::vector& source_set) - { - std::vector::iterator i - = std::lower_bound(data.begin(), data.end(), exponent, Select1st()); - if(i != data.end() && i->first == exponent) - { - i->second.insert(i->second.end(), source_set.begin(), source_set.end()); - } - else - { - //MoveToSet_Unique(exponent, source_set); - data.insert(i, std::pair > - (exponent, source_set) ); - } - } - - bool Optimize() - { - /* TODO: Group them such that: - * - * x^3 * z^2 becomes (x*z)^2 * x^1 - * x^3 * y^2.5 * z^2 becomes (x*z*y)^2 * y^0.5 * x^1 - * rather than (x*y*z)^2 * (x*y)^0.5 * x^0.5 - * - * x^4.5 * z^2.5 becomes (z * x)^2.5 * x^2 - * becomes (x*z*x)^2 * (z*x)^0.5 - * becomes (z*x*x*z*x)^0.5 * (z*x*x)^1.5 -- buzz, bad. - * - */ - bool changed = false; - std::sort( data.begin(), data.end(), Select1st() ); - redo: - /* Supposed algorithm: - * For the smallest pair of data[] where the difference - * between the two is a "neat value" (x*16 is positive integer), - * do the combining as indicated above. - */ - /* - * NOTE: Hanged in Testbed test P44, looping the following - * (Var0 ^ 0.75) * ((1.5 * Var0) ^ 1.0) - * = (Var0 ^ 1.75) * (1.5 ^ 1.0) - * Fixed by limiting to cases where (exp_a != 1.0). - * - * NOTE: Converting (x*z)^0.5 * x^16.5 - * into x^17 * z^0.5 - * is handled by code within CollectMulGroup(). - * However, bacause it is prone for infinite looping, - * the use of "IsIdenticalTo(before)" is added at the - * end of ConstantFolding_MulGrouping(). - * - * This algorithm could make it into (x*z*x)^0.5 * x^16, - * but this is wrong, for it falsely includes x^evenint.. twice. - */ - for(size_t a=0; a= fabs(exp_a)) break; - double exp_diff_still_probable_integer = exp_diff * 16.0; - if(IsIntegerConst(exp_diff_still_probable_integer) - && !(IsIntegerConst(exp_b) && !IsIntegerConst(exp_diff)) - ) - { - /* When input is x^3 * z^2, - * exp_a = 2 - * a_set = z - * exp_b = 3 - * b_set = x - * exp_diff = 3-2 = 1 - */ - std::vector& a_set = data[a].second; - std::vector& b_set = data[b].second; - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Before ConstantExponentCollection iteration:\n"; - Dump(std::cout); - #endif - if(IsIntegerConst(exp_b) - && IsEvenIntegerConst(exp_b) - //&& !IsEvenIntegerConst(exp_diff) - && !IsEvenIntegerConst(exp_diff+exp_a)) - { - CodeTree tmp2; - tmp2.SetOpcode(cMul); - tmp2.SetParamsMove(b_set); - tmp2.Rehash(); - CodeTree tmp; - tmp.SetOpcode(cAbs); - tmp.AddParamMove(tmp2); - tmp.Rehash(); - b_set.resize(1); - b_set[0].swap(tmp); - } - - a_set.insert(a_set.end(), b_set.begin(), b_set.end()); - - std::vector b_copy = b_set; - data.erase(data.begin() + b); - MoveToSet_NonUnique(exp_diff, b_copy); - changed = true; - - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "After ConstantExponentCollection iteration:\n"; - Dump(std::cout); - #endif - goto redo; - } - } - } - return changed; - } - - #ifdef DEBUG_SUBSTITUTIONS - void Dump(std::ostream& out) - { - for(size_t a=0; a 0) out << '*'; - DumpTree(data[a].second[b], out); - } - out << std::endl; - } - } - #endif - - }; - - struct RangeComparisonData - { - enum Decision - { - MakeFalse=0, - MakeTrue=1, - MakeNEqual=2, - MakeEqual=3, - MakeNotNotP0=4, - MakeNotNotP1=5, - MakeNotP0=6, - MakeNotP1=7, - Unchanged=8 - }; - enum WhatDoWhenCase - { - Never =0, - Eq0 =1, // val==0 - Eq1 =2, // val==1 - Gt0Le1=3, // val>0 && val<=1 - Ge0Lt1=4 // val>=0 && val<1 - }; - Decision if_identical; // What to do when operands are identical - Decision if_always[4]; // What to do if Always <, <=, >, >= - struct { Decision what : 4; WhatDoWhenCase when : 4; } - p0_logical_a, p1_logical_a, - p0_logical_b, p1_logical_b; - - Decision Analyze(const CodeTree& a, const CodeTree& b) const - { - if(a.IsIdenticalTo(b)) - return if_identical; - - MinMaxTree p0 = a.CalculateResultBoundaries(); - MinMaxTree p1 = b.CalculateResultBoundaries(); - if(p0.has_max && p1.has_min) - { - if(p0.max < p1.min && if_always[0] != Unchanged) - return if_always[0]; // p0 < p1 - if(p0.max <= p1.min && if_always[1] != Unchanged) - return if_always[1]; // p0 <= p1 - } - if(p0.has_min && p1.has_max) - { - if(p0.min > p1.max && if_always[2] != Unchanged) - return if_always[2]; // p0 > p1 - if(p0.min >= p1.max && if_always[3] != Unchanged) - return if_always[3]; // p0 >= p1 - } - - if(a.IsLogicalValue()) - { - if(p0_logical_a.what != Unchanged) - if(TestCase(p0_logical_a.when, p1)) return p0_logical_a.what; - if(p0_logical_b.what != Unchanged) - if(TestCase(p0_logical_b.when, p1)) return p0_logical_b.what; - } - if(b.IsLogicalValue()) - { - if(p1_logical_a.what != Unchanged) - if(TestCase(p1_logical_a.when, p0)) return p1_logical_a.what; - if(p1_logical_b.what != Unchanged) - if(TestCase(p1_logical_b.when, p0)) return p1_logical_b.what; - } - return Unchanged; - } - static bool TestCase(WhatDoWhenCase when, const MinMaxTree& p) - { - if(!p.has_min || !p.has_max) return false; - switch(when) - { - case Eq0: return p.min==0.0 && p.max==p.min; - case Eq1: return p.min==1.0 && p.max==p.max; - case Gt0Le1: return p.min>0 && p.max<=1; - case Ge0Lt1: return p.min>=0 && p.max<1; - default:; - } - return false; - } - }; - -} - -namespace FPoptimizer_CodeTree -{ - template /* ComparisonSet::ConditionType */ - bool CodeTree::ConstantFolding_LogicCommon(CondType cond_type, bool is_logical) - { - bool should_regenerate = false; - ComparisonSet comp; - for(size_t a=0; a 0; ) - { - const CodeTree& atree = GetParam(a); - if(atree.IsLogicalValue()) - DelParam(a); - } - } - - for(size_t a=0; a/*base value (mul group)*/ - > exponent_list; - typedef std::multimap exponent_map; - exponent_map by_exponent; - - for(CollectionSet::PositionType - j = mul.collections.begin(); - j != mul.collections.end(); - ++j) - { - CodeTree& value = j->second.value; - CodeTree& exponent = j->second.factor; - if(j->second.factor_needs_rehashing) exponent.Rehash(); - const fphash_t exponent_hash = exponent.GetHash(); - - exponent_map::iterator i = by_exponent.lower_bound(exponent_hash); - for(; i != by_exponent.end() && i->first == exponent_hash; ++i) - if(i->second.first.IsIdenticalTo(exponent)) - { - if(!exponent.IsImmed() || !FloatEqual(exponent.GetImmed(), 1.0)) - should_regenerate = true; - i->second.second.push_back(value); - goto skip_b; - } - by_exponent.insert(i, std::make_pair(exponent_hash, - std::make_pair(exponent, - std::vector (size_t(1), value) - ))); - skip_b:; - } - - #ifdef FP_MUL_COMBINE_EXPONENTS - ConstantExponentCollection by_float_exponent; - for(exponent_map::iterator - j,i = by_exponent.begin(); - i != by_exponent.end(); - i=j) - { - j=i; ++j; - exponent_list& list = i->second; - if(list.first.IsImmed()) - { - double exponent = list.first.GetImmed(); - if(!(exponent == 0.0)) - by_float_exponent.MoveToSet_Unique(exponent, list.second); - by_exponent.erase(i); - } - } - if(by_float_exponent.Optimize()) - should_regenerate = true; - #endif - - if(should_regenerate) - { - CodeTree before = *this; - before.CopyOnWrite(); - - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Before ConstantFolding_MulGrouping: "; DumpTree(before); - std::cout << "\n"; - #endif - DelParams(); - - /* Group by exponents */ - /* First handle non-constant exponents */ - for(exponent_map::iterator - i = by_exponent.begin(); - i != by_exponent.end(); - ++i) - { - exponent_list& list = i->second; - #ifndef FP_MUL_COMBINE_EXPONENTS - if(list.first.IsImmed()) - { - double exponent = list.first.GetImmed(); - if(exponent == 0.0) continue; - if(FloatEqual(exponent, 1.0)) - { - AddParamsMove(list.second); - continue; - } - } - #endif - CodeTree mul; - mul.SetOpcode(cMul); - mul.SetParamsMove( list.second); - mul.Rehash(); - - if(has_highlevel_opcodes && list.first.IsImmed()) - { - if(list.first.GetImmed() == 1.0 / 3.0) - { - CodeTree cbrt; - cbrt.SetOpcode(cCbrt); - cbrt.AddParamMove(mul); - cbrt.Rehash(); - AddParamMove(cbrt); - continue; - } - if(list.first.GetImmed() == 0.5) - { - CodeTree sqrt; - sqrt.SetOpcode(cSqrt); - sqrt.AddParamMove(mul); - sqrt.Rehash(); - AddParamMove(sqrt); - continue; - } - if(list.first.GetImmed() == -0.5) - { - CodeTree rsqrt; - rsqrt.SetOpcode(cRSqrt); - rsqrt.AddParamMove(mul); - rsqrt.Rehash(); - AddParamMove(rsqrt); - continue; - } - if(list.first.GetImmed() == -1.0) - { - CodeTree inv; - inv.SetOpcode(cInv); - inv.AddParamMove(mul); - inv.Rehash(); - AddParamMove(inv); - continue; - } - } - CodeTree pow; - pow.SetOpcode(cPow); - pow.AddParamMove(mul); - pow.AddParamMove( list.first ); - pow.Rehash(); - AddParamMove(pow); - } - #ifdef FP_MUL_COMBINE_EXPONENTS - by_exponent.clear(); - /* Then handle constant exponents */ - for(size_t a=0; a remaining ( GetParamCount() ); - size_t has_mulgroups_remaining = 0; - for(size_t a=0; a 0) - { - if(has_mulgroups_remaining > 1) // is it possible to find a duplicate? - { - std::vector< std::pair > occurance_counts; - std::multimap occurance_pos; - bool found_dup = false; - for(size_t a=0; a::const_iterator - i = occurance_pos.lower_bound(p_hash); - i != occurance_pos.end() && i->first == p_hash; - ++i) - { - if(occurance_counts[i->second].first.IsIdenticalTo(p)) - { - occurance_counts[i->second].second += 1; - found_dup = true; - goto found_mulgroup_item_dup; - } - } - occurance_counts.push_back(std::make_pair(p, size_t(1))); - occurance_pos.insert(std::make_pair(p_hash, occurance_counts.size()-1)); - found_mulgroup_item_dup:; - } - } - if(found_dup) - { - // Find the "x" to group by - CodeTree group_by; { size_t max = 0; - for(size_t p=0; p max) - { group_by = occurance_counts[p].first; max = occurance_counts[p].second; } - } } - // Collect the items for adding in the group (a+b) - CodeTree group_add; - group_add.SetOpcode(cAdd); - - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Duplicate across some trees: "; - DumpTree(group_by); - std::cout << " in "; - DumpTree(*this); - std::cout << "\n"; - #endif - for(size_t a=0; asecond.value; - CodeTree& coeff = j->second.factor; - if(j->second.factor_needs_rehashing) coeff.Rehash(); - - if(coeff.IsImmed()) - { - if(coeff.GetImmed() == 0.0) - continue; - if(FloatEqual(coeff.GetImmed(), 1.0)) - { - AddParamMove(value); - continue; - } - } - CodeTree mul; - mul.SetOpcode(cMul); - mul.AddParamMove(value); - mul.AddParamMove(coeff); - mul.Rehash(); - AddParamMove(mul); - } - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "After ConstantFolding_AddGrouping: "; DumpTree(*this); - std::cout << "\n"; - #endif - return true; - } - return false; - } - - bool CodeTree::ConstantFolding_IfOperations() - { - // If the If() condition begins with a cNot, - // remove the cNot and swap the branches. - for(;;) - { - if(GetParam(0).GetOpcode() == cNot) - { - SetOpcode(cIf); - GetParam(0).Become( GetParam(0).GetParam(0) ); - GetParam(1).swap(GetParam(2)); - } - else if(GetParam(0).GetOpcode() == cAbsNot) - { - SetOpcode(cAbsIf); - GetParam(0).Become( GetParam(0).GetParam(0) ); - GetParam(1).swap(GetParam(2)); - } - else break; - } - if(GetParam(0).GetOpcode() == cIf - || GetParam(0).GetOpcode() == cAbsIf) - { - // if(if(x, a,b), c,d) - // -> if(x, if(a, c,d), if(b, c,d)) - // when either a or b is constantly true/false - CodeTree cond = GetParam(0); - CodeTree truth_a; - truth_a.SetOpcode(cond.GetOpcode() == cIf ? cNotNot : cAbsNotNot); - truth_a.AddParam(cond.GetParam(1)); - truth_a.ConstantFolding(); - CodeTree truth_b; - truth_b.SetOpcode(cond.GetOpcode() == cIf ? cNotNot : cAbsNotNot); - truth_b.AddParam(cond.GetParam(2)); - truth_b.ConstantFolding(); - if(truth_a.IsImmed() || truth_b.IsImmed()) - { - CodeTree then_tree; - then_tree.SetOpcode(cond.GetOpcode()); - then_tree.AddParam(cond.GetParam(1)); - then_tree.AddParam(GetParam(1)); - then_tree.AddParam(GetParam(2)); - then_tree.Rehash(); - CodeTree else_tree; - else_tree.SetOpcode(cond.GetOpcode()); - else_tree.AddParam(cond.GetParam(2)); - else_tree.AddParam(GetParam(1)); - else_tree.AddParam(GetParam(2)); - else_tree.Rehash(); - SetOpcode(cond.GetOpcode()); - SetParam(0, cond.GetParam(0)); - SetParamMove(1, then_tree); - SetParamMove(2, else_tree); - return true; // rerun cIf optimization - } - } - if(GetParam(1).GetOpcode() == GetParam(2).GetOpcode() - && (GetParam(1).GetOpcode() == cIf - || GetParam(1).GetOpcode() == cAbsIf)) - { - CodeTree& leaf1 = GetParam(1); - CodeTree& leaf2 = GetParam(2); - if(leaf1.GetParam(0).IsIdenticalTo(leaf2.GetParam(0)) - && (leaf1.GetParam(1).IsIdenticalTo(leaf2.GetParam(1)) - || leaf1.GetParam(2).IsIdenticalTo(leaf2.GetParam(2)))) - { - // if(x, if(y,a,b), if(y,c,d)) - // -> if(y, if(x,a,c), if(x,b,d)) - // when either a,c are identical or b,d are identical - CodeTree then_tree; - then_tree.SetOpcode(GetOpcode()); - then_tree.AddParam(GetParam(0)); - then_tree.AddParam(leaf1.GetParam(1)); - then_tree.AddParam(leaf2.GetParam(1)); - then_tree.Rehash(); - CodeTree else_tree; - else_tree.SetOpcode(GetOpcode()); - else_tree.AddParam(GetParam(0)); - else_tree.AddParam(leaf1.GetParam(2)); - else_tree.AddParam(leaf2.GetParam(2)); - else_tree.Rehash(); - SetOpcode(leaf1.GetOpcode()); - SetParam(0, leaf1.GetParam(0)); - SetParamMove(1, then_tree); - SetParamMove(2, else_tree); - return true; // rerun cIf optimization - // cIf [x (cIf [y a z]) (cIf [y z b])] : (cXor x y) z (cIf[x a b]) - // ^ if only we had cXor opcode. - } - if(leaf1.GetParam(1).IsIdenticalTo(leaf2.GetParam(1)) - && leaf1.GetParam(2).IsIdenticalTo(leaf2.GetParam(2))) - { - // if(x, if(y,a,b), if(z,a,b)) - // -> if( if(x, y,z), a,b) - CodeTree cond_tree; - cond_tree.SetOpcode(GetOpcode()); - cond_tree.AddParamMove(GetParam(0)); - cond_tree.AddParam(leaf1.GetParam(0)); - cond_tree.AddParam(leaf2.GetParam(0)); - cond_tree.Rehash(); - SetOpcode(leaf1.GetOpcode()); - SetParamMove(0, cond_tree); - SetParam(2, leaf1.GetParam(2)); - SetParam(1, leaf1.GetParam(1)); - return true; // rerun cIf optimization - } - if(leaf1.GetParam(1).IsIdenticalTo(leaf2.GetParam(2)) - && leaf1.GetParam(2).IsIdenticalTo(leaf2.GetParam(1))) - { - // if(x, if(y,a,b), if(z,b,a)) - // -> if( if(x, y,!z), a,b) - CodeTree not_tree; - not_tree.SetOpcode(leaf2.GetOpcode() == cIf ? cNot : cAbsNot); - not_tree.AddParam(leaf2.GetParam(0)); - not_tree.Rehash(); - CodeTree cond_tree; - cond_tree.SetOpcode(GetOpcode()); - cond_tree.AddParamMove(GetParam(0)); - cond_tree.AddParam(leaf1.GetParam(0)); - cond_tree.AddParamMove(not_tree); - cond_tree.Rehash(); - SetOpcode(leaf1.GetOpcode()); - SetParamMove(0, cond_tree); - SetParam(2, leaf1.GetParam(2)); - SetParam(1, leaf1.GetParam(1)); - return true; // rerun cIf optimization - } - } - - // If the sub-expression evaluates to approx. zero, yield param3. - // If the sub-expression evaluates to approx. nonzero, yield param2. - MinMaxTree p = GetParam(0).CalculateResultBoundaries(); - switch(GetLogicalValue(p, GetOpcode()==cAbsIf)) - { - case 1: // true - Become(GetParam(1)); - return true; // rerun optimization (opcode changed) - case 0: // false - Become(GetParam(2)); - return true; // rerun optimization (opcode changed) - default: ; - } - - CodeTree& branch1 = GetParam(1); - CodeTree& branch2 = GetParam(2); - - if(branch1.IsIdenticalTo(branch2)) - { - // If both branches of an If() are identical, the test becomes unnecessary - Become(GetParam(1)); - return true; // rerun optimization (opcode changed) - } - - const OPCODE op1 = branch1.GetOpcode(); - const OPCODE op2 = branch2.GetOpcode(); - if(op1 == op2) - { - // If both branches apply the same unary function to different values, - // extract the function. E.g. if(x,sin(a),sin(b)) -> sin(if(x,a,b)) - if(branch1.GetParamCount() == 1) - { - CodeTree changed_if; - changed_if.SetOpcode(GetOpcode()); - changed_if.AddParamMove(GetParam(0)); - changed_if.AddParam(branch1.GetParam(0)); - changed_if.AddParam(branch2.GetParam(0)); - changed_if.Rehash(); - SetOpcode(op1); - DelParams(); - AddParamMove(changed_if); - return true; // rerun optimization (opcode changed) - } - if(op1 == cAdd || op1 == cMul - || op1 == cAnd || op1 == cOr - || op1 == cAbsAnd || op1 == cAbsOr - || op1 == cMin || op1 == cMax) - { - // If the two groups contain one or more - // identical values, extract them. - std::vector overlap; - for(size_t a=branch1.GetParamCount(); a-- > 0; ) - { - for(size_t b=branch2.GetParamCount(); b-- > 0; ) - { - if(branch1.GetParam(a).IsIdenticalTo(branch2.GetParam(b))) - { - if(overlap.empty()) { branch1.CopyOnWrite(); branch2.CopyOnWrite(); } - overlap.push_back(branch1.GetParam(a)); - branch2.DelParam(b); - branch1.DelParam(a); - break; - } - } - } - if(!overlap.empty()) - { - branch1.Rehash(); - branch2.Rehash(); - CodeTree changed_if; - changed_if.SetOpcode(GetOpcode()); - changed_if.SetParamsMove(GetParams()); - changed_if.Rehash(); - SetOpcode(op1); - SetParamsMove(overlap); - AddParamMove(changed_if); - return true; // rerun optimization (opcode changed) - } - } - } - // if(x, y+z, y) -> if(x, z,0)+y - if(op1 == cAdd - || op1 == cMul - || (op1 == cAnd && branch2.IsLogicalValue()) - || (op1 == cOr && branch2.IsLogicalValue()) - ) - { - for(size_t a=branch1.GetParamCount(); a-- > 0; ) - if(branch1.GetParam(a).IsIdenticalTo(branch2)) - { - branch1.CopyOnWrite(); - branch1.DelParam(a); - branch1.Rehash(); - CodeTree branch2_backup = branch2; - branch2 = CodeTree( (op1==cAdd||op1==cOr) ? 0.0 : 1.0 ); - CodeTree changed_if; - changed_if.SetOpcode(GetOpcode()); - changed_if.SetParamsMove(GetParams()); - changed_if.Rehash(); - SetOpcode(op1); - AddParamMove(branch2_backup); - AddParamMove(changed_if); - return true; // rerun optimization (opcode changed) - } - } - // if(x, y&z, !!y) -> if(x, z, 1) & y - if((op1 == cAnd || op1 == cOr) && op2 == cNotNot) - { - CodeTree& branch2op = branch2.GetParam(0); - for(size_t a=branch1.GetParamCount(); a-- > 0; ) - if(branch1.GetParam(a).IsIdenticalTo(branch2op)) - { - branch1.CopyOnWrite(); - branch1.DelParam(a); - branch1.Rehash(); - CodeTree branch2_backup = branch2op; - branch2 = CodeTree( (op1==cOr) ? 0.0 : 1.0 ); - CodeTree changed_if; - changed_if.SetOpcode(GetOpcode()); - changed_if.SetParamsMove(GetParams()); - changed_if.Rehash(); - SetOpcode(op1); - AddParamMove(branch2_backup); - AddParamMove(changed_if); - return true; // rerun optimization (opcode changed) - } - } - // if(x, y, y+z) -> if(x, 0,z)+y - if(op2 == cAdd - || op2 == cMul - || (op2 == cAnd && branch1.IsLogicalValue()) - || (op2 == cOr && branch1.IsLogicalValue()) - ) - { - for(size_t a=branch2.GetParamCount(); a-- > 0; ) - if(branch2.GetParam(a).IsIdenticalTo(branch1)) - { - branch2.CopyOnWrite(); - branch2.DelParam(a); - branch2.Rehash(); - CodeTree branch1_backup = branch1; - branch1 = CodeTree( (op2==cAdd||op2==cOr) ? 0.0 : 1.0 ); - CodeTree changed_if; - changed_if.SetOpcode(GetOpcode()); - changed_if.SetParamsMove(GetParams()); - changed_if.Rehash(); - SetOpcode(op2); - AddParamMove(branch1_backup); - AddParamMove(changed_if); - return true; // rerun optimization (opcode changed) - } - } - // if(x, !!y, y&z) -> if(x, 1, z) & y - if((op2 == cAnd || op2 == cOr) && op1 == cNotNot) - { - CodeTree& branch1op = branch1.GetParam(0); - for(size_t a=branch2.GetParamCount(); a-- > 0; ) - if(branch2.GetParam(a).IsIdenticalTo(branch1op)) - { - branch2.CopyOnWrite(); - branch2.DelParam(a); - branch2.Rehash(); - CodeTree branch1_backup = branch1op; - branch1 = CodeTree( (op2==cOr) ? 0.0 : 1.0 ); - CodeTree changed_if; - changed_if.SetOpcode(GetOpcode()); - changed_if.SetParamsMove(GetParams()); - changed_if.Rehash(); - SetOpcode(op2); - AddParamMove(branch1_backup); - AddParamMove(changed_if); - return true; // rerun optimization (opcode changed) - } - } - return false; // No changes - } - - bool CodeTree::ConstantFolding_PowOperations() - { - if(GetParam(0).IsImmed() - && GetParam(1).IsImmed()) - { - double const_value = fp_pow(GetParam(0).GetImmed(), - GetParam(1).GetImmed()); - data = new CodeTreeData(const_value); - return false; - } - if(GetParam(1).IsImmed() - && (float)GetParam(1).GetImmed() == 1.0) - { - // Conversion through a float type value gets rid of - // awkward abs(x)^1 generated from exp(log(x^6)/6), - // without sacrificing as much precision as FloatEqual() does. - // x^1 = x - Become(GetParam(0)); - return true; // rerun optimization (opcode changed) - } - if(GetParam(0).IsImmed() - && (float)GetParam(0).GetImmed() == 1.0) - { - // 1^x = 1 - data = new CodeTreeData(1.0); - return false; - } - - // 5^(20*x) = (5^20)^x - if(GetParam(0).IsImmed() - && GetParam(1).GetOpcode() == cMul) - { - bool changes = false; - double base_immed = GetParam(0).GetImmed(); - CodeTree mulgroup = GetParam(1); - for(size_t a=mulgroup.GetParamCount(); a-->0; ) - if(mulgroup.GetParam(a).IsImmed()) - { - double imm = mulgroup.GetParam(a).GetImmed(); - //if(imm >= 0.0) - { - double new_base_immed = fp_pow(base_immed, imm); - if(std::isinf(new_base_immed) || new_base_immed == 0.0) - { - // It produced an infinity. Do not change. - break; - } - - if(!changes) - { - changes = true; - mulgroup.CopyOnWrite(); - } - base_immed = new_base_immed; - mulgroup.DelParam(a); - break; // - } - } - if(changes) - { - mulgroup.Rehash(); - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Before pow-mul change: "; DumpTree(*this); - std::cout << "\n"; - #endif - GetParam(0).Become(CodeTree(base_immed)); - GetParam(1).Become(mulgroup); - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "After pow-mul change: "; DumpTree(*this); - std::cout << "\n"; - #endif - } - } - // (x*20)^2 = x^2 * 20^2 - if(GetParam(1).IsImmed() - && GetParam(0).GetOpcode() == cMul) - { - double exponent_immed = GetParam(1).GetImmed(); - double factor_immed = 1.0; - bool changes = false; - CodeTree& mulgroup = GetParam(0); - for(size_t a=mulgroup.GetParamCount(); a-->0; ) - if(mulgroup.GetParam(a).IsImmed()) - { - double imm = mulgroup.GetParam(a).GetImmed(); - //if(imm >= 0.0) - { - double new_factor_immed = fp_pow(imm, exponent_immed); - if(std::isinf(new_factor_immed) || new_factor_immed == 0.0) - { - // It produced an infinity. Do not change. - break; - } - if(!changes) - { - changes = true; - mulgroup.CopyOnWrite(); - } - factor_immed *= new_factor_immed; - mulgroup.DelParam(a); - break; // - } - } - if(changes) - { - mulgroup.Rehash(); - CodeTree newpow; - newpow.SetOpcode(cPow); - newpow.SetParamsMove(GetParams()); - SetOpcode(cMul); - AddParamMove(newpow); - AddParam( CodeTree(factor_immed) ); - return true; // rerun optimization (opcode changed) - } - } - - // (x^3)^2 = x^6 - // NOTE: If 3 is even and 3*2 is not, x must be changed to abs(x). - if(GetParam(0).GetOpcode() == cPow - && GetParam(1).IsImmed() - && GetParam(0).GetParam(1).IsImmed()) - { - double a = GetParam(0).GetParam(1).GetImmed(); - double b = GetParam(1).GetImmed(); - double c = a * b; // new exponent - if(IsEvenIntegerConst(a) // a is an even int? - && !IsEvenIntegerConst(c)) // c is not? - { - CodeTree newbase; - newbase.SetOpcode(cAbs); - newbase.AddParam(GetParam(0).GetParam(0)); - newbase.Rehash(); - SetParamMove(0, newbase); - } - else - SetParam(0, GetParam(0).GetParam(0)); - SetParam(1, CodeTree(c)); - } - return false; // No changes that require a rerun - } - - bool CodeTree::ConstantFolding_ComparisonOperations() - { - static const RangeComparisonData Data[6] = - { - // cEqual: - // Case: p0 == p1 Antonym: p0 != p1 - // Synonym: p1 == p0 Antonym: p1 != p0 - { RangeComparisonData::MakeTrue, // If identical: always true - {RangeComparisonData::MakeFalse, // If Always p0 < p1: always false - RangeComparisonData::Unchanged, - RangeComparisonData::MakeFalse, // If Always p0 > p1: always false - RangeComparisonData::Unchanged}, - // NotNot(p0) if p1==1 NotNot(p1) if p0==1 - // Not(p0) if p1==0 Not(p1) if p0==0 - {RangeComparisonData::MakeNotNotP0, RangeComparisonData::Eq1}, - {RangeComparisonData::MakeNotNotP1, RangeComparisonData::Eq1}, - {RangeComparisonData::MakeNotP0, RangeComparisonData::Eq0}, - {RangeComparisonData::MakeNotP1, RangeComparisonData::Eq0} - }, - // cNEqual: - // Case: p0 != p1 Antonym: p0 == p1 - // Synonym: p1 != p0 Antonym: p1 == p0 - { RangeComparisonData::MakeFalse, // If identical: always false - {RangeComparisonData::MakeTrue, // If Always p0 < p1: always true - RangeComparisonData::Unchanged, - RangeComparisonData::MakeTrue, // If Always p0 > p1: always true - RangeComparisonData::Unchanged}, - // NotNot(p0) if p1==0 NotNot(p1) if p0==0 - // Not(p0) if p1==1 Not(p1) if p0==1 - {RangeComparisonData::MakeNotNotP0, RangeComparisonData::Eq0}, - {RangeComparisonData::MakeNotNotP1, RangeComparisonData::Eq0}, - {RangeComparisonData::MakeNotP0, RangeComparisonData::Eq1}, - {RangeComparisonData::MakeNotP1, RangeComparisonData::Eq1} - }, - // cLess: - // Case: p0 < p1 Antonym: p0 >= p1 - // Synonym: p1 > p0 Antonym: p1 <= p0 - { RangeComparisonData::MakeFalse, // If identical: always false - {RangeComparisonData::MakeTrue, // If Always p0 < p1: always true - RangeComparisonData::MakeNEqual, - RangeComparisonData::MakeFalse, // If Always p0 > p1: always false - RangeComparisonData::MakeFalse},// If Always p0 >= p1: always false - // Not(p0) if p1>0 & p1<=1 -- NotNot(p1) if p0>=0 & p0<1 - {RangeComparisonData::MakeNotP0, RangeComparisonData::Gt0Le1}, - {RangeComparisonData::MakeNotNotP1, RangeComparisonData::Ge0Lt1}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never} - }, - // cLessOrEq: - // Case: p0 <= p1 Antonym: p0 > p1 - // Synonym: p1 >= p0 Antonym: p1 < p0 - { RangeComparisonData::MakeTrue, // If identical: always true - {RangeComparisonData::Unchanged, // If Always p0 < p1: ? - RangeComparisonData::MakeTrue, // If Always p0 <= p1: always true - RangeComparisonData::MakeFalse, // If Always p0 > p1: always false - RangeComparisonData::MakeEqual},// If Never p0 < p1: use cEqual - // Not(p0) if p1>=0 & p1<1 -- NotNot(p1) if p0>0 & p0<=1 - {RangeComparisonData::MakeNotP0, RangeComparisonData::Ge0Lt1}, - {RangeComparisonData::MakeNotNotP1, RangeComparisonData::Gt0Le1}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never} - }, - // cGreater: - // Case: p0 > p1 Antonym: p0 <= p1 - // Synonym: p1 < p0 Antonym: p1 >= p0 - { RangeComparisonData::MakeFalse, // If identical: always false - {RangeComparisonData::MakeFalse, // If Always p0 < p1: always false - RangeComparisonData::MakeFalse, // If Always p0 <= p1: always false - RangeComparisonData::MakeTrue, // If Always p0 > p1: always true - RangeComparisonData::MakeNEqual}, - // NotNot(p0) if p1>=0 & p1<1 -- Not(p1) if p0>0 & p0<=1 - {RangeComparisonData::MakeNotNotP0, RangeComparisonData::Ge0Lt1}, - {RangeComparisonData::MakeNotP1, RangeComparisonData::Gt0Le1}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never} - }, - // cGreaterOrEq: - // Case: p0 >= p1 Antonym: p0 < p1 - // Synonym: p1 <= p0 Antonym: p1 > p0 - { RangeComparisonData::MakeTrue, // If identical: always true - {RangeComparisonData::MakeFalse, // If Always p0 < p1: always false - RangeComparisonData::MakeEqual, // If Always p0 >= p1: always true - RangeComparisonData::Unchanged, // If always p0 > p1: ? - RangeComparisonData::MakeTrue}, // If Never p0 > p1: use cEqual - // NotNot(p0) if p1>0 & p1<=1 -- Not(p1) if p0>=0 & p0<1 - {RangeComparisonData::MakeNotNotP0, RangeComparisonData::Gt0Le1}, - {RangeComparisonData::MakeNotP1, RangeComparisonData::Ge0Lt1}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never}, - {RangeComparisonData::Unchanged, RangeComparisonData::Never} - } - }; - switch(Data[GetOpcode()-cEqual].Analyze(GetParam(0), GetParam(1))) - { - case RangeComparisonData::MakeFalse: - data = new CodeTreeData(0.0); return true; - case RangeComparisonData::MakeTrue: - data = new CodeTreeData(1.0); return true; - case RangeComparisonData::MakeEqual: SetOpcode(cEqual); return true; - case RangeComparisonData::MakeNEqual: SetOpcode(cNEqual); return true; - case RangeComparisonData::MakeNotNotP0: SetOpcode(cNotNot); DelParam(1); return true; - case RangeComparisonData::MakeNotNotP1: SetOpcode(cNotNot); DelParam(0); return true; - case RangeComparisonData::MakeNotP0: SetOpcode(cNot); DelParam(1); return true; - case RangeComparisonData::MakeNotP1: SetOpcode(cNot); DelParam(0); return true; - case RangeComparisonData::Unchanged:; - } - return false; - } - - bool CodeTree::ConstantFolding_Assimilate() - { - /* If the list contains another list of the same kind, assimilate it */ - bool assimilated = false; - for(size_t a=GetParamCount(); a-- > 0; ) - if(GetParam(a).GetOpcode() == GetOpcode()) - { - #ifdef DEBUG_SUBSTITUTIONS - if(!assimilated) - { - std::cout << "Before assimilation: "; DumpTree(*this); - std::cout << "\n"; - assimilated = true; - } - #endif - // Assimilate its children and remove it - AddParamsMove(GetParam(a).GetUniqueRef().GetParams(), a); - } - #ifdef DEBUG_SUBSTITUTIONS - if(assimilated) - { - std::cout << "After assimilation: "; DumpTree(*this); - std::cout << "\n"; - } - #endif - return assimilated; - } - - void CodeTree::ConstantFolding() - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Runs ConstantFolding for: "; DumpTree(*this); - std::cout << "\n"; - #endif - using namespace std; - redo:; - - // Insert here any hardcoded constant-folding optimizations - // that you want to be done whenever a new subtree is generated. - /* Not recursive. */ - - double const_value = 1.0; - if(GetOpcode() != cImmed) - { - MinMaxTree p = CalculateResultBoundaries(); - if(p.has_min && p.has_max && p.min == p.max) - { - // Replace us with this immed - const_value = p.min; - goto ReplaceTreeWithConstValue; - } - } - - if(false) - { - ReplaceTreeWithOne: - const_value = 1.0; - goto ReplaceTreeWithConstValue; - ReplaceTreeWithZero: - const_value = 0.0; - ReplaceTreeWithConstValue: - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Replacing "; DumpTree(*this); - if(IsImmed()) - std::cout << "(" << std::hex - << *(const uint_least64_t*)&GetImmed() - << std::dec << ")"; - std::cout << " with const value " << const_value; - std::cout << "(" << std::hex - << *(const uint_least64_t*)&const_value - << std::dec << ")"; - std::cout << "\n"; - #endif - data = new CodeTreeData(const_value); - return; - ReplaceTreeWithParam0: - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Before replace: "; DumpTree(*this); - std::cout << "\n"; - #endif - Become(GetParam(0)); - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "After replace: "; DumpTree(*this); - std::cout << "\n"; - #endif - goto redo; - } - - /* Constant folding */ - switch(GetOpcode()) - { - case cImmed: - break; // nothing to do - case VarBegin: - break; // nothing to do - - case cAnd: - case cAbsAnd: - { - ConstantFolding_Assimilate(); - for(size_t a=GetParamCount(); a-- > 0; ) - switch(GetLogicalValue(GetParam(a).CalculateResultBoundaries(), - GetOpcode()==cAbsAnd)) - { - case 0: goto ReplaceTreeWithZero; - case 1: DelParam(a); break; // x & y & 1 = x & y; x & 1 = !!x - default: ; - } - switch(GetParamCount()) - { - case 0: goto ReplaceTreeWithOne; - case 1: SetOpcode(GetOpcode()==cAnd ? cNotNot : cAbsNotNot); goto redo; // Replace self with the single operand - default: if(GetOpcode()==cAnd) if(ConstantFolding_AndLogic()) goto redo; - } - break; - } - case cOr: - case cAbsOr: - { - ConstantFolding_Assimilate(); - for(size_t a=GetParamCount(); a-- > 0; ) - switch(GetLogicalValue(GetParam(a).CalculateResultBoundaries(), - GetOpcode()==cAbsOr)) - { - case 1: goto ReplaceTreeWithOne; - case 0: DelParam(a); break; - default: ; - } - switch(GetParamCount()) - { - case 0: goto ReplaceTreeWithZero; - case 1: SetOpcode(GetOpcode()==cOr ? cNotNot : cAbsNotNot); goto redo; // Replace self with the single operand - default: if(GetOpcode()==cOr) if(ConstantFolding_OrLogic()) goto redo; - } - break; - } - case cNot: - case cAbsNot: - { - unsigned opposite = 0; - switch(GetParam(0).GetOpcode()) - { - case cEqual: opposite = cNEqual; break; - case cNEqual: opposite = cEqual; break; - case cLess: opposite = cGreaterOrEq; break; - case cGreater: opposite = cLessOrEq; break; - case cLessOrEq: opposite = cGreater; break; - case cGreaterOrEq: opposite = cLess; break; - //cNotNot already handled by grammar: @L cNotNot - case cNot: opposite = cNotNot; break; - case cAbsNot: opposite = cAbsNotNot; break; - case cAbsNotNot: opposite = cAbsNot; break; - default: break; - } - if(opposite) - { - SetOpcode(OPCODE(opposite)); - SetParamsMove(GetParam(0).GetUniqueRef().GetParams()); - goto redo; - } - - // If the sub-expression evaluates to approx. zero, yield one. - // If the sub-expression evaluates to approx. nonzero, yield zero. - switch(GetLogicalValue(GetParam(0).CalculateResultBoundaries(), - GetOpcode()==cAbsNot)) - { - case 1: goto ReplaceTreeWithZero; - case 0: goto ReplaceTreeWithOne; - default: ; - } - if(GetOpcode() == cNot && GetParam(0).IsAlwaysSigned(true)) - SetOpcode(cAbsNot); - - if(GetParam(0).GetOpcode() == cIf - || GetParam(0).GetOpcode() == cAbsIf) - { - CodeTree iftree = GetParam(0); - const CodeTree& ifp1 = iftree.GetParam(1); - const CodeTree& ifp2 = iftree.GetParam(2); - if(ifp1.GetOpcode() == cNot - || ifp1.GetOpcode() == cAbsNot) - { - // cNot [(cIf [x (cNot[y]) z])] -> cIf [x (cNotNot[y]) (cNot[z])] - SetParam(0, iftree.GetParam(0)); // condition - CodeTree p1; - p1.SetOpcode(ifp1.GetOpcode()==cNot ? cNotNot : cAbsNotNot); - p1.AddParam(ifp1.GetParam(0)); - p1.Rehash(); - AddParamMove(p1); - CodeTree p2; - p2.SetOpcode(GetOpcode()); - p2.AddParam(ifp2); - p2.Rehash(); - AddParamMove(p2); - SetOpcode(iftree.GetOpcode()); - goto redo; - } - if(ifp2.GetOpcode() == cNot - || ifp2.GetOpcode() == cAbsNot) - { - // cNot [(cIf [x y (cNot[z])])] -> cIf [x (cNot[y]) (cNotNot[z])] - SetParam(0, iftree.GetParam(0)); // condition - CodeTree p1; - p1.SetOpcode(GetOpcode()); - p1.AddParam(ifp1); - p1.Rehash(); - AddParamMove(p1); - CodeTree p2; - p2.SetOpcode(ifp2.GetOpcode()==cNot ? cNotNot : cAbsNotNot); - p2.AddParam(ifp2.GetParam(0)); - p2.Rehash(); - AddParamMove(p2); - SetOpcode(iftree.GetOpcode()); - goto redo; - } - } - break; - } - case cNotNot: - case cAbsNotNot: - { - // The function of cNotNot is to protect a logical value from - // changing. If the parameter is already a logical value, - // then the cNotNot opcode is redundant. - if(GetParam(0).IsLogicalValue()) - goto ReplaceTreeWithParam0; - - // If the sub-expression evaluates to approx. zero, yield zero. - // If the sub-expression evaluates to approx. nonzero, yield one. - switch(GetLogicalValue(GetParam(0).CalculateResultBoundaries(), - GetOpcode()==cAbsNotNot)) - { - case 0: goto ReplaceTreeWithZero; - case 1: goto ReplaceTreeWithOne; - default: ; - } - if(GetOpcode() == cNotNot && GetParam(0).IsAlwaysSigned(true)) - SetOpcode(cAbsNotNot); - - if(GetParam(0).GetOpcode() == cIf - || GetParam(0).GetOpcode() == cAbsIf) - { - CodeTree iftree = GetParam(0); - const CodeTree& ifp1 = iftree.GetParam(1); - const CodeTree& ifp2 = iftree.GetParam(2); - if(ifp1.GetOpcode() == cNot - || ifp1.GetOpcode() == cAbsNot) - { - // cNotNot [(cIf [x (cNot[y]) z])] -> cIf [x (cNot[y]) (cNotNot[z])] - SetParam(0, iftree.GetParam(0)); // condition - AddParam(ifp1); - CodeTree p2; - p2.SetOpcode(GetOpcode()); - p2.AddParam(ifp2); - p2.Rehash(); - AddParamMove(p2); - SetOpcode(iftree.GetOpcode()); - goto redo; - } - if(ifp2.GetOpcode() == cNot - || ifp2.GetOpcode() == cAbsNot) - { - // cNotNot [(cIf [x y (cNot[z])])] -> cIf [x (cNotNot[y]) (cNot[z])] - SetParam(0, iftree.GetParam(0)); // condition - CodeTree p1; - p1.SetOpcode(GetOpcode()); - p1.AddParam(ifp1); - p1.Rehash(); - AddParamMove(p1); - AddParam(ifp2); - SetOpcode(iftree.GetOpcode()); - goto redo; - } - } - break; - } - case cIf: - case cAbsIf: - { - if(ConstantFolding_IfOperations()) - goto redo; - break; - } - case cMul: - { - NowWeAreMulGroup: ; - ConstantFolding_Assimilate(); - // If one sub-expression evalutes to exact zero, yield zero. - double immed_product = 1.0; - size_t n_immeds = 0; bool needs_resynth=false; - for(size_t a=0; a 1 || (n_immeds == 1 && FloatEqual(immed_product, 1.0))) - needs_resynth = true; - if(needs_resynth) - { - // delete immeds and add new ones - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "cMul: Will add new immed " << immed_product << "\n"; - #endif - for(size_t a=GetParamCount(); a-->0; ) - if(GetParam(a).IsImmed()) - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << " - For that, deleting immed " << GetParam(a).GetImmed(); - std::cout << "\n"; - #endif - DelParam(a); - } - if(!FloatEqual(immed_product, 1.0)) - AddParam( CodeTree(immed_product) ); - } - switch(GetParamCount()) - { - case 0: goto ReplaceTreeWithOne; - case 1: goto ReplaceTreeWithParam0; // Replace self with the single operand - default: - if(ConstantFolding_MulGrouping()) goto redo; - if(ConstantFolding_MulLogicItems()) goto redo; - } - break; - } - case cAdd: - { - ConstantFolding_Assimilate(); - double immed_sum = 0.0; - size_t n_immeds = 0; bool needs_resynth=false; - for(size_t a=0; a 1 || (n_immeds == 1 && immed_sum == 0.0)) - needs_resynth = true; - if(needs_resynth) - { - // delete immeds and add new ones - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "cAdd: Will add new immed " << immed_sum << "\n"; - std::cout << "In: "; DumpTree(*this); - std::cout << "\n"; - #endif - for(size_t a=GetParamCount(); a-->0; ) - if(GetParam(a).IsImmed()) - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << " - For that, deleting immed " << GetParam(a).GetImmed(); - std::cout << "\n"; - #endif - DelParam(a); - } - if(!(immed_sum == 0.0)) - AddParam( CodeTree(immed_sum) ); - } - switch(GetParamCount()) - { - case 0: goto ReplaceTreeWithZero; - case 1: goto ReplaceTreeWithParam0; // Replace self with the single operand - default: - if(ConstantFolding_AddGrouping()) goto redo; - if(ConstantFolding_AddLogicItems()) goto redo; - } - break; - } - case cMin: - { - ConstantFolding_Assimilate(); - /* Goal: If there is any pair of two operands, where - * their ranges form a disconnected set, i.e. as below: - * xxxxx - * yyyyyy - * Then remove the larger one. - * - * Algorithm: 1. figure out the smallest maximum of all operands. - * 2. eliminate all operands where their minimum is - * larger than the selected maximum. - */ - size_t preserve=0; - MinMaxTree smallest_maximum; - for(size_t a=0; a 0; ) - { - MinMaxTree p = GetParam(a).CalculateResultBoundaries(); - if(p.has_min && a != preserve && p.min >= smallest_maximum.max) - DelParam(a); - } - //fprintf(stderr, "Remains: %u\n", (unsigned)GetParamCount()); - if(GetParamCount() == 1) - { - // Replace self with the single operand - goto ReplaceTreeWithParam0; - } - break; - } - case cMax: - { - ConstantFolding_Assimilate(); - /* Goal: If there is any pair of two operands, where - * their ranges form a disconnected set, i.e. as below: - * xxxxx - * yyyyyy - * Then remove the smaller one. - * - * Algorithm: 1. figure out the biggest minimum of all operands. - * 2. eliminate all operands where their maximum is - * smaller than the selected minimum. - */ - size_t preserve=0; - MinMaxTree biggest_minimum; - for(size_t a=0; a biggest_minimum.min)) - { - biggest_minimum.min = p.min; - biggest_minimum.has_min = true; - preserve=a; - } } - if(biggest_minimum.has_min) - { - //fprintf(stderr, "Removing all where max < %g\n", biggest_minimum.min); - for(size_t a=GetParamCount(); a-- > 0; ) - { - MinMaxTree p = GetParam(a).CalculateResultBoundaries(); - if(p.has_max && a != preserve && p.max < biggest_minimum.min) - { - //fprintf(stderr, "Removing %g\n", p.max); - DelParam(a); - } - } - } - //fprintf(stderr, "Remains: %u\n", (unsigned)GetParamCount()); - if(GetParamCount() == 1) - { - // Replace self with the single operand - goto ReplaceTreeWithParam0; - } - break; - } - - case cEqual: - case cNEqual: - case cLess: - case cGreater: - case cLessOrEq: - case cGreaterOrEq: - if(ConstantFolding_ComparisonOperations()) goto redo; - // Any reversible functions: - // sin(x) -> ASIN: Not doable, x can be cyclic - // asin(x) -> SIN: doable. - // Invalid combinations are caught by - // range-estimation. Threshold is at |pi/2|. - // acos(x) -> COS: doable. - // Invalid combinations are caught by - // range-estimation. Note that though - // the range is contiguous, it is direction-flipped. - // log(x) -> EXP: no problem - // exp2, exp10: Converted to cPow, done by grammar. - // atan(x) -> TAN: doable. - // Invalid combinations are caught by - // range-estimation. Threshold is at |pi/2|. - // sinh(x) -> ASINH: no problem - // tanh(x) -> ATANH: no problem, but atanh is limited to -1..1 - // Invalid combinations are caught by - // range-estimation, but the exact value - // of 1.0 still needs checking, because - // it involves infinity. - if(GetParam(1).IsImmed()) - switch(GetParam(0).GetOpcode()) - { - case cAsin: - SetParam(0, GetParam(0).GetParam(0)); - SetParam(1, CodeTree(fp_sin(GetParam(1).GetImmed()))); - goto redo; - case cAcos: - // -1..+1 --> pi..0 (polarity-flipping) - SetParam(0, GetParam(0).GetParam(0)); - SetParam(1, CodeTree(fp_cos(GetParam(1).GetImmed()))); - SetOpcode( GetOpcode()==cLess ? cGreater - : GetOpcode()==cLessOrEq ? cGreaterOrEq - : GetOpcode()==cGreater ? cLess - : GetOpcode()==cGreaterOrEq ? cLessOrEq - : GetOpcode() ); - goto redo; - case cAtan: - SetParam(0, GetParam(0).GetParam(0)); - SetParam(1, CodeTree(fp_tan(GetParam(1).GetImmed()))); - goto redo; - case cLog: - // Different logarithms have a constant-multiplication, - // which is no problem. - SetParam(0, GetParam(0).GetParam(0)); - SetParam(1, CodeTree(fp_exp(GetParam(1).GetImmed()))); - goto redo; - case cSinh: - SetParam(0, GetParam(0).GetParam(0)); - SetParam(1, CodeTree(fp_asinh(GetParam(1).GetImmed()))); - goto redo; - case cTanh: - if(fabs(GetParam(1).GetImmed()) < 1.0) - { - SetParam(0, GetParam(0).GetParam(0)); - SetParam(1, CodeTree(fp_atanh(GetParam(1).GetImmed()))); - goto redo; - } - break; - default: break; - } - break; - - case cAbs: - { - /* If we know the operand is always positive, cAbs is redundant. - * If we know the operand is always negative, use actual negation. - */ - MinMaxTree p0 = GetParam(0).CalculateResultBoundaries(); - if(p0.has_min && p0.min >= 0.0) - goto ReplaceTreeWithParam0; - if(p0.has_max && p0.max <= NEGATIVE_MAXIMUM) - { - /* abs(negative) = negative*-1 */ - SetOpcode(cMul); - AddParam( CodeTree(-1.0) ); - /* The caller of ConstantFolding() will do Sort() and Rehash() next. - * Thus, no need to do it here. */ - /* We were changed into a cMul group. Do cMul folding. */ - goto NowWeAreMulGroup; - } - /* If the operand is a cMul group, find elements - * that are always positive and always negative, - * and move them out, e.g. abs(p*n*x*y) = p*(-n)*abs(x*y) - */ - if(GetParam(0).GetOpcode() == cMul) - { - const CodeTree& p = GetParam(0); - std::vector pos_set; - std::vector neg_set; - for(size_t a=0; a= 0.0) - { pos_set.push_back(p.GetParam(a)); } - if(p0.has_max && p0.max <= NEGATIVE_MAXIMUM) - { neg_set.push_back(p.GetParam(a)); } - } - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "Abs: mul group has " << pos_set.size() - << " pos, " << neg_set.size() << "neg\n"; - #endif - if(!pos_set.empty() || !neg_set.empty()) - { - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "AbsReplace-Before: "; - DumpTree(*this); - std::cout << "\n" << std::flush; - DumpHashes(*this, std::cout); - #endif - CodeTree pclone; - pclone.SetOpcode(cMul); - for(size_t a=0; a= 0.0) - || (p0.has_max && p0.max <= NEGATIVE_MAXIMUM)) - {/*pclone.DelParam(a);*/} - else - pclone.AddParam( p.GetParam(a) ); - /* Here, p*n*x*y -> x*y. - * p is saved in pos_set[] - * n is saved in neg_set[] - */ - } - pclone.Rehash(); - CodeTree abs_mul; - abs_mul.SetOpcode(cAbs); - abs_mul.AddParamMove(pclone); - abs_mul.Rehash(); - CodeTree mulgroup; - mulgroup.SetOpcode(cMul); - mulgroup.AddParamMove(abs_mul); // cAbs[whatever remains in p] - mulgroup.AddParamsMove(pos_set); - /* Now: - * mulgroup = p * Abs(x*y) - */ - if(!neg_set.empty()) - { - if(neg_set.size() % 2) - mulgroup.AddParam( CodeTree(-1.0) ); - mulgroup.AddParamsMove(neg_set); - /* Now: - * mulgroup = p * n * -1 * Abs(x*y) - */ - } - Become(mulgroup); - #ifdef DEBUG_SUBSTITUTIONS - std::cout << "AbsReplace-After: "; - DumpTree(*this, std::cout); - std::cout << "\n" << std::flush; - DumpHashes(*this, std::cout); - #endif - /* We were changed into a cMul group. Do cMul folding. */ - goto NowWeAreMulGroup; - } - } - break; - } - - #define HANDLE_UNARY_CONST_FUNC(funcname) \ - if(GetParam(0).IsImmed()) \ - { const_value = funcname(GetParam(0).GetImmed()); \ - goto ReplaceTreeWithConstValue; } - - case cLog: - HANDLE_UNARY_CONST_FUNC(log); - if(GetParam(0).GetOpcode() == cPow) - { - CodeTree pow = GetParam(0); - if(pow.GetParam(0).IsAlwaysSigned(true)) // log(posi ^ y) = y*log(posi) - { - pow.CopyOnWrite(); - pow.SetOpcode(cLog); - SetOpcode(cMul); - AddParamMove(pow.GetParam(1)); - pow.DelParam(1); - pow.Rehash(); - SetParamMove(0, pow); - goto NowWeAreMulGroup; - } - if(pow.GetParam(1).IsAlwaysParity(false)) // log(x ^ even) = even*log(abs(x)) - { - pow.CopyOnWrite(); - CodeTree abs; - abs.SetOpcode(cAbs); - abs.AddParamMove(pow.GetParam(0)); - abs.Rehash(); - pow.SetOpcode(cLog); - SetOpcode(cMul); - pow.SetParamMove(0, abs); - AddParamMove(pow.GetParam(1)); - pow.DelParam(1); - pow.Rehash(); - SetParamMove(0, pow); - goto NowWeAreMulGroup; - } - } - else if(GetParam(0).GetOpcode() == cAbs) - { - // log(abs(x^y)) = y*log(abs(x)) - CodeTree pow = GetParam(0).GetParam(0); - if(pow.GetOpcode() == cPow) - { - pow.CopyOnWrite(); - CodeTree abs; - abs.SetOpcode(cAbs); - abs.AddParamMove(pow.GetParam(0)); - abs.Rehash(); - pow.SetOpcode(cLog); - SetOpcode(cMul); - pow.SetParamMove(0, abs); - AddParamMove(pow.GetParam(1)); - pow.DelParam(1); - pow.Rehash(); - SetParamMove(0, pow); - goto NowWeAreMulGroup; - } - } - break; - case cAcosh: HANDLE_UNARY_CONST_FUNC(fp_acosh); break; - case cAsinh: HANDLE_UNARY_CONST_FUNC(fp_asinh); break; - case cAtanh: HANDLE_UNARY_CONST_FUNC(fp_atanh); break; - case cAcos: HANDLE_UNARY_CONST_FUNC(fp_acos); break; - case cAsin: HANDLE_UNARY_CONST_FUNC(fp_asin); break; - case cAtan: HANDLE_UNARY_CONST_FUNC(fp_atan); break; - case cCosh: HANDLE_UNARY_CONST_FUNC(fp_cosh); break; - case cSinh: HANDLE_UNARY_CONST_FUNC(fp_sinh); break; - case cTanh: HANDLE_UNARY_CONST_FUNC(fp_tanh); break; - case cSin: HANDLE_UNARY_CONST_FUNC(fp_sin); break; - case cCos: HANDLE_UNARY_CONST_FUNC(fp_cos); break; - case cTan: HANDLE_UNARY_CONST_FUNC(fp_tan); break; - case cCeil: HANDLE_UNARY_CONST_FUNC(fp_ceil); break; - case cTrunc: HANDLE_UNARY_CONST_FUNC(fp_trunc); break; - case cFloor: HANDLE_UNARY_CONST_FUNC(fp_floor); break; - case cCbrt: HANDLE_UNARY_CONST_FUNC(fp_cbrt); break; // converted into cPow x 0.33333 - case cSqrt: HANDLE_UNARY_CONST_FUNC(fp_sqrt); break; // converted into cPow x 0.5 - case cExp: HANDLE_UNARY_CONST_FUNC(fp_exp); break; // convered into cPow CONSTANT_E x - case cInt: HANDLE_UNARY_CONST_FUNC(fp_int); break; - case cLog2: HANDLE_UNARY_CONST_FUNC(fp_log2); break; - case cLog10: HANDLE_UNARY_CONST_FUNC(fp_log10); break; - - case cLog2by: - if(GetParam(0).IsImmed() - && GetParam(1).IsImmed()) - { const_value = fp_log2(GetParam(0).GetImmed()) * GetParam(1).GetImmed(); - goto ReplaceTreeWithConstValue; } - break; - - case cMod: /* Can more be done than this? */ - if(GetParam(0).IsImmed() - && GetParam(1).IsImmed()) - { const_value = fmod(GetParam(0).GetImmed(), GetParam(1).GetImmed()); - goto ReplaceTreeWithConstValue; } - break; - - case cAtan2: - { - /* Range based optimizations for (y,x): - * If y is +0 and x <= -0, +pi is returned - * If y is -0 and x <= -0, -pi is returned (assumed never happening) - * If y is +0 and x >= +0, +0 is returned - * If y is -0 and x >= +0, -0 is returned (assumed never happening) - * If x is +-0 and y < 0, -pi/2 is returned - * If x is +-0 and y > 0, +pi/2 is returned - * Otherwise, perform constant folding when available - * If we know x <> 0, convert into atan(y / x) - * TODO: Figure out whether the above step is wise - * It allows e.g. atan2(6*x, 3*y) -> atan(2*x/y) - * when we know y != 0 - */ - MinMaxTree p0 = GetParam(0).CalculateResultBoundaries(); - MinMaxTree p1 = GetParam(1).CalculateResultBoundaries(); - if(GetParam(0).IsImmed() - && FloatEqual(GetParam(0).GetImmed(), 0.0)) // y == 0 - { - if(p1.has_max && p1.max < 0) // y == 0 && x < 0 - { const_value = CONSTANT_PI; goto ReplaceTreeWithConstValue; } - if(p1.has_min && p1.min >= 0.0) // y == 0 && x >= 0.0 - { const_value = 0.0; goto ReplaceTreeWithConstValue; } - } - if(GetParam(1).IsImmed() - && FloatEqual(GetParam(1).GetImmed(), 0.0)) // x == 0 - { - if(p0.has_max && p0.max < 0) // y < 0 && x == 0 - { const_value = -CONSTANT_PIHALF; goto ReplaceTreeWithConstValue; } - if(p0.has_min && p0.min > 0) // y > 0 && x == 0 - { const_value = CONSTANT_PIHALF; goto ReplaceTreeWithConstValue; } - } - if(GetParam(0).IsImmed() - && GetParam(1).IsImmed()) - { const_value = atan2(GetParam(0).GetImmed(), - GetParam(1).GetImmed()); - goto ReplaceTreeWithConstValue; } - if((p1.has_min && p1.min > 0.0) // p1 != 0.0 - || (p1.has_max && p1.max < NEGATIVE_MAXIMUM)) // become atan(p0 / p1) - { - CodeTree pow_tree; - pow_tree.SetOpcode(cPow); - pow_tree.AddParamMove(GetParam(1)); - pow_tree.AddParam(CodeTree(-1.0)); - pow_tree.Rehash(); - CodeTree div_tree; - div_tree.SetOpcode(cMul); - div_tree.AddParamMove(GetParam(0)); - div_tree.AddParamMove(pow_tree); - div_tree.Rehash(); - SetOpcode(cAtan); - SetParamMove(0, div_tree); - DelParam(1); - } - break; - } - - case cPow: - { - if(ConstantFolding_PowOperations()) goto redo; - break; - } - - /* The following opcodes are processed by GenerateFrom() - * within fpoptimizer_bytecode_to_codetree.c and thus - * they will never occur in the calling context for the - * most of the parsing context. They may however occur - * at the late phase, so we deal with them. - */ - case cDiv: // converted into cPow y -1 - if(GetParam(0).IsImmed() - && GetParam(1).IsImmed() - && GetParam(1).GetImmed() != 0.0) - { const_value = GetParam(0).GetImmed() / GetParam(1).GetImmed(); - goto ReplaceTreeWithConstValue; } - break; - case cInv: // converted into cPow y -1 - if(GetParam(0).IsImmed() - && GetParam(0).GetImmed() != 0.0) - { const_value = 1.0 / GetParam(0).GetImmed(); - goto ReplaceTreeWithConstValue; } - // Note: Could use (mulgroup)^immed optimization from cPow - break; - case cSub: // converted into cMul y -1 - if(GetParam(0).IsImmed() - && GetParam(1).IsImmed()) - { const_value = GetParam(0).GetImmed() - GetParam(1).GetImmed(); - goto ReplaceTreeWithConstValue; } - break; - case cNeg: // converted into cMul x -1 - if(GetParam(0).IsImmed()) - { const_value = -GetParam(0).GetImmed(); - goto ReplaceTreeWithConstValue; } - break; - case cRad: // converted into cMul x CONSTANT_RD - if(GetParam(0).IsImmed()) - { const_value = GetParam(0).GetImmed() * CONSTANT_RD; - goto ReplaceTreeWithConstValue; } - break; - case cDeg: // converted into cMul x CONSTANT_DR - if(GetParam(0).IsImmed()) - { const_value = GetParam(0).GetImmed() * CONSTANT_DR; - goto ReplaceTreeWithConstValue; } - break; - case cSqr: // converted into cMul x x - if(GetParam(0).IsImmed()) - { const_value = GetParam(0).GetImmed() * GetParam(0).GetImmed(); - goto ReplaceTreeWithConstValue; } - break; - case cExp2: // converted into cPow 2.0 x - HANDLE_UNARY_CONST_FUNC(fp_exp2); break; - case cRSqrt: // converted into cPow x -0.5 - if(GetParam(0).IsImmed()) - { const_value = 1.0 / sqrt(GetParam(0).GetImmed()); - goto ReplaceTreeWithConstValue; } - break; - case cCot: // converted into cMul (cPow (cTan x) -1) - if(GetParam(0).IsImmed()) - { double tmp = tan(GetParam(0).GetImmed()); - if(tmp != 0.0) - { const_value = 1.0 / tmp; - goto ReplaceTreeWithConstValue; } } - break; - case cSec: // converted into cMul (cPow (cCos x) -1) - if(GetParam(0).IsImmed()) - { double tmp = cos(GetParam(0).GetImmed()); - if(tmp != 0.0) - { const_value = 1.0 / tmp; - goto ReplaceTreeWithConstValue; } } - break; - case cCsc: // converted into cMul (cPow (cSin x) -1) - if(GetParam(0).IsImmed()) - { double tmp = sin(GetParam(0).GetImmed()); - if(tmp != 0.0) - { const_value = 1.0 / tmp; - goto ReplaceTreeWithConstValue; } } - break; - - /* Opcodes that do not occur in the tree for other reasons */ - case cRDiv: // version of cDiv - case cRSub: // version of cSub - case cDup: - case cFetch: - case cPopNMov: - case cNop: - case cJump: - break; /* Should never occur */ - - /* Opcodes that we can't do anything about */ - case cPCall: - case cFCall: - case cEval: - break; - } - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_rangeestimation.c" -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" - -#include /* for CalculateResultBoundaries() */ - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; -using namespace FPoptimizer_CodeTree; - -//#define DEBUG_SUBSTITUTIONS_extra_verbose - -namespace FPoptimizer_CodeTree -{ - MinMaxTree CodeTree::CalculateResultBoundaries() const -#ifdef DEBUG_SUBSTITUTIONS_extra_verbose - { - MinMaxTree tmp = CalculateResultBoundaries_do(); - std::cout << "Estimated boundaries: "; - if(tmp.has_min) std::cout << tmp.min; else std::cout << "-inf"; - std::cout << " .. "; - if(tmp.has_max) std::cout << tmp.max; else std::cout << "+inf"; - std::cout << ": "; - FPoptimizer_CodeTree::DumpTree(*this); - std::cout << std::endl; - return tmp; - } - MinMaxTree CodeTree::CalculateResultBoundaries_do() const -#endif - { - using namespace std; - switch( GetOpcode() ) - { - case cImmed: - return MinMaxTree(GetImmed(), GetImmed()); // a definite value. - case cAnd: - case cAbsAnd: - case cOr: - case cAbsOr: - case cNot: - case cAbsNot: - case cNotNot: - case cAbsNotNot: - case cEqual: - case cNEqual: - case cLess: - case cLessOrEq: - case cGreater: - case cGreaterOrEq: - { - /* These operations always produce truth values (0 or 1) */ - /* Narrowing them down is a matter of performing Constant optimization */ - return MinMaxTree( 0.0, 1.0 ); - } - case cAbs: - { - /* cAbs always produces a positive value */ - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min && m.has_max) - { - if(m.min < 0.0 && m.max >= 0.0) // ex. -10..+6 or -6..+10 - { - /* -x..+y: spans across zero. min=0, max=greater of |x| and |y|. */ - double tmp = -m.min; if(tmp > m.max) m.max = tmp; - m.min = 0.0; m.has_min = true; - } - else if(m.min < 0.0) // ex. -10..-4 - { double tmp = m.max; m.max = -m.min; m.min = -tmp; } - } - else if(!m.has_min && m.has_max && m.max < 0.0) // ex. -inf..-10 - { - m.min = fabs(m.max); m.has_min = true; m.has_max = false; - } - else if(!m.has_max && m.has_min && m.min > 0.0) // ex. +10..+inf - { - m.min = fabs(m.min); m.has_min = true; m.has_max = false; - } - else // ex. -inf..+inf, -inf..+10, -10..+inf - { - // all of these cover -inf..0, 0..+inf, or both - m.min = 0.0; m.has_min = true; m.has_max = false; - } - return m; - } - - case cLog: /* Defined for 0.0 < x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) { if(m.min < 0.0) m.has_min = false; else m.min = log(m.min); } // No boundaries - if(m.has_max) { if(m.max < 0.0) m.has_max = false; else m.max = log(m.max); } - return m; - } - - case cLog2: /* Defined for 0.0 < x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) { if(m.min < 0.0) m.has_min = false; else m.min = fp_log2(m.min); } // No boundaries - if(m.has_max) { if(m.max < 0.0) m.has_max = false; else m.max = fp_log2(m.max); } - return m; - } - - case cLog10: /* Defined for 0.0 < x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) { if(m.min < 0.0) m.has_min = false; else m.min = fp_log10(m.min); } - if(m.has_max) { if(m.max < 0.0) m.has_max = false; else m.max = fp_log10(m.max); } - return m; - } - - case cAcosh: /* defined for 1.0 < x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) { if(m.min <= 1.0) m.has_min = false; else m.min = fp_acosh(m.min); } // No boundaries - if(m.has_max) { if(m.max <= 1.0) m.has_max = false; else m.max = fp_acosh(m.max); } - return m; - } - case cAsinh: /* defined for all values -inf <= x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) m.min = fp_asinh(m.min); // No boundaries - if(m.has_max) m.max = fp_asinh(m.max); - return m; - } - case cAtanh: /* defined for all values -inf <= x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) m.min = fp_atanh(m.min); // No boundaries - if(m.has_max) m.max = fp_atanh(m.max); - return m; - } - case cAcos: /* defined for -1.0 <= x < 1, results within CONSTANT_PI..0 */ - { - /* Somewhat complicated to narrow down from this */ - /* TODO: A resourceful programmer may add it later. */ - return MinMaxTree( 0.0, CONSTANT_PI ); - } - case cAsin: /* defined for -1.0 <= x < 1, results within -CONSTANT_PIHALF..CONSTANT_PIHALF */ - { - /* Somewhat complicated to narrow down from this */ - /* TODO: A resourceful programmer may add it later. */ - return MinMaxTree( -CONSTANT_PIHALF, CONSTANT_PIHALF ); - } - case cAtan: /* defined for all values -inf <= x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) m.min = atan(m.min); else { m.min = -CONSTANT_PIHALF; m.has_min = true; } - if(m.has_max) m.max = atan(m.max); else { m.max = CONSTANT_PIHALF; m.has_max = true; } - return m; - } - case cAtan2: /* too complicated to estimate */ - { - MinMaxTree p0 = GetParam(0).CalculateResultBoundaries(); - MinMaxTree p1 = GetParam(1).CalculateResultBoundaries(); - if(GetParam(0).IsImmed() - && FloatEqual(GetParam(0).GetImmed(), 0.0)) // y == 0 - { - // Either 0.0 or CONSTANT_PI - return MinMaxTree(0.0, CONSTANT_PI); - } - if(GetParam(1).IsImmed() - && FloatEqual(GetParam(1).GetImmed(), 0.0)) // x == 0 - { - // EIther -CONSTANT_PIHALF or +CONSTANT_PIHALF - return MinMaxTree(-CONSTANT_PIHALF, CONSTANT_PIHALF); - } - // Anything else - /* Somewhat complicated to narrow down from this */ - /* TODO: A resourceful programmer may add it later. */ - return MinMaxTree(-CONSTANT_PI, CONSTANT_PI); - } - - case cSin: - case cCos: - { - /* Could be narrowed down from here, - * but it's too complicated due to - * the cyclic nature of the function. */ - /* TODO: A resourceful programmer may add it later. */ - return MinMaxTree(-1.0, 1.0); - } - case cTan: - { - /* Could be narrowed down from here, - * but it's too complicated due to - * the cyclic nature of the function */ - /* TODO: A resourceful programmer may add it later. */ - return MinMaxTree(); // (CONSTANT_NEG_INF, CONSTANT_POS_INF); - } - - case cCeil: - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - m.max = std::ceil(m.max); // ceil() may increase the value, may not decrease - return m; - } - case cFloor: - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - m.min = std::floor(m.min); // floor() may decrease the value, may not increase - return m; - } - case cTrunc: - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - m.min = std::floor(m.min); // trunc() may either increase or decrease the value - m.max = std::ceil(m.max); // for safety, we assume both - return m; - } - case cInt: - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - m.min = std::floor(m.min); // int() may either increase or decrease the value - m.max = std::ceil(m.max); // for safety, we assume both - return m; - } - case cSinh: /* defined for all values -inf <= x <= inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) m.min = sinh(m.min); // No boundaries - if(m.has_max) m.max = sinh(m.max); - return m; - } - case cTanh: /* defined for all values -inf <= x <= inf, results within -1..1 */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) m.min = tanh(m.min); else { m.has_min = true; m.min =-1.0; } - if(m.has_max) m.max = tanh(m.max); else { m.has_max = true; m.max = 1.0; } - return m; - } - case cCosh: /* defined for all values -inf <= x <= inf, results within 1..inf */ - { - MinMaxTree m = GetParam(0).CalculateResultBoundaries(); - if(m.has_min) - { - if(m.has_max) // max, min - { - if(m.min >= 0.0 && m.max >= 0.0) // +x .. +y - { m.min = cosh(m.min); m.max = cosh(m.max); } - else if(m.min < 0.0 && m.max >= 0.0) // -x .. +y - { double tmp = cosh(m.min); m.max = cosh(m.max); - if(tmp > m.max) m.max = tmp; - m.min = 1.0; } - else // -x .. -y - { m.min = cosh(m.min); m.max = cosh(m.max); - std::swap(m.min, m.max); } - } - else // min, no max - { - if(m.min >= 0.0) // 0..inf -> 1..inf - { m.has_max = false; m.min = cosh(m.min); } - else - { m.has_max = false; m.min = 1.0; } // Anything between 1..inf - } - } - else // no min - { - m.has_min = true; m.min = 1.0; // always a lower boundary - if(m.has_max) // max, no min - { - m.min = cosh(m.max); // n..inf - m.has_max = false; // No upper boundary - } - else // no max, no min - m.has_max = false; // No upper boundary - } - return m; - } - - case cIf: - case cAbsIf: - { - // No guess which branch is chosen. Produce a spanning min & max. - MinMaxTree res1 = GetParam(1).CalculateResultBoundaries(); - MinMaxTree res2 = GetParam(2).CalculateResultBoundaries(); - if(!res2.has_min) res1.has_min = false; else if(res1.has_min && res2.min < res1.min) res1.min = res2.min; - if(!res2.has_max) res1.has_max = false; else if(res1.has_max && res2.max > res1.max) res1.max = res2.max; - return res1; - } - - case cMin: - { - bool has_unknown_min = false; - bool has_unknown_max = false; - - MinMaxTree result; - for(size_t a=0; a result.min) - result.min = m.min; - - if(!m.has_max) - has_unknown_max = true; - else if(!result.has_max || m.max > result.max) - result.max = m.max; - } - if(has_unknown_min) result.has_min = false; - if(has_unknown_max) result.has_max = false; - return result; - } - case cAdd: - { - /* It's complicated. Follow the logic below. */ - /* Note: This also deals with the following opcodes: - * cNeg, cSub, cRSub - */ - MinMaxTree result(0.0, 0.0); - for(size_t a=0; a result.max) std::swap(result.min, result.max); - return result; - } - case cMul: - { - /* It's very complicated. Follow the logic below. */ - struct Value - { - enum ValueType { Finite, MinusInf, PlusInf }; - ValueType valueType; - double value; - - Value(ValueType t): valueType(t), value(0) {} - Value(double v): valueType(Finite), value(v) {} - - bool isNegative() const - { - return valueType == MinusInf || - (valueType == Finite && value < 0.0); - } - - void operator*=(const Value& rhs) - { - if(valueType == Finite && rhs.valueType == Finite) - value *= rhs.value; - else - valueType = (isNegative() != rhs.isNegative() ? - MinusInf : PlusInf); - } - - bool operator<(const Value& rhs) const - { - return - (valueType == MinusInf && rhs.valueType != MinusInf) || - (valueType == Finite && - (rhs.valueType == PlusInf || - (rhs.valueType == Finite && value < rhs.value))); - } - }; - - struct MultiplicationRange - { - Value minValue, maxValue; - - MultiplicationRange(): - minValue(Value::PlusInf), - maxValue(Value::MinusInf) {} - - void multiply(Value value1, const Value& value2) - { - value1 *= value2; - if(value1 < minValue) minValue = value1; - if(maxValue < value1) maxValue = value1; - } - }; - - MinMaxTree result(1.0, 1.0); - for(size_t a=0; a result.max) std::swap(result.min, result.max); - return result; - } - case cMod: - { - /* TODO: The boundaries of modulo operator could be estimated better. */ - - MinMaxTree x = GetParam(0).CalculateResultBoundaries(); - MinMaxTree y = GetParam(1).CalculateResultBoundaries(); - - if(y.has_max) - { - if(y.max >= 0.0) - { - if(!x.has_min || x.min < 0) - return MinMaxTree(-y.max, y.max); - else - return MinMaxTree(0.0, y.max); - } - else - { - if(!x.has_max || x.max >= 0) - return MinMaxTree(y.max, -y.max); - else - return MinMaxTree(y.max, NEGATIVE_MAXIMUM); - } - } - else - return MinMaxTree(); - } - case cPow: - { - if(GetParam(1).IsImmed() && GetParam(1).GetImmed() == 0.0) - { - // Note: This makes 0^0 evaluate into 1. - return MinMaxTree(1.0, 1.0); // x^0 = 1 - } - if(GetParam(0).IsImmed() && GetParam(0).GetImmed() == 0.0) - { - // Note: This makes 0^0 evaluate into 0. - return MinMaxTree(0.0, 0.0); // 0^x = 0 - } - if(GetParam(0).IsImmed() && FloatEqual(GetParam(0).GetImmed(), 1.0)) - { - return MinMaxTree(1.0, 1.0); // 1^x = 1 - } - if(GetParam(1).IsImmed() - && GetParam(1).GetImmed() > 0 - && GetParam(1).IsAlwaysParity(false)) - { - // x ^ even_int_const always produces a non-negative value. - double exponent = GetParam(1).GetImmed(); - MinMaxTree tmp = GetParam(0).CalculateResultBoundaries(); - MinMaxTree result; - result.has_min = true; - result.min = 0; - if(tmp.has_min && tmp.min >= 0) - result.min = fp_pow(tmp.min, exponent); - else if(tmp.has_max && tmp.max <= 0) - result.min = fp_pow(tmp.max, exponent); - - result.has_max = false; - if(tmp.has_min && tmp.has_max) - { - result.has_max = true; - result.max = std::max(fabs(tmp.min), fabs(tmp.max)); - result.max = fp_pow(result.max, exponent); - } - return result; - } - - MinMaxTree p0 = GetParam(0).CalculateResultBoundaries(); - MinMaxTree p1 = GetParam(1).CalculateResultBoundaries(); - TriTruthValue p0_positivity = - (p0.has_min && p0.min >= 0.0) ? IsAlways - : (p0.has_max && p0.max < 0.0 ? IsNever - : Unknown); - TriTruthValue p1_evenness = GetParam(1).GetEvennessInfo(); - - /* If param0 IsAlways, the return value is also IsAlways */ - /* If param1 is even, the return value is IsAlways */ - /* If param1 is odd, the return value is same as param0's */ - /* If param0 is negative and param1 is not integer, - * the return value is imaginary (assumed Unknown) - * - * Illustrated in this truth table: - * P=positive, N=negative - * E=even, O=odd, U=not integer - * *=unknown, X=invalid (unknown), x=maybe invalid (unknown) - * - * param1: PE PO P* NE NO N* PU NU * - * param0: - * PE P P P P P P P P P - * PO P P P P P P P P P - * PU P P P P P P P P P - * P* P P P P P P P P P - * NE P N * P N * X X x - * NO P N * P N * X X x - * NU P N * P N * X X x - * N* P N * P N * X X x - * * P * * P * * x x * - * - * Note: This also deals with the following opcodes: - * cSqrt (param0, PU) (x^0.5) - * cRSqrt (param0, NU) (x^-0.5) - * cExp (PU, param1) (CONSTANT_E^x) - */ - TriTruthValue result_positivity = Unknown; - switch(p0_positivity) - { - case IsAlways: - // e.g. 5^x = positive. - result_positivity = IsAlways; - break; - case IsNever: - { - result_positivity = p1_evenness; - break; - } - default: - switch(p1_evenness) - { - case IsAlways: - // e.g. x^( 4) = positive - // e.g. x^(-4) = positive - result_positivity = IsAlways; - break; - case IsNever: - break; - case Unknown: - { - /* If p1 is const non-integer, - * assume the result is positive - * though it may be NaN instead. - */ - if(GetParam(1).IsImmed() - && GetParam(1).IsAlwaysInteger(false) - && GetParam(1).GetImmed() >= 0.0) - { - result_positivity = IsAlways; - } - break; - } - } - } - switch(result_positivity) - { - case IsAlways: - { - /* The result is always positive. - * Figure out whether we know the minimum value. */ - double min = 0.0; - if(p0.has_min && p1.has_min) - { - min = pow(p0.min, p1.min); - if(p0.min < 0.0 && (!p1.has_max || p1.max >= 0.0) && min >= 0.0) - min = 0.0; - } - if(p0.has_min && p0.min >= 0.0 && p0.has_max && p1.has_max) - { - double max = pow(p0.max, p1.max); - if(min > max) std::swap(min, max); - return MinMaxTree(min, max); - } - return MinMaxTree(min, false); - } - case IsNever: - { - /* The result is always negative. - * TODO: Figure out whether we know the maximum value. - */ - return MinMaxTree(false, NEGATIVE_MAXIMUM); - } - default: - { - /* It can be negative or positive. - * We know nothing about the boundaries. */ - break; - } - } - break; - } - - /* The following opcodes are processed by GenerateFrom() - * within fpoptimizer_bytecode_to_codetree.c and thus - * they will never occur in the calling context for the - * most of the parsing context. They may however occur - * at the late phase, so we deal with them. - */ - case cNeg: - { - CodeTree tmp; - tmp.SetOpcode(cMul); - tmp.AddParam(CodeTree(-1.0)); - tmp.AddParam(GetParam(0)); - return tmp.CalculateResultBoundaries(); - } - case cSub: // converted into cMul y -1 - { - CodeTree tmp, tmp2; - tmp2.SetOpcode(cNeg); - tmp2.AddParam(GetParam(1)); - tmp.SetOpcode(cAdd); - tmp.AddParam(GetParam(0)); - tmp.AddParamMove(tmp2); - return tmp.CalculateResultBoundaries(); - } - case cInv: // converted into cPow x -1 - { - CodeTree tmp; - tmp.SetOpcode(cPow); - tmp.AddParam(GetParam(0)); - tmp.AddParam(CodeTree(-1.0)); - return tmp.CalculateResultBoundaries(); - } - case cDiv: // converted into cPow y -1 - { - CodeTree tmp, tmp2; - tmp2.SetOpcode(cInv); - tmp2.AddParam(GetParam(1)); - tmp.SetOpcode(cMul); - tmp.AddParam(GetParam(0)); - tmp.AddParamMove(tmp2); - return tmp.CalculateResultBoundaries(); - } - case cRad: // converted into cMul x CONSTANT_RD - { - CodeTree tmp; - tmp.SetOpcode(cMul); - tmp.AddParam(GetParam(0)); - tmp.AddParam(CodeTree(CONSTANT_RD)); - return tmp.CalculateResultBoundaries(); - } - case cDeg: // converted into cMul x CONSTANT_DR - { - CodeTree tmp; - tmp.SetOpcode(cMul); - tmp.AddParam(GetParam(0)); - tmp.AddParam(CodeTree(CONSTANT_DR)); - return tmp.CalculateResultBoundaries(); - } - case cSqr: // converted into cMul x x or cPow x 2 - { - CodeTree tmp; - tmp.SetOpcode(cPow); - tmp.AddParam(GetParam(0)); - tmp.AddParam(CodeTree(2.0)); - return tmp.CalculateResultBoundaries(); - } - case cExp: // converted into cPow CONSTANT_E x - { - CodeTree tmp; - tmp.SetOpcode(cPow); - tmp.AddParam(CodeTree(CONSTANT_E)); - tmp.AddParam(GetParam(0)); - return tmp.CalculateResultBoundaries(); - } - case cExp2: // converted into cPow 2 x - { - CodeTree tmp; - tmp.SetOpcode(cPow); - tmp.AddParam(CodeTree(2.0)); - tmp.AddParam(GetParam(0)); - return tmp.CalculateResultBoundaries(); - } - case cCbrt: // converted into cPow x 0.33333333 - { - // However, contrary to x^(1/3), this allows - // negative values for x, and produces those - // as well. - MinMaxTree result = GetParam(0).CalculateResultBoundaries(); - if(result.has_min) result.min = fp_cbrt(result.min); - if(result.has_max) result.max = fp_cbrt(result.max); - return result; - } - case cSqrt: // converted into cPow x 0.5 - { - MinMaxTree result = GetParam(0).CalculateResultBoundaries(); - if(result.has_min) result.min = result.min < 0 ? 0 : fp_sqrt(result.min); - if(result.has_max) result.max = result.max < 0 ? 0 : fp_sqrt(result.max); - return result; - } - case cRSqrt: // converted into cPow x -0.5 - { - CodeTree tmp; - tmp.SetOpcode(cPow); - tmp.AddParam(GetParam(0)); - tmp.AddParam(CodeTree(-0.5)); - return tmp.CalculateResultBoundaries(); - } - case cLog2by: // converted into cMul y CONSTANT_L2I (cLog x) - { - CodeTree tmp, tmp2; - tmp2.SetOpcode(cLog2); - tmp2.AddParam(GetParam(0)); - tmp.SetOpcode(cMul); - tmp.AddParamMove(tmp2); - tmp.AddParam(GetParam(1)); - return tmp.CalculateResultBoundaries(); - } - case cCot: // converted into 1 / cTan - { - CodeTree tmp, tmp2; - tmp2.SetOpcode(cTan); - tmp2.AddParam(GetParam(0)); - tmp.SetOpcode(cInv); - tmp.AddParamMove(tmp2); - return tmp.CalculateResultBoundaries(); - } - case cSec: // converted into 1 / cCos - { - CodeTree tmp, tmp2; - tmp2.SetOpcode(cCos); - tmp2.AddParam(GetParam(0)); - tmp.SetOpcode(cInv); - tmp.AddParamMove(tmp2); - return tmp.CalculateResultBoundaries(); - } - case cCsc: // converted into 1 / cSin - { - CodeTree tmp, tmp2; - tmp2.SetOpcode(cSin); - tmp2.AddParam(GetParam(0)); - tmp.SetOpcode(cInv); - tmp.AddParamMove(tmp2); - return tmp.CalculateResultBoundaries(); - } - /* The following opcodes are processed by GenerateFrom() - * within fpoptimizer_bytecode_to_codetree.c and thus - * they will never occur in the calling context: - */ - break; /* Should never occur */ - - /* Opcodes that do not occur in the tree for other reasons */ - case cRDiv: // version of cDiv - case cRSub: // version of cSub - case cDup: - case cFetch: - case cPopNMov: - case cNop: - case cJump: - case VarBegin: - break; /* Should never occur */ - - /* Opcodes that are completely unpredictable */ - case cPCall: - break; - case cFCall: - break; // Cannot deduce - case cEval: - break; // Cannot deduce - } - return MinMaxTree(); /* Cannot deduce */ - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_transformations.c" -// line removed for fpoptimizer.c: #include "fpoptimizer_bytecodesynth.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_consts.h" - -#ifdef FP_SUPPORT_OPTIMIZER - -using namespace FUNCTIONPARSERTYPES; -//using namespace FPoptimizer_Grammar; - -//#define DEBUG_POWI -//#define DEBUG_SUBSTITUTIONS_CSE - -#if defined(__x86_64) || !defined(FP_SUPPORT_CBRT) -# define CBRT_IS_SLOW -#endif - -namespace FPoptimizer_ByteCode -{ - extern const unsigned char powi_table[256]; -} -namespace -{ - using namespace FPoptimizer_CodeTree; - - typedef - std::multimap > - TreeCountType; - - void FindTreeCounts(TreeCountType& TreeCounts, const CodeTree& tree) - { - TreeCountType::iterator i = TreeCounts.lower_bound(tree.GetHash()); - bool found = false; - for(; i != TreeCounts.end() && i->first == tree.GetHash(); ++i) - { - if(tree.IsIdenticalTo( i->second.second ) ) - { - i->second.first += 1; - found = true; - break; - } - } - if(!found) - { - TreeCounts.insert(i, std::make_pair(tree.GetHash(), std::make_pair(size_t(1), tree))); - } - - for(size_t a=0; a 0) - { - CodeTree tmp; - tmp.SetOpcode(cCbrt); - tmp.AddParamMove(tree); - tmp.Rehash(); - tree.swap(tmp); - --cbrt_count; - } - while(sqrt_count > 0) - { - CodeTree tmp; - tmp.SetOpcode(cSqrt); - if(inverted) - { - tmp.SetOpcode(cRSqrt); - inverted = false; - } - tmp.AddParamMove(tree); - tmp.Rehash(); - tree.swap(tmp); - --sqrt_count; - } - if(inverted) - { - CodeTree tmp; - tmp.SetOpcode(cInv); - tmp.AddParamMove(tree); - tree.swap(tmp); - } - } - - double CalculatePowiFactorCost(long abs_int_exponent) - { - static std::map cache; - std::map::iterator i = cache.lower_bound(abs_int_exponent); - if(i != cache.end() && i->first == abs_int_exponent) - return i->second; - std::pair result(abs_int_exponent, 0.0); - double& cost = result.second; - - while(abs_int_exponent > 1) - { - int factor = 0; - if(abs_int_exponent < 256) - { - factor = FPoptimizer_ByteCode::powi_table[abs_int_exponent]; - if(factor & 128) factor &= 127; else factor = 0; - if(factor & 64) factor = -(factor&63) - 1; - } - if(factor) - { - cost += CalculatePowiFactorCost(factor); - abs_int_exponent /= factor; - continue; - } - if(!(abs_int_exponent & 1)) - { - abs_int_exponent /= 2; - cost += 3; // sqr - } - else - { - cost += 3.5; // dup+mul - abs_int_exponent -= 1; - } - } - - cache.insert(i, result); - return cost; - } - - struct PowiResolver - { - /* Any exponentiation can be turned into one of these: - * - * x^y -> sqrt(x)^(y*2) = x Sqrt y*2 Pow - * x^y -> cbrt(x)^(y*3) = x Cbrt y*3 Pow - * x^y -> rsqrt(x)^(y*-2) = x RSqrt y*-2 Pow - * x^y -> x^(y-1/2) * sqrt(x) = x Sqrt x y-0.5 Pow Mul - * x^y -> x^(y-1/3) * cbrt(x) = x Cbrt x y-0.33 Pow Mul - * x^y -> x^(y+1/2) * rsqrt(x) = x Sqrt x y+0.5 Pow Mul - * x^y -> inv(x)^(-y) = x Inv -y Pow - * - * These rules can be applied recursively. - * The goal is to find the optimal chain of operations - * that results in the least number of sqrt,cbrt operations; - * an integer value of y, and that the integer is as close - * to zero as possible. - */ - static const unsigned MaxSep = 4; - - struct PowiResult - { - PowiResult() : - n_int_sqrt(0), - n_int_cbrt(0), - resulting_exponent(0), - sep_list() { } - - int n_int_sqrt; - int n_int_cbrt; - long resulting_exponent; - int sep_list[MaxSep]; - }; - - PowiResult CreatePowiResult(double exponent) const - { - static const double RootPowers[(1+4)*(1+3)] = - { - // (sqrt^n(x)) - 1.0, - 1.0 / (2), - 1.0 / (2*2), - 1.0 / (2*2*2), - 1.0 / (2*2*2*2), - // cbrt^1(sqrt^n(x)) - 1.0 / (3), - 1.0 / (3*2), - 1.0 / (3*2*2), - 1.0 / (3*2*2*2), - 1.0 / (3*2*2*2*2), - // cbrt^2(sqrt^n(x)) - 1.0 / (3*3), - 1.0 / (3*3*2), - 1.0 / (3*3*2*2), - 1.0 / (3*3*2*2*2), - 1.0 / (3*3*2*2*2*2), - // cbrt^3(sqrt^n(x)) - 1.0 / (3*3*3), - 1.0 / (3*3*3*2), - 1.0 / (3*3*3*2*2), - 1.0 / (3*3*3*2*2*2), - 1.0 / (3*3*3*2*2*2*2) - }; - - PowiResult result; - - int best_factor = FindIntegerFactor(exponent); - if(best_factor == 0) - { - #ifdef DEBUG_POWI - printf("no factor found for %g\n", exponent); - #endif - return result; // Unoptimizable - } - - double best_cost = EvaluateFactorCost(best_factor, 0, 0, 0) - + CalculatePowiFactorCost(long(exponent*best_factor)); - int s_count = 0; - int c_count = 0; - int mul_count = 0; - - #ifdef DEBUG_POWI - printf("orig = %g\n", exponent); - printf("plain factor = %d, cost %g\n", best_factor, best_cost); - #endif - - for(unsigned n_s=0; n_s= 5) break; - // When cbrt is implemented through exp and log, - // there is no advantage over exp(log()), so don't support it. -#endif - int n_sqrt = s%5; - int n_cbrt = s/5; - if(n_sqrt + n_cbrt > 4) continue; - - double changed_exponent = exponent; - changed_exponent -= RootPowers[s]; - - int factor = FindIntegerFactor(changed_exponent); - if(factor != 0) - { - double cost = EvaluateFactorCost - (factor, s_count + n_sqrt, c_count + n_cbrt, mul_count + 1) - + CalculatePowiFactorCost(long(changed_exponent*factor)); - - #ifdef DEBUG_POWI - printf("%d sqrt %d cbrt factor = %d, cost %g\n", - n_sqrt, n_cbrt, factor, cost); - #endif - if(cost < best_sep_cost) - { - best_selected_sep = s; - best_sep_factor = factor; - best_sep_cost = cost; - } - } - } - if(!best_selected_sep) break; - - result.sep_list[n_s] = best_selected_sep; - exponent -= RootPowers[best_selected_sep]; - s_count += best_selected_sep % 5; - c_count += best_selected_sep / 5; - best_cost = best_sep_cost; - best_factor = best_sep_factor; - mul_count += 1; - } - - result.resulting_exponent = (long) (exponent * best_factor + 0.5); - while(best_factor % 2 == 0) - { - ++result.n_int_sqrt; - best_factor /= 2; - } - while(best_factor % 3 == 0) - { - ++result.n_int_cbrt; - best_factor /= 3; - } - return result; - } - - private: - // Find the integer that "value" must be multiplied - // with to produce an integer... - // Consisting of factors 2 and 3 only. - bool MakesInteger(double value, int factor) const - { - double v = value * double(factor); - double diff = fabs(v - (double)(long)(v+0.5)); - //printf("factor %d: v=%.20f, diff=%.20f\n", factor,v, diff); - return diff < 1e-9; - } - int FindIntegerFactor(double value) const - { - int factor = (2*2*2*2); -#ifdef CBRT_IS_SLOW - // When cbrt is implemented through exp and log, - // there is no advantage over exp(log()), so don't support it. -#else - factor *= (3*3*3); -#endif - int result = 0; - if(MakesInteger(value, factor)) - { - result = factor; - while((factor % 2) == 0 && MakesInteger(value, factor/2)) - result = factor /= 2; - while((factor % 3) == 0 && MakesInteger(value, factor/3)) - result = factor /= 3; - } -#ifdef CBRT_IS_SLOW - if(result == 0) - { - /* Note: Even if we allow one cbrt, - * cbrt(cbrt(x)) still gets turned into - * exp(log(x)*0.111111) - * which gives an error when x < 0... - * should we use a special system here? - * i.e. exp(log(-5)*y) - * = -exp(log(5)*y) - * except when y is an even integer, - * when = exp(log(5)*y) - * We use a custom fp_pow() function - * in order to handle these situations. - */ - if(MakesInteger(value, 3)) return 3; // single cbrt opcode - } -#endif - return result; - } - - int EvaluateFactorCost(int factor, int s, int c, int nmuls) const - { - const int sqrt_cost = 6; -#ifdef CBRT_IS_SLOW - const int cbrt_cost = 25; -#else - const int cbrt_cost = 8; -#endif - int result = s * sqrt_cost + c * cbrt_cost; - while(factor % 2 == 0) { factor /= 2; result += sqrt_cost; } - while(factor % 3 == 0) { factor /= 3; result += cbrt_cost; } - result += nmuls; - return result; - } - }; -} - -namespace FPoptimizer_CodeTree -{ - bool CodeTree::RecreateInversionsAndNegations(bool prefer_base2) - { - bool changed = false; - - for(size_t a=0; a div_params; - CodeTree found_log2, found_log2by; - - if(true) - { - /* This lengthy bit of code - * changes log2(x)^3 * 5 - * to log2by(x, 5^(1/3)) ^ 3 - * which is better for runtime - * than log2by(x,1)^3 * 5 - */ - bool found_log2_on_exponent = false; - double log2_exponent = 0; - for(size_t a = GetParamCount(); a-- > 0; ) - { - const CodeTree& powgroup = GetParam(a); - if(powgroup.GetOpcode() == cPow - && powgroup.GetParam(0).GetOpcode() == cLog2 - && powgroup.GetParam(1).IsImmed()) - { - // Found log2 on exponent - found_log2_on_exponent = true; - log2_exponent = powgroup.GetParam(1).GetImmed(); - break; - } - } - if(found_log2_on_exponent) - { - double immeds = 1.0; - for(size_t a = GetParamCount(); a-- > 0; ) - { - const CodeTree& powgroup = GetParam(a); - if(powgroup.IsImmed()) - { - immeds *= powgroup.GetImmed(); - DelParam(a); - } - } - for(size_t a = GetParamCount(); a-- > 0; ) - { - CodeTree& powgroup = GetParam(a); - if(powgroup.GetOpcode() == cPow - && powgroup.GetParam(0).GetOpcode() == cLog2 - && powgroup.GetParam(1).IsImmed()) - { - CodeTree& log2 = powgroup.GetParam(0); - log2.CopyOnWrite(); - log2.SetOpcode(cLog2by); - log2.AddParam( CodeTree( fp_pow(immeds, 1.0 / log2_exponent) ) ); - log2.Rehash(); - break; - } - } - } - } - - for(size_t a = GetParamCount(); a-- > 0; ) - { - const CodeTree& powgroup = GetParam(a); - if(powgroup.GetOpcode() == cPow - && powgroup.GetParam(1).IsImmed()) - { - const CodeTree& exp_param = powgroup.GetParam(1); - double exponent = exp_param.GetImmed(); - if(FloatEqual(exponent, -1.0)) - { - CopyOnWrite(); - div_params.push_back(GetParam(a).GetParam(0)); - DelParam(a); // delete the pow group - } - else if(exponent < 0 && IsIntegerConst(exponent)) - { - CodeTree edited_powgroup; - edited_powgroup.SetOpcode(cPow); - edited_powgroup.AddParam(powgroup.GetParam(0)); - edited_powgroup.AddParam(CodeTree(-exponent)); - edited_powgroup.Rehash(); - div_params.push_back(edited_powgroup); - CopyOnWrite(); - DelParam(a); // delete the pow group - } - } - else if(powgroup.GetOpcode() == cLog2 && !found_log2.IsDefined()) - { - found_log2 = powgroup.GetParam(0); - CopyOnWrite(); - DelParam(a); - } - else if(powgroup.GetOpcode() == cLog2by && !found_log2by.IsDefined()) - { - found_log2by = powgroup; - CopyOnWrite(); - DelParam(a); - } - } - if(!div_params.empty()) - { - changed = true; - - CodeTree divgroup; - divgroup.SetOpcode(cMul); - divgroup.SetParamsMove(div_params); - divgroup.Rehash(); // will reduce to div_params[0] if only one item - CodeTree mulgroup; - mulgroup.SetOpcode(cMul); - mulgroup.SetParamsMove(GetParams()); - mulgroup.Rehash(); // will reduce to 1.0 if none remained in this cMul - if(mulgroup.IsImmed() && FloatEqual(mulgroup.GetImmed(), 1.0)) - { - SetOpcode(cInv); - AddParamMove(divgroup); - } - /*else if(mulgroup.IsImmed() && FloatEqual(mulgroup.GetImmed(), -1.0)) - { - CodeTree invgroup; - invgroup.SetOpcode(cInv); - invgroup.AddParamMove(divgroup); - invgroup.Rehash(); - SetOpcode(cNeg); - AddParamMove(invgroup); - }*/ - else - { - if(mulgroup.GetDepth() >= divgroup.GetDepth()) - { - SetOpcode(cDiv); - AddParamMove(mulgroup); - AddParamMove(divgroup); - } - else - { - SetOpcode(cRDiv); - AddParamMove(divgroup); - AddParamMove(mulgroup); - } - } - } - if(found_log2.IsDefined()) - { - CodeTree mulgroup; - mulgroup.SetOpcode(GetOpcode()); - mulgroup.SetParamsMove(GetParams()); - mulgroup.Rehash(); - while(mulgroup.RecreateInversionsAndNegations(prefer_base2)) - mulgroup.FixIncompleteHashes(); - SetOpcode(cLog2by); - AddParamMove(found_log2); - AddParamMove(mulgroup); - changed = true; - } - if(found_log2by.IsDefined()) - { - CodeTree mulgroup; - mulgroup.SetOpcode(cMul); - mulgroup.AddParamMove(found_log2by.GetParam(1)); - mulgroup.AddParamsMove(GetParams()); - mulgroup.Rehash(); - while(mulgroup.RecreateInversionsAndNegations(prefer_base2)) - mulgroup.FixIncompleteHashes(); - DelParams(); - SetOpcode(cLog2by); - AddParamMove(found_log2by.GetParam(0)); - AddParamMove(mulgroup); - changed = true; - } - break; - } - case cAdd: - { - std::vector sub_params; - - for(size_t a = GetParamCount(); a-- > 0; ) - if(GetParam(a).GetOpcode() == cMul) - { - bool is_signed = false; // if the mul group has a -1 constant... - - CodeTree& mulgroup = GetParam(a); - - for(size_t b=mulgroup.GetParamCount(); b-- > 0; ) - { - if(mulgroup.GetParam(b).IsImmed()) - { - double factor = mulgroup.GetParam(b).GetImmed(); - if(FloatEqual(factor, -1.0)) - { - mulgroup.CopyOnWrite(); - mulgroup.DelParam(b); - is_signed = !is_signed; - } - else if(FloatEqual(factor, -2.0)) - { - mulgroup.CopyOnWrite(); - mulgroup.DelParam(b); - mulgroup.AddParam( CodeTree(2.0) ); - is_signed = !is_signed; - } - } - } - if(is_signed) - { - mulgroup.Rehash(); - sub_params.push_back(mulgroup); - CopyOnWrite(); - DelParam(a); - } - } - else if(GetParam(a).GetOpcode() == cDiv) - { - bool is_signed = false; - CodeTree& divgroup = GetParam(a); - if(divgroup.GetParam(0).IsImmed()) - { - if(FloatEqual(divgroup.GetParam(0).GetImmed(), -1.0)) - { - divgroup.CopyOnWrite(); - divgroup.DelParam(0); - divgroup.SetOpcode(cInv); - is_signed = !is_signed; - } - } - if(is_signed) - { - divgroup.Rehash(); - sub_params.push_back(divgroup); - CopyOnWrite(); - DelParam(a); - } - } - else if(GetParam(a).GetOpcode() == cRDiv) - { - bool is_signed = false; - CodeTree& divgroup = GetParam(a); - if(divgroup.GetParam(1).IsImmed()) - { - if(FloatEqual(divgroup.GetParam(1).GetImmed(), -1.0)) - { - divgroup.CopyOnWrite(); - divgroup.DelParam(1); - divgroup.SetOpcode(cInv); - is_signed = !is_signed; - } - } - if(is_signed) - { - divgroup.Rehash(); - sub_params.push_back(divgroup); - CopyOnWrite(); - DelParam(a); - } - } - if(!sub_params.empty()) - { - CodeTree subgroup; - subgroup.SetOpcode(cAdd); - subgroup.SetParamsMove(sub_params); - subgroup.Rehash(); // will reduce to sub_params[0] if only one item - CodeTree addgroup; - addgroup.SetOpcode(cAdd); - addgroup.SetParamsMove(GetParams()); - addgroup.Rehash(); // will reduce to 0.0 if none remained in this cAdd - if(addgroup.IsImmed() && FloatEqual(addgroup.GetImmed(), 0.0)) - { - SetOpcode(cNeg); - AddParamMove(subgroup); - } - else - { - if(addgroup.GetDepth() == 1) - { - /* 5 - (x+y+z) is best expressed as rsub(x+y+z, 5); - * this has lowest stack usage. - * This is identified by addgroup having just one member. - */ - SetOpcode(cRSub); - AddParamMove(subgroup); - AddParamMove(addgroup); - } - else if(subgroup.GetOpcode() == cAdd) - { - /* a+b-(x+y+z) is expressed as a+b-x-y-z. - * Making a long chain of cSubs is okay, because the - * cost of cSub is the same as the cost of cAdd. - * Thus we get the lowest stack usage. - * This approach cannot be used for cDiv. - */ - SetOpcode(cSub); - AddParamMove(addgroup); - AddParamMove(subgroup.GetParam(0)); - for(size_t a=1; a 0) - { - // If one of the internal sqrts can be changed into rsqrt - signed_chain = true; - } - - #ifdef DEBUG_POWI - printf("Will resolve powi %g as powi(chain(%d,%d),%ld)", - fabs(p1.GetImmed()), - r.n_int_sqrt, - r.n_int_cbrt, - r.resulting_exponent); - for(unsigned n=0; n 0.0) - { - // Convert into cExp or Exp2. - // x^y = exp(log(x) * y) = - // Can only be done when x is positive, though. - if(prefer_base2) - { - double mulvalue = fp_log2( p0.GetImmed() ); - if(mulvalue == 1.0) - { - // exp2(1)^x becomes exp2(x) - DelParam(0); - } - else - { - // exp2(4)^x becomes exp2(4*x) - CodeTree exponent; - exponent.SetOpcode(cMul); - exponent.AddParam( CodeTree( mulvalue ) ); - exponent.AddParam(p1); - exponent.Rehash(); - SetParamMove(0, exponent); - DelParam(1); - } - SetOpcode(cExp2); - changed = true; - } - else - { - double mulvalue = std::log( p0.GetImmed() ); - if(mulvalue == 1.0) - { - // exp(1)^x becomes exp(x) - DelParam(0); - } - else - { - // exp(4)^x becomes exp(4*x) - CodeTree exponent; - exponent.SetOpcode(cMul); - exponent.AddParam( CodeTree( mulvalue ) ); - exponent.AddParam(p1); - exponent.Rehash(); - SetParamMove(0, exponent); - DelParam(1); - } - SetOpcode(cExp); - changed = true; - } - } - else if(p0.IsAlwaysSigned(true)) - { - if(prefer_base2) - { - CodeTree log; - log.SetOpcode(cLog2); - log.AddParam(p0); - log.Rehash(); - CodeTree exponent; - exponent.SetOpcode(cMul); - exponent.AddParam(p1); - exponent.AddParamMove(log); - exponent.Rehash(); - SetOpcode(cExp2); - SetParamMove(0, exponent); - DelParam(1); - changed = true; - } - else - { - CodeTree log; - log.SetOpcode(cLog); - log.AddParam(p0); - log.Rehash(); - CodeTree exponent; - exponent.SetOpcode(cMul); - exponent.AddParam(p1); - exponent.AddParamMove(log); - exponent.Rehash(); - SetOpcode(cExp); - SetParamMove(0, exponent); - DelParam(1); - changed = true; - } - } - } - break; - } - - default: break; - } - - if(changed) - goto exit_changed; - - return changed; - } - - bool ContainsOtherCandidates( - const CodeTree& within, - const CodeTree& tree, - const FPoptimizer_ByteCode::ByteCodeSynth& synth, - const TreeCountType& TreeCounts) - { - for(size_t b=tree.GetParamCount(), a=0; afirst != leaf.GetHash()) - continue; - - size_t score = i->second.first; - const CodeTree& candidate = i->second.second; - - // It must not yet have been synthesized - if(synth.Find(candidate)) - continue; - - // And it must not be a simple expression - // Because cImmed, VarBegin are faster than cFetch - if(leaf.GetDepth() <= 1) - continue; - - // It must always occur at least twice - if(score < 2) - continue; - - // And it must either appear on both sides - // of a cIf, or neither - if(IfBalanceGood(within, leaf).BalanceGood == false) - continue; - - return true; - } - if(ContainsOtherCandidates(within, leaf, synth, TreeCounts)) - return true; - } - return false; - } - - size_t CodeTree::SynthCommonSubExpressions( - FPoptimizer_ByteCode::ByteCodeSynth& synth) const - { - size_t stacktop_before = synth.GetStackTop(); - - /* Find common subtrees */ - TreeCountType TreeCounts; - FindTreeCounts(TreeCounts, *this); - - #ifdef DEBUG_SUBSTITUTIONS_CSE - DumpHashes(*this); - #endif - - /* Synthesize some of the most common ones */ - for(;;) - { - size_t best_score = 0; - TreeCountType::iterator synth_it; - for(TreeCountType::iterator - j,i = TreeCounts.begin(); - i != TreeCounts.end(); - i=j) - { - j=i; ++j; - - size_t score = i->second.first; - const CodeTree& tree = i->second.second; - - #ifdef DEBUG_SUBSTITUTIONS_CSE - std::cout << "Score " << score << ":\n"; - DumpTreeWithIndent(tree); - #endif - - // It must not yet have been synthesized - if(synth.Find(tree)) - { - TreeCounts.erase(i); - continue; - } - - // And it must not be a simple expression - // Because cImmed, VarBegin are faster than cFetch - if(tree.GetDepth() <= 1) - { - TreeCounts.erase(i); - continue; - } - - // It must always occur at least twice - if(score < 2) - { - TreeCounts.erase(i); - continue; - } - - // And it must either appear on both sides - // of a cIf, or neither - if(IfBalanceGood(*this, tree).BalanceGood == false) - { - TreeCounts.erase(i); - continue; - } - - // It must not contain other candidates - if(ContainsOtherCandidates(*this, tree, synth, TreeCounts)) - { - // Don't erase it; it may be a proper candidate later - continue; - } - - // Is a candidate. - score *= tree.GetDepth(); - if(score > best_score) - { best_score = score; synth_it = i; } - } - - if(best_score <= 0) break; // Didn't find anything. - - const CodeTree& tree = synth_it->second.second; - #ifdef DEBUG_SUBSTITUTIONS_CSE - std::cout << "Found Common Subexpression:"; DumpTree(tree); std::cout << "\n"; - #endif - /* Synthesize the selected tree */ - tree.SynthesizeByteCode(synth, false); - TreeCounts.erase(synth_it); - #ifdef DEBUG_SUBSTITUTIONS_CSE - std::cout << "Done with Common Subexpression:"; DumpTree(tree); std::cout << "\n"; - #endif - } - - return synth.GetStackTop() - stacktop_before; - } -} - -#endif - -#line 1 "fpoptimizer/fpoptimizer_main.c" -#include "fpconfig.h" -#include "fparser.h" -#include "fptypes.h" - -// line removed for fpoptimizer.c: #include "fpoptimizer_codetree.h" -// line removed for fpoptimizer.c: #include "fpoptimizer_optimize.h" - -using namespace FUNCTIONPARSERTYPES; - -#ifdef FP_SUPPORT_OPTIMIZER -using namespace FPoptimizer_CodeTree; - -template<> -void FunctionParserBase::Optimize() -{ - typedef double Value_t; - - CopyOnWrite(); - - //PrintByteCode(std::cout); - - CodeTree tree; - tree.GenerateFrom(data->ByteCode, data->Immed, *data); - - FPoptimizer_Optimize::ApplyGrammars(tree); - - std::vector byteCode; - std::vector immed; - size_t stacktop_max = 0; - tree.SynthesizeByteCode(byteCode, immed, stacktop_max); - - /*std::cout << std::flush; - std::cerr << std::flush; - fprintf(stderr, "Estimated stacktop %u\n", (unsigned)stacktop_max); - fflush(stderr);*/ - - if(data->StackSize != stacktop_max) - { - data->StackSize = stacktop_max; // note: gcc warning is meaningful -#ifndef FP_USE_THREAD_SAFE_EVAL - data->Stack.resize(stacktop_max); -#endif - } - - data->ByteCode.swap(byteCode); - data->Immed.swap(immed); - - //PrintByteCode(std::cout); -} - -template<> -void FunctionParserBase::Optimize() -{} - -template<> -void FunctionParserBase::Optimize() -{} - -template<> -void FunctionParserBase::Optimize() -{} - -#ifdef FP_SUPPORT_MPFR_FLOAT_TYPE -template<> -void FunctionParserBase::Optimize() -{} -#endif - -#ifdef FP_SUPPORT_GMP_INT_TYPE -template<> -void FunctionParserBase::Optimize() -{} -#endif - - -FUNCTIONPARSER_INSTANTIATE_TYPES - -#endif - -#line 1 "fpoptimizer/fpoptimizer_footer.txt" - -#endif - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fptypes.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fptypes.h deleted file mode 100644 index a38cc4c26b..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/fptypes.h +++ /dev/null @@ -1,267 +0,0 @@ -/***************************************************************************\ -|* Function Parser for C++ v4.0.3 *| -|*-------------------------------------------------------------------------*| -|* Copyright: Juha Nieminen, Joel Yliluoma *| -\***************************************************************************/ - -// NOTE: -// This file contains only internal types for the function parser library. -// You don't need to include this file in your code. Include "fparser.hh" -// only. - -#ifndef ONCE_FPARSER_TYPES_H_ -#define ONCE_FPARSER_TYPES_H_ - -#include "fpconfig.h" -#include - -#ifdef ONCE_FPARSER_H_ -# include -#endif - -namespace FUNCTIONPARSERTYPES -{ - enum OPCODE - { -// The order of opcodes in the function list must -// match that which is in the Functions[] array. - cAbs, - cAcos, cAcosh, - cAsin, cAsinh, - cAtan, cAtan2, cAtanh, - cCbrt, cCeil, - cCos, cCosh, cCot, cCsc, - cEval, - cExp, cExp2, cFloor, cIf, cInt, cLog, cLog10, cLog2, cMax, cMin, - cPow, cSec, cSin, cSinh, cSqrt, cTan, cTanh, - cTrunc, - -// These do not need any ordering: -// Except that if you change the order of {eq,neq,lt,le,gt,ge}, you -// must also change the order in ConstantFolding_ComparisonOperations(). - cImmed, cJump, - cNeg, cAdd, cSub, cMul, cDiv, cMod, - cEqual, cNEqual, cLess, cLessOrEq, cGreater, cGreaterOrEq, - cNot, cAnd, cOr, - cNotNot, /* Protects the double-not sequence from optimizations */ - - cDeg, cRad, /* Multiplication and division by 180 / pi */ - - cFCall, cPCall, - -#ifdef FP_SUPPORT_OPTIMIZER - cFetch, /* Same as Dup, except with absolute index - * (next value is index) */ - cPopNMov, /* cPopNMov(x,y) moves [y] to [x] and deletes anything - * above [x]. Used for disposing of temporaries. - */ - cLog2by, /* log2by(x,y) = log2(x) * y */ -#endif - cAbsAnd, /* As cAnd, but assume both operands are absolute values */ - cAbsOr, /* As cOr, but assume both operands are absolute values */ - cAbsNot, /* As cAbsNot, but assume the operand is an absolute value */ - cAbsNotNot, /* As cAbsNotNot, but assume the operand is an absolute value */ - cAbsIf, /* As cAbsIf, but assume the 1st operand is an absolute value */ - - cDup, /* Duplicates the last value in the stack: Push [Stacktop] */ - cInv, /* Inverts the last value in the stack (x = 1/x) */ - cSqr, /* squares the last operand in the stack, no push/pop */ - cRDiv, /* reverse division (not x/y, but y/x) */ - cRSub, /* reverse subtraction (not x-y, but y-x) */ - cRSqrt, /* inverse square-root (1/sqrt(x)) */ - - cNop, - VarBegin - }; - -#ifdef ONCE_FPARSER_H_ - struct FuncDefinition - { - enum FunctionFlags - { - Enabled = 0x01, - AngleIn = 0x02, - AngleOut = 0x04, - OkForInt = 0x08 - }; - -#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT - const char name[8]; -#else - struct name { } name; -#endif - unsigned params : 8; - unsigned flags : 8; - - inline bool enabled() const { return flags != 0; } - inline bool okForInt() const { return (flags & OkForInt) != 0; } - }; - -#ifndef FP_DISABLE_EVAL -# define FP_EVAL_FUNCTION_ENABLED \ - FuncDefinition::Enabled | FuncDefinition::OkForInt -#else -# define FP_EVAL_FUNCTION_ENABLED 0 -#endif -#ifdef FUNCTIONPARSER_SUPPORT_DEBUG_OUTPUT -# define FP_FNAME(n) n -#else -# define FP_FNAME(n) {} -#endif -// This list must be in the same order as that in OPCODE enum, -// because the opcode value is used to index this array, and -// the pointer to array element is used for generating the opcode. - const FuncDefinition Functions[]= - { - /*cAbs */ { FP_FNAME("abs"), 1, - FuncDefinition::Enabled | FuncDefinition::OkForInt }, - /*cAcos */ { FP_FNAME("acos"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleOut }, - /*cAcosh*/ { FP_FNAME("acosh"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleOut }, - /*cAsin */ { FP_FNAME("asin"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleOut }, - /*cAsinh*/ { FP_FNAME("asinh"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleOut }, - /*cAtan */ { FP_FNAME("atan"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleOut }, - /*cAtan2*/ { FP_FNAME("atan2"), 2, - FuncDefinition::Enabled | FuncDefinition::AngleOut }, - /*cAtanh*/ { FP_FNAME("atanh"), 1, FuncDefinition::Enabled }, - /*cCbrt */ { FP_FNAME("cbrt"), 1, FuncDefinition::Enabled }, - /*cCeil */ { FP_FNAME("ceil"), 1, FuncDefinition::Enabled }, - /*cCos */ { FP_FNAME("cos"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cCosh */ { FP_FNAME("cosh"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cCot */ { FP_FNAME("cot"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cCsc */ { FP_FNAME("csc"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cEval */ { FP_FNAME("eval"), 0, FP_EVAL_FUNCTION_ENABLED }, - /*cExp */ { FP_FNAME("exp"), 1, FuncDefinition::Enabled }, - /*cExp2 */ { FP_FNAME("exp2"), 1, FuncDefinition::Enabled }, - /*cFloor*/ { FP_FNAME("floor"), 1, FuncDefinition::Enabled }, - /*cIf */ { FP_FNAME("if"), 0, - FuncDefinition::Enabled | FuncDefinition::OkForInt }, - /*cInt */ { FP_FNAME("int"), 1, FuncDefinition::Enabled }, - /*cLog */ { FP_FNAME("log"), 1, FuncDefinition::Enabled }, - /*cLog10*/ { FP_FNAME("log10"), 1, FuncDefinition::Enabled }, - /*cLog2 */ { FP_FNAME("log2"), 1, FuncDefinition::Enabled }, - /*cMax */ { FP_FNAME("max"), 2, - FuncDefinition::Enabled | FuncDefinition::OkForInt }, - /*cMin */ { FP_FNAME("min"), 2, - FuncDefinition::Enabled | FuncDefinition::OkForInt }, - /*cPow */ { FP_FNAME("pow"), 2, FuncDefinition::Enabled }, - /*cSec */ { FP_FNAME("sec"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cSin */ { FP_FNAME("sin"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cSinh */ { FP_FNAME("sinh"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cSqrt */ { FP_FNAME("sqrt"), 1, - FuncDefinition::Enabled }, - /*cTan */ { FP_FNAME("tan"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cTanh */ { FP_FNAME("tanh"), 1, - FuncDefinition::Enabled | FuncDefinition::AngleIn }, - /*cTrunc*/ { FP_FNAME("trunc"), 1, - FuncDefinition::Enabled } - }; -#undef FP_FNAME - - struct NamePtr - { - const char* name; - unsigned nameLength; - - NamePtr(const char* n, unsigned l): name(n), nameLength(l) {} - - inline bool operator==(const NamePtr& rhs) const - { - return nameLength == rhs.nameLength - && std::memcmp(name, rhs.name, nameLength) == 0; - } - inline bool operator<(const NamePtr& rhs) const - { - for(unsigned i = 0; i < nameLength; ++i) - { - if(i == rhs.nameLength) return false; - const char c1 = name[i], c2 = rhs.name[i]; - if(c1 < c2) return true; - if(c2 < c1) return false; - } - return nameLength < rhs.nameLength; - } - }; - - template - struct NameData - { - enum DataType { CONSTANT, UNIT, FUNC_PTR, PARSER_PTR, VARIABLE }; - DataType type; - unsigned index; - Value_t value; - - NameData(DataType t, unsigned v) : type(t), index(v), value() { } - NameData(DataType t, Value_t v) : type(t), index(), value(v) { } - NameData() { } - }; - - template - class namePtrsType: public - std::map< - FUNCTIONPARSERTYPES::NamePtr, - FUNCTIONPARSERTYPES::NameData - > - { - }; - - const unsigned FUNC_AMOUNT = sizeof(Functions)/sizeof(Functions[0]); -#endif // ONCE_FPARSER_H_ -} - -#ifdef ONCE_FPARSER_H_ -#include - -template -struct FunctionParserBase::Data -{ - unsigned referenceCounter; - - unsigned numVariables; - std::string variablesString; - FUNCTIONPARSERTYPES::namePtrsType namePtrs; - - struct FuncPtrData - { - union - { - FunctionPtr funcPtr; - FunctionParserBase* parserPtr; - }; - unsigned params; - }; - - std::vector FuncPtrs; - std::vector FuncParsers; - - std::vector ByteCode; - std::vector Immed; -#ifndef FP_USE_THREAD_SAFE_EVAL - std::vector Stack; - // Note: When Stack exists, - // Stack.size() and StackSize are mutually redundant. -#endif - unsigned StackSize; - - Data(); - Data(const Data&); - Data& operator=(const Data&); // not implemented on purpose - ~Data(); -}; -#endif - -#include "fpaux.h" - -#endif diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash.h deleted file mode 100644 index d02659184f..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @file hash.h - * @author Thomas Lewiner - * @version - * @date - * - * @brief - * - */ -//________________________________________________ - - -#ifndef _HASH_H_ -#define _HASH_H_ - -// may be overridden by the preprocessor -#ifndef USE_HASH_PTR -# define USE_HASH_PTR 1 -#endif // USE_HASH_PTR - -// may be overridden by the preprocessor -#ifndef HASH_BITS -# define HASH_BITS 22 -#endif // HASH_BITS - -#ifndef NON_HASH_BITS -# define NON_HASH_BITS 22 -#endif // HASH_BITS - - - - -#if USE_HASH_PTR - -// #define HASH_HAS_ERASE 1 -# include "hash_ptr.h" - -#else // USE_HASH_PTR - -# undef HASH_HAS_ERASE -# include "hash_noptr.h" - -#endif // USE_HASH_PTR - - -#endif // _HASH_H_ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_noptr.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_noptr.h deleted file mode 100644 index dc021cccce..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_noptr.h +++ /dev/null @@ -1,251 +0,0 @@ -/** - * @file hash_noptr.h - * @author Thomas Lewiner - * @version - * @date - * - * @brief Hash table without pointers - * - */ -//________________________________________________ - - -#ifndef _HASH_H_ -# error This header should not be included directly! include hash.h instead -#endif // _HASH_H_ - -#pragma once - - -#include // memset - -#include "morton.h" - -//_____________________________________________________________________________ -// Class hash -template < typename Data > class Hash -//----------------------------------------------------------------------------- -{ -public: - typedef uint cntr ; -// static const cntr HASH_BITS = 16 ; -// static const cntr NON_HASH_BITS = 64-HASH_BITS ; - static const cntr HASH_SIZE = ((cntr)1< 0 ; --n, ++ptr ) - s += ( ptr->key != KEY_INV ) ; - return s ; - } - - bool insert( KeyData d ) - { - cntr h = hash( d.key ) ; - KeyData *p = _hash + h ; - const cntr skip = ((d.key>>HASH_BITS) & SKIP_MASK) + SKIP_MINI ; - cntr overflow = skip ; - while( p->key != KEY_INV && p->key != d.key ) - { // collision - h += skip ; - if( h < HASH_SIZE ) - p += skip ; - else - { - h &= HASH_MASK ; - p = _hash + h ; - if( !(overflow--) ) - return false ; - } - } - *p = d ; - return true ; - } - - const KeyData operator[] ( Key k ) const - { - cntr h = hash( k ) ; - const KeyData *p = _hash + h ; - const cntr skip = ((k>>HASH_BITS) & SKIP_MASK) + SKIP_MINI ; - cntr overflow = skip ; - while( p->key != k && p->key != KEY_INV ) - { // collision - h += skip ; - if( h < HASH_SIZE ) - p += skip ; - else - { - h &= HASH_MASK ; - p = _hash + h ; - if( !(overflow--) ) - return KD_INV ; - } - } - return *p ; - } - - KeyData &operator[] ( Key k ) - { - cntr h = hash( k ) ; - KeyData *p = _hash + h ; - const cntr skip = ((k>>HASH_BITS) & SKIP_MASK) + SKIP_MINI ; - cntr overflow = skip ; - while( p->key != k && p->key != KEY_INV ) - { // collision - h += skip ; - if( h < HASH_SIZE ) - p += skip ; - else - { - h &= HASH_MASK ; - p = _hash + h ; - if( !(overflow--) ) - return KD_INV ; - } - } - return *p ; - } - - - bool contains( Key k ) const { return (*this)[k].key == k ; } - - - - //------------------------------------------------ - // iterator - public : - /// iterator - class iterator - { - public : - // constructors - /// default constructors - iterator( Hash &hash_, cntr id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE) { while( _ptr != _last && _ptr->key == KEY_INV ) ++_ptr ; } - - /// destructor - ~iterator() {} - - /// copy constructor - iterator( const iterator &it ) : _ptr(it._ptr), _last(it._last) {} - - /// assignment operator - iterator &operator = ( const iterator &it ) - { _ptr = it._ptr; _last = it._last; return *this; } - - //----------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const iterator &it ) const { return _ptr == it._ptr ; } - /// inequality operator - inline bool operator !=( const iterator &it ) const { return _ptr != it._ptr ; } - - /// validation operator - inline bool operator ()() const { return _ptr != _last ; } - - /// key accessor - inline const Key &key() const { return _ptr->key ; } - - /// value accessor - inline const Data &operator * () const { return _ptr->data ; } - - /// value accessor - inline Data &operator * () { return _ptr->data ; } - - /// accesses the next position - inline iterator &operator ++() { while( (++_ptr != _last) && _ptr->key == KEY_INV ) ; return *this ; } - - //----------------------------------------------------------------------------- - // Elements - private : - KeyData *_ptr ; ///< position pointer - const KeyData *_last ; ///< last position pointer - }; - - //------------------------------------------------ - // const_iterator - public : - /// const_iterator - class const_iterator - { - public : - // constructors - /// default constructors - const_iterator( const Hash &hash_, cntr id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE) { while( _ptr != _last && _ptr->key == KEY_INV ) ++_ptr ; } - - /// destructor - ~const_iterator() {} - - /// copy constructor - const_iterator( const const_iterator &it ) : _ptr(it._ptr), _last(it._last) {} - - /// assignment operator - const_iterator &operator = ( const const_iterator &it ) - { _ptr = it._ptr; _last = it._last; return *this; } - - //----------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const const_iterator &it ) const { return _ptr == it._ptr ; } - /// inequality operator - inline bool operator !=( const const_iterator &it ) const { return _ptr != it._ptr ; } - - /// validation operator - inline bool operator ()() const { return _ptr != _last ; } - - /// key accessor - inline const Key &key() const { return _ptr->key ; } - - /// value accessor - inline const Data &operator * () const { return _ptr->data ; } - - /// accesses the next position - inline const_iterator &operator ++() { while( (++_ptr != _last) && _ptr->key == KEY_INV ) ; return *this ; } - - //----------------------------------------------------------------------------- - // Elements - private : - const KeyData * _ptr ; ///< position pointer - const KeyData * const _last ; ///< last position pointer - }; - - public : - /// Node iterator creation - iterator begin( cntr id = 0 ) { return iterator( *this, id ) ; } - /// Node const iterator creation - const_iterator cbegin( cntr id = 0 ) { return const_iterator( *this, id ) ; } - -}; -//_____________________________________________________________________________ - - - -/// hash function specification: no inversion -template <> inline Hash::cntr Hash::hash( Key k ) const { return k & HASH_MASK ; } - -/// hash function specification: inversion -template <> inline Hash::cntr Hash::hash( Key k ) const { return (k>>NON_HASH_BITS) & HASH_MASK ; } diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_octree.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_octree.cpp deleted file mode 100644 index 2c17aa0101..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_octree.cpp +++ /dev/null @@ -1,1356 +0,0 @@ -/** - * \file hash_octree.cpp - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with hashtable and hierarchical operations - */ -//_____________________________________________________________________________ - - -#ifndef WIN32 -#pragma implementation -#endif // WIN32 - - -#include -#include "hash_octree.h" - -/// invalid key -template<> Hash::KeyData Hash::KD_INV = { KEY_INV, R_INV } ; - - - -//_____________________________________________________________________________ -// Create the root -void HashOctree::init() -//----------------------------------------------------------------------------- -{ - _max_level = 0 ; - _max_field = R_INV ; - HashField::KeyData kd ; - kd.key = 1 ; - kd.data = 0.0 ; - _hash.insert( kd ) ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Check that each point scan or scribble is in the right node -bool HashOctree::check () -//----------------------------------------------------------------------------- -{ - bool result = true ; - - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - Key k = it.key() << 3 ; - bool has_son = false ; - bool all_sons = true ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( _hash[ k | i ].key != KEY_INV ) - has_son = true ; - else - all_sons = false ; - } - - if( it.is_leaf() && has_son ) - { - printf("(hash) Invalid leaf %d: value %f\n", (int)k, _hash[k].data ) ; - result = false ; - } - - if( has_son && !all_sons ) - { - printf("(hash) Invalid subdivision %d: value %f\n", (int)k, _hash[k].data ) ; - result = false ; - } - } - - return result ; -} -//_____________________________________________________________________________ - - - - - - -//_____________________________________________________________________________ -// Deletes the content of the octree -void HashOctree::clear_octree() -//----------------------------------------------------------------------------- -{ - _hash.reset() ; - _max_level = 0 ; - _max_field = R_INV ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// set the values of each leaf from the implicit function -bool HashOctree::set_impl( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - _max_field = -FLT_MAX ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - if( it.is_leaf() ) - { - real v = (*ref).value_at( it.top() ) ; - *it = v ; - v = fabs(v) ; - if( _max_field < v ) _max_field = v ; - } -// else -// *it = R_INV ; - } - -// printf( "max field: %f\n", max_field() ) ; - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool HashOctree::refine( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - clear() ; init() ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it = geom_root() ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - _hash[it.key()].data = it._field = R_INV ; - HashField::KeyData kd ; - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - s.push( geom_cell( kd.key, kd.data ) ) ; - } - - Level lv = it.lv()+1 ; - if( _max_level < lv ) _max_level = lv ; - } - - return refined ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool HashOctree::adapt( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - -#ifdef HASH_HAS_ERASE - _max_level = 0 ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it = geom_root() ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - geom_cell sons[8] ; - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; - - // look for the leaves - if( !it.is_leaf() ) - { - if( !(*ref).need_refine( it ) ) - { - // delete branch - std::stack del_s ; - del_s.push( it.key() ) ; - while( !del_s.empty() ) - { - Key n = del_s.top() << 3 ; - del_s.pop() ; - - for( int i = 0 ; i < 8 ; ++i ) - { - HashField::KeyData kd = _hash.erase( n|i ) ; - if( kd == HashField::KD_INV ) continue ; // is_leaf(n) - del_s.push( n|i ) ; - } - } - - refined = true ; - _hash[it.key()].data = 0.0 ; // leaf now! - if( _max_level < it.lv() ) _max_level = it.lv() ; - continue ; - } - - it.sons( sons, _hash ) ; - for( int i = 0 ; i < 8 ; ++i ) - s.push( sons[i] ) ; - - if( _max_level < sons[0].lv() ) _max_level = sons[0].lv() ; - continue ; - } - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - _hash[it.key()].data = it._field = R_INV ; - HashField::KeyData kd ; - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - s.push( geom_cell( kd.key, kd.data ) ) ; - } - - Level lv = it.lv()+1 ; - if( _max_level < lv ) _max_level = lv ; - } - - return refined ; - -#else // HASH_HAS_ERASE - // no remotion in the hash table! - return refine( ref ) ; -#endif // HASH_HAS_ERASE -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Draw the octree with wireframe -bool HashOctree::draw_wire() -//----------------------------------------------------------------------------- -{ - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - it.draw_wire() ; - - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with dots -bool HashOctree::draw_centers() -//----------------------------------------------------------------------------- -{ - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - ::glTexCoord1f( (GLfloat)fabs(*it / max_field()) ) ; - it.top().draw() ; - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Recursion structure -typedef struct -//----------------------------------------------------------------------------- -{ - enum { DUAL_VERTEX=0, DUAL_EDGE=1, DUAL_FACE=2, DUAL_CUBE=3 } type ; - Key cells[8] ; - int direction ; -} hash_dual_iterator_struct ; -//----------------------------------------------------------------------------- -// edge pattern for cubes -// direction : x -> 0, y -> 1, z -> 2, other -> -1 -static const int dir_edges[19][3] = { - {0,1,0}, {0,2,1}, {0,4,2}, {1,3,1}, {1,5,2}, {2,3,0}, {2,6,2}, {3,7,2}, {4,5,0}, {4,6,1}, {5,7,1}, {6,7,0}, - {0,5,-1}, {0,6,-1}, {1,7,-1}, {2,7,-1}, {0,3,-1}, {4,7,-1}, {0,7,-1} } ; -//_____________________________________________________________________________ - - - -#define PRINT_DUAL_DEBUG 0 - -//_____________________________________________________________________________ -// Debug print -void print_final_cube( Key *cells ) -{ -#if PRINT_DUAL_DEBUG - printf( "cube %d %d %d %d %d %d %d %d \n", - (int)(cells[0]), - (int)(cells[1]), - (int)(cells[2]), - (int)(cells[3]), - (int)(cells[4]), - (int)(cells[5]), - (int)(cells[6]), - (int)(cells[7]) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_cube( const char*ori, Key *cells ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->cube %d %d %d %d %d %d %d %d \n", ori, - (int)(cells[0]), - (int)(cells[1]), - (int)(cells[2]), - (int)(cells[3]), - (int)(cells[4]), - (int)(cells[5]), - (int)(cells[6]), - (int)(cells[7]) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_face( const char*ori, Key *cells ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->face %d %d %d %d\n", ori, - (int)(cells[0]), - (int)(cells[1]), - (int)(cells[2]), - (int)(cells[3]) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_edge( const char*ori, Key *cells ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->edge %d %d\n", ori, - (int)(cells[0]), - (int)(cells[1]) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_vertex( const char*ori, Key *cells ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->vertex %d\n", ori, - (int)(cells[0]) ) ; -#endif // PRINT_DUAL_DEBUG -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Rebuild the octree dual -bool HashOctree::dual_cubes_walk( hash_dual_walker &walker ) -//----------------------------------------------------------------------------- -{ - bool result = true ; - - - // face pattern for a cube - // direction : yz -> 0, zx -> 1, xy -> 2 - static const int faces[6][5] = { - {0,1,2,3, 2}, {4,5,6,7, 2}, {0,1,4,5, 1}, {2,3,6,7, 1}, {0,2,4,6, 0}, {1,3,5,7, 0} } ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - hash_dual_iterator_struct dual_it ; - dual_it.type = hash_dual_iterator_struct::DUAL_VERTEX ; - dual_it.cells[0] = (Key)1 ; - std::stack< hash_dual_iterator_struct > s ; - s.push( dual_it ) ; - - _dual_temp_memory = s.size() ; - while( !s.empty() ) - { - int s_size = s.size() ; - if( s_size > _dual_temp_memory ) _dual_temp_memory = s_size ; - - dual_it = s.top() ; - s.pop() ; - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // vertex case - if( dual_it.type == hash_dual_iterator_struct::DUAL_VERTEX ) - { - print_dual_vertex( "!", dual_it.cells ) ; - - Key v = dual_it.cells[0] ; - if( is_leaf(v) ) continue ; - v <<= 3 ; - - //_____________________________________________________________________________ - // vertex - dual_it.type = hash_dual_iterator_struct::DUAL_VERTEX ; - for( int i = 0 ; i < 8 ; ++i ) - { - dual_it.cells[0] = v | i ; - s.push( dual_it ) ; - print_dual_vertex( "vertex", dual_it.cells ) ; - } - - //_____________________________________________________________________________ - // edge - dual_it.type = hash_dual_iterator_struct::DUAL_EDGE ; - for( int i = 0 ; i < 12 ; ++i ) - { - dual_it.cells[0] = v | dir_edges[i][0] ; - dual_it.cells[1] = v | dir_edges[i][1] ; - dual_it.direction = dir_edges[i][2] ; - s.push( dual_it ) ; - print_dual_edge( "vertex", dual_it.cells ) ; - } - - //_____________________________________________________________________________ - // face - dual_it.type = hash_dual_iterator_struct::DUAL_FACE ; - for( int i = 0 ; i < 6 ; ++i ) - { - dual_it.cells[0] = v | faces[i][0] ; - dual_it.cells[1] = v | faces[i][1] ; - dual_it.cells[2] = v | faces[i][2] ; - dual_it.cells[3] = v | faces[i][3] ; - dual_it.direction = faces[i][4] ; - s.push( dual_it ) ; - print_dual_face( "vertex", dual_it.cells ) ; - } - - //_____________________________________________________________________________ - // cube - dual_it.type = hash_dual_iterator_struct::DUAL_CUBE ; - for( int i = 0 ; i < 8 ; ++i ) dual_it.cells[i] = v | i ; - s.push( dual_it ) ; - print_dual_cube( "vertex", dual_it.cells ) ; - - continue ; - } - - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // edge case - else if( dual_it.type == hash_dual_iterator_struct::DUAL_EDGE ) - { - print_dual_edge( "!", dual_it.cells ) ; - - Key all_sons[2][8] ; - Key v0 = dual_it.cells[0] << 3 ; - Key v1 = dual_it.cells[1] << 3 ; - if( is_leaf( dual_it.cells[0] ) ) - { - if( is_leaf( dual_it.cells[1] ) ) - continue ; - - // repeat father - for( int i = 0 ; i < 8 ; ++i ) - { - all_sons[0][i] = dual_it.cells[0] ; - all_sons[1][i] = v1 | i ; - } - } - else - { - if( is_leaf( dual_it.cells[1] ) ) - { - // repeat father - for( int i = 0 ; i < 8 ; ++i ) - { - all_sons[0][i] = v0 | i ; - all_sons[1][i] = dual_it.cells[1] ; - } - } - else - { - for( int i = 0 ; i < 8 ; ++i ) - { - all_sons[0][i] = v0 | i ; - all_sons[1][i] = v1 | i ; - } - } - } - - - //_____________________________________________________________________________ - // local cube - Key sons[8] ; - int dir = dual_it.direction ; - switch( dir ) - { - // x-aligned edge - case 0 : - sons[0] = all_sons[0][1] ; - sons[1] = all_sons[1][0] ; - sons[2] = all_sons[0][3] ; - sons[3] = all_sons[1][2] ; - sons[4] = all_sons[0][5] ; - sons[5] = all_sons[1][4] ; - sons[6] = all_sons[0][7] ; - sons[7] = all_sons[1][6] ; - break ; - - // y-aligned edge - case 1 : - sons[0] = all_sons[0][2] ; - sons[1] = all_sons[0][3] ; - sons[2] = all_sons[1][0] ; - sons[3] = all_sons[1][1] ; - sons[4] = all_sons[0][6] ; - sons[5] = all_sons[0][7] ; - sons[6] = all_sons[1][4] ; - sons[7] = all_sons[1][5] ; - break ; - - // z-aligned edge - case 2 : - sons[0] = all_sons[0][4] ; - sons[1] = all_sons[0][5] ; - sons[2] = all_sons[0][6] ; - sons[3] = all_sons[0][7] ; - sons[4] = all_sons[1][0] ; - sons[5] = all_sons[1][1] ; - sons[6] = all_sons[1][2] ; - sons[7] = all_sons[1][3] ; - break ; - } - - //_____________________________________________________________________________ - // edge - dual_it.direction = dir ; // same direction - dual_it.type = hash_dual_iterator_struct::DUAL_EDGE ; - for( int i = 0 ; i < 12 ; ++i ) - { - if( dir_edges[i][2] != dir ) continue ; - dual_it.cells[0] = sons[ dir_edges[i][0] ] ; - dual_it.cells[1] = sons[ dir_edges[i][1] ] ; - s.push( dual_it ) ; - print_dual_edge( "edge", dual_it.cells ) ; - } - - //_____________________________________________________________________________ - // face - dual_it.type = hash_dual_iterator_struct::DUAL_FACE ; - for( int i = 0 ; i < 6 ; ++i ) - { - if( faces[i][4] == dir ) continue ; - dual_it.cells[0] = sons[ faces[i][0] ] ; - dual_it.cells[1] = sons[ faces[i][1] ] ; - dual_it.cells[2] = sons[ faces[i][2] ] ; - dual_it.cells[3] = sons[ faces[i][3] ] ; - dual_it.direction = faces[i][4] ; - s.push( dual_it ) ; - print_dual_face( "edge", dual_it.cells ) ; - } - - //_____________________________________________________________________________ - // cube - dual_it.type = hash_dual_iterator_struct::DUAL_CUBE ; - for( int i = 0 ; i < 8 ; ++i ) dual_it.cells[i] = sons[i] ; - s.push( dual_it ) ; - print_dual_cube( "edge", dual_it.cells ) ; - - continue ; - } - - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // face case - else if( dual_it.type == hash_dual_iterator_struct::DUAL_FACE ) - { - print_dual_face( "!", dual_it.cells ) ; - - Key all_sons[4][8] ; - bool leaf = true ; - for( int i = 0 ; i < 4 ; ++i ) - { - if( is_leaf( dual_it.cells[i] ) ) - { - // repeat father - for( int j = 0 ; j < 8 ; ++j ) - all_sons[i][j] = dual_it.cells[i] ; - } - else - { - leaf = false ; - Key f = dual_it.cells[i] << 3 ; - for( int j = 0 ; j < 8 ; ++j ) - all_sons[i][j] = f | j ; - } - } - if( leaf ) continue ; - - - //_____________________________________________________________________________ - // local cube - Key sons[8] ; - int dir = dual_it.direction ; - switch( dir ) - { - // yz-aligned face - case 0 : - sons[0] = all_sons[0][6] ; - sons[1] = all_sons[0][7] ; - sons[2] = all_sons[1][4] ; - sons[3] = all_sons[1][5] ; - sons[4] = all_sons[2][2] ; - sons[5] = all_sons[2][3] ; - sons[6] = all_sons[3][0] ; - sons[7] = all_sons[3][1] ; - break ; - - // zx-aligned edge - case 1 : - sons[0] = all_sons[0][5] ; - sons[1] = all_sons[1][4] ; - sons[2] = all_sons[0][7] ; - sons[3] = all_sons[1][6] ; - sons[4] = all_sons[2][1] ; - sons[5] = all_sons[3][0] ; - sons[6] = all_sons[2][3] ; - sons[7] = all_sons[3][2] ; - break ; - - // xy-aligned edge - case 2 : - sons[0] = all_sons[0][3] ; - sons[1] = all_sons[1][2] ; - sons[2] = all_sons[2][1] ; - sons[3] = all_sons[3][0] ; - sons[4] = all_sons[0][7] ; - sons[5] = all_sons[1][6] ; - sons[6] = all_sons[2][5] ; - sons[7] = all_sons[3][4] ; - break ; - } - - //_____________________________________________________________________________ - // face - // same direction - dual_it.direction = dir ; - dual_it.type = hash_dual_iterator_struct::DUAL_FACE ; - for( int i = 0 ; i < 6 ; ++i ) - { - if( faces[i][4] != dir ) continue ; - dual_it.cells[0] = sons[ faces[i][0] ] ; - dual_it.cells[1] = sons[ faces[i][1] ] ; - dual_it.cells[2] = sons[ faces[i][2] ] ; - dual_it.cells[3] = sons[ faces[i][3] ] ; - // dual_it.direction = faces[i][4] ; - s.push( dual_it ) ; - print_dual_face( "face", dual_it.cells ) ; - } - - //_____________________________________________________________________________ - // cube - dual_it.type = hash_dual_iterator_struct::DUAL_CUBE ; - for( int i = 0 ; i < 8 ; ++i ) dual_it.cells[i] = sons[i] ; - s.push( dual_it ) ; - print_dual_cube( "face", dual_it.cells ) ; - - continue ; - } - - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // cube case - else if( dual_it.type == hash_dual_iterator_struct::DUAL_CUBE ) - { - print_dual_cube( "!", dual_it.cells ) ; - - bool leaf = true ; - - //_____________________________________________________________________________ - // cube - for( int i = 0 ; i < 8 ; ++i ) - { - // copy father - if( is_leaf( dual_it.cells[i] ) ) - continue ; - - // else - leaf = false ; - dual_it.cells[i] = ( dual_it.cells[i]<<3 ) | 7-i ; - } - - // finally add dual cube - if( leaf ) - { - result &= walker( *this, dual_it.cells ) ; - print_final_cube( dual_it.cells ) ; - } - else - { - s.push( dual_it ) ; - print_dual_cube( "cube", dual_it.cells ) ; - } - - continue ; - } - - } - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Isosurface walker -bool hash_isosurface_walker( HashOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MarchingCubes &mc = fo.mc() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - /** indexes of the cube */ - Key *indexes = mc.indexes() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const Key k = keys[j] ; - HashOctree::geom_cell c = fo.geom_key(k) ; - cube[i] = *c ; - - space[i] = (Point)c ; - indexes[i] = k ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool HashOctree::build_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc.dat_access() = ref ; - - printf( "Build isosurface... " ) ; - bool result = false ; - - //_________________________________________________________________________ - // Dual Marching Cubes - - _mc.init_all() ; - - result = dual_cubes_walk( hash_isosurface_walker ) ; - - _mc.clean_temps() ; - - printf( "generated %d vertices and %d faces!\n", _mc.nverts(), _mc.ntrigs() ) ; - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Isosurface drawing walker -bool hash_direct_isosurface_walker( HashOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MC_Draw &mc = fo.mc_draw() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const HashOctree::geom_cell c = fo.geom_key( keys[j] ) ; - cube[i] = *c ; - space[i] = (Point)c ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool HashOctree::direct_draw_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc_draw.dat_access() = ref ; - - bool result = false ; - - // Dual Marching Cubes - ::glBegin( GL_TRIANGLES ) ; - { - result = dual_cubes_walk( hash_direct_isosurface_walker ) ; - } - ::glEnd() ; // GL_TRIANGLES - - return result ; -} -//_____________________________________________________________________________ - - - - - - -//_____________________________________________________________________________ -// Draw walker -bool hash_draw_walker( HashOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - Cube cells[8] ; - for( int i = 0 ; i < 8 ; ++i ) - cells[i] = key2cube( keys[i] ) ; - - ((Point)cells[0]).draw() ; - ((Point)cells[1]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[3]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[2]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[0]).draw() ; - - ((Point)cells[4]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[5]).draw() ; - ((Point)cells[7]).draw() ; - - ((Point)cells[7]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[6]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[0]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[7]).draw() ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Draw the dual octree with wireframe -bool HashOctree::draw_dual() -//----------------------------------------------------------------------------- -{ - ::glBegin( GL_LINES ) ; - bool result = dual_cubes_walk( hash_draw_walker ) ; - ::glEnd() ; // GL_LINES - - return result ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Do nothing walker, just for dual generation timing -bool hash_timing_walker( HashOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - return true ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Do nothing, just for dual generation timing -bool HashOctree::dual_timing() -//----------------------------------------------------------------------------- -{ - return dual_cubes_walk( hash_timing_walker ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Prints statistics about the octree -void HashOctree::stats() -//----------------------------------------------------------------------------- -{ - uint level_dist[MAX_LEVEL+1] ; - memset( level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - - int s = 0 ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - ++s ; - if( it.is_leaf() ) level_dist[ it.lv() ] ++ ; - } - - printf( " number of nodes:\t%d\n", s ) ; -#if USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyBucket) ) ) ; - _hash.stats() ; -#else // USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyData ) ) ) ; -#endif // USE_HASH_PTR - - printf( " leaves' levels:\t" ) ; - for( Level l = 0 ; l <= MAX_LEVEL; ++l ) - printf( "\t%d", level_dist[l] ) ; - printf( "\n" ) ; - - printf( " max size of the stack:\t%d\n", _dual_temp_memory ) ; - printf( " total memory of stack:\t%d\n", (int) ( _dual_temp_memory * sizeof(hash_dual_iterator_struct) ) ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// search operations - - -//_____________________________________________________________________________ -// Find cells of the octree at a given position -bool HashOctree::find_leaf( real x, real y, real z, geom_cell &n ) const -//----------------------------------------------------------------------------- -{ - - n = geom_root() ; - - while( !n.is_leaf() ) - { - ++n.lv() ; - real sz = n.sz() ; - - // side test : - // 0->back lower left, 1->back lower right, 2->back upper left, 3->back upper right - // 4->front lower left, 5->front lower right, 6->front upper left, 7->front upper right - int i = ( (n.cz() < z) << 2 ) | ( (n.cy() < y) << 1 ) | (n.cx() < x) ; - n.cx() += (i&1) ? +sz : -sz ; - n.cy() += (i&2) ? +sz : -sz ; - n.cz() += (i&4) ? +sz : -sz ; - - geom_cell s ; - n.son(i,s,_hash) ; - n = s ; - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find cells of the octree inside a given box of center x,y and half side r -bool HashOctree::find_radius( real x, real y, real z, real r, List &cells ) const -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - geom_cell n = geom_root() ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - while( !s.empty() ) - { - n = s.top() ; s.pop() ; -// printf( "%d\t%.4f\t%.4f\t%.4f\n", (int)n.lv(), n.x(), n.y(), n.z() ) ; - if( n.is_leaf() ) - { - cells.insert( n ) ; - continue ; - } - - geom_cell sons[8] ; - n.sons( sons, _hash ) ; - real sz_ = sons[0].sz() + r ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( (fabs( sons[i].cx() - x ) < sz_ ) && - (fabs( sons[i].cy() - y ) < sz_ ) && - (fabs( sons[i].cz() - z ) < sz_ ) ) - s.push( sons[i] ) ; - } - } -// printf( "\n" ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find neighbor cells of the octree to a given cell -bool HashOctree::adjacent( const geom_cell &cell, List &cells ) const -//----------------------------------------------------------------------------- -{ - return find_radius( cell.cx(), cell.cy(), cell.cz(), cell.sz() + (real) 0.5 / (1 << max_level() ) , cells ) ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// I/O - -//_____________________________________________________________________________ -// Draws the intersecting cells of a plane with the octree with color -void HashOctree::draw_plane ( real nx, real ny, real nz, real d ) -//----------------------------------------------------------------------------- -{ - geom_cell n = geom_root() ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - //_____________________________________________________________________________ - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - //_____________________________________________________________________________ - - ::glLineWidth( 1.0f ) ; - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - - if( n.is_leaf() ) - { - - ::glTexCoord1f( (GLfloat)fabs(*n/max_field()) ) ; - ::glBegin( GL_LINES ) ; - n.draw_wire() ; - ::glEnd() ; // GL_LINES - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons, _hash ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draws the intersection of a plane with the octree with color -void HashOctree::draw_slice ( real nx, real ny, real nz, real d, float alpha ) -//----------------------------------------------------------------------------- -{ - geom_cell n = geom_root() ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - - - //_____________________________________________________________________________ - - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - if( n.is_leaf() ) - { - // retrieves the signs of each cube corner - real val[8] ; - real v = nx * n.cx() + ny * n.cy() + nz * n.cz() + d ; - real sz_ = n.sz() ; - int zeros = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - val[i] = v + nx * ((i&1)?sz_:-sz_) + ny * ((i&2)?sz_:-sz_) + nz * ((i&4)?sz_:-sz_) ; - if( fabs(val[i]) < R_EPSILON ) { val[i] = R_EPSILON ; ++zeros ; } - } - - //_________________________________________________________________________ - // degenerated intersection - if( zeros > 0 ) - { - int npos = 0, nneg = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) continue ; - if( val[i] < 0 ) - ++nneg ; - else - ++npos ; - } - float def = (nneg>npos) ? (float)R_EPSILON : -(float)R_EPSILON ; - - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) val[i] = def ; - } - // continue ; - } - - //_________________________________________________________________________ - // Continuation method - int v0=-1, v1=-1 ; // current edge vertices - - // get the first intersection - static int edges[12][2] = { {0,1}, {0,2}, {0,4}, {1,3}, {1,5}, {2,3}, {2,6}, {3,7}, {4,5}, {4,6}, {5,7}, {6,7} } ; - for( int e = 0 ; e < 12 ; ++e ) - { - if( val[ edges[e][0] ] * val[ edges[e][1] ] < 0 ) - { - v0 = edges[e][0] ; - v1 = edges[e][1] ; - break ; - } - } - int ov0 = v0, ov1 = v1 ; - - - // equation of previous face adjacent to v0v1: v>>c & 1 == s (c-th coordinate equal to +/- 1) - int pf = -1 ; bool ps ; - if ( (v0 & 1) == (v1 & 1) ) { pf = 0 ; ps = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( (v0 & 2) == (v1 & 2) ) { pf = 1 ; ps = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( (v0 & 4) == (v1 & 4) )*/ { pf = 2 ; ps = ((v0 & 4) >> 2 ) == 1 ; } - - // printf( "cube %d %d %d %d %d %d %d %d, march : (%d,%d) ", val[0]>0, val[1]>0, val[2]>0, val[3]>0, val[4]>0, val[5]>0, val[6]>0, val[7]>0, v0, v1 ) ; - - //_________________________________________________________________________ - // marching - - GLfloat color = (GLfloat)fabs(*n / max_field()) ; - //cmap.gl_color( at(*n) ) ; - ::glBegin( GL_POLYGON ) ; - { - do - { - // equation of next face adjacent to v0v1 - int nf = -1 ; bool ns ; - if ( pf != 0 && ((v0 & 1) == (v1 & 1)) ) { nf = 0 ; ns = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( pf != 1 && ((v0 & 2) == (v1 & 2)) ) { nf = 1 ; ns = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( pf != 2 && ((v0 & 4) == (v1 & 4)) )*/ { nf = 2 ; ns = ((v0 & 4) >> 2 ) == 1 ; } - - /* equivalent construction - // get the direction perpendicular to v0v1 - int of = (v0 ^ v1) & 7 ; // only bit of difference - of = of==1 ? 0 : (of==2 ? 1 : 2) ; - - // compute the equation of the next face adjacent to v0v1 - int nf = 3 - (pf+of) ; // third option: {pf,nf,of}={0,1,2} - bool ns = (v0 >> nf) & 1 ; // value of the edge on that direction - */ - - // compute the two next vertices (invert the pf-th bit - int v2 = ps ? ( v0 & (~(1< 0) | ((val[v2] > 0) << 1) | ((val[v1] > 0) << 2) | ((val[v0] > 0) << 3) ; - if( c > 7 ) c = (~c)&7 ; // consider v0 as negative, and thus v1 as positive - /* - if( c < 4 ) - { // degenerated intesection - printf( "degenerated intersection %d!\n", c ) ; - } - */ - - //_______________________________________________________________________ - // method of continuity on the cube surface - switch( c ) - { - case 4 : v0 = v3 ; break ; - case 5 : v0 = v2 ; v1 = v3 ; break ; - case 6 : /* impossible case */ break ; - case 7 : v1 = v2 ; break ; - } - - - - - real cx = n.cx(); - real cy = n.cy(); - real cz = n.cz(); - real sz = sz_; - real a0 = val[v0]; - int i0 = v0; - real a1 = val[v1]; - int i1 = v1; - - real w0 = a1 / (a1-a0) ; - real w1 = a0 / (a0-a1) ; - - real x = cx + w0 * ((i0&1)?sz:-sz) + w1 * ((i1&1)?sz:-sz); - real y = cy + w0 * ((i0&2)?sz:-sz) + w1 * ((i1&2)?sz:-sz); - real z = cz + w0 * ((i0&4)?sz:-sz) + w1 * ((i1&4)?sz:-sz); - - ::glTexCoord1d( color ) ; - ::glVertex3d(x, y, z) ; - - // next face - pf = nf ; ps = ns ; - - // printf( "(%d,%d) ", v0, v1 ) ; - } while( v0 != ov0 || v1 != ov1 ) ; - // printf( "\n" ) ; - } - ::glEnd() ; // GL_POLYGON - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons, _hash ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - - - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_octree.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_octree.h deleted file mode 100644 index 89a111297f..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_octree.h +++ /dev/null @@ -1,352 +0,0 @@ -/** - * \file hash_octree.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with hashtable and hierarchical operations - */ -//_____________________________________________________________________________ - - -#pragma once - -#ifndef WIN32 -#pragma interface -#endif // WIN32 - - -#include "mlist.h" -#include "cube.h" -#include "hash.h" -#include "MarchingCubes.h" -#include "mc_draw.h" -#include "data_access.h" - - - -//_____________________________________________________________________________ -// HashOctree -/// \class HashOctree HashOctree.h -class HashOctree -//----------------------------------------------------------------------------- -{ -// forward declaration -public: - class geom_cell ; - class cell_iterator ; - class leaf_iterator ; - -// Elements -protected: - /// Octree cell data structure - typedef Hash HashField ; - - /// Hashtable of the octree nodes - HashField _hash ; - - /// Maximal level of the octree (for find_adjacent) - Level _max_level ; - - /// Maximal field of the octree - real _max_field ; - - /// Isosurface - MarchingCubes _mc ; - - /// Isosurface Draw - MC_Draw _mc_draw ; - - /// Dual run memory consumption - uint _dual_temp_memory ; - -//----------------------------------------------------------------------------- -// Constructors -public: - /// Default constructor: Constructs a octree with and empty root - HashOctree() { init() ; } - - /// Destructor: Free memory - ~HashOctree() { clear() ; } - - - /// Create the root - void init() ; - - /// Memory cleaning - void clear() { clear_octree() ; _mc.clean_all() ; } - - /// Delete the content of the octree - void clear_octree() ; - - /// Check that only the leaves have data - bool check () ; - - /// Prints statistics about the octree - void stats() ; - - - /// Return the maximal level of the octree - Level max_level() const { return _max_level ; } - - /// Return the maximal field of the octree - real max_field() const { return _max_field ; } - - /// Return the isosurface - MarchingCubes &mc() { return _mc ; } - - /// Return the isosurface draw - MC_Draw &mc_draw() { return _mc_draw ; } - - /// set the values of each leaf from the implicit function - bool set_impl( data_access *ref = NULL ) ; - - /// Refine the octree according to the data access - bool refine( data_access *ref = NULL ) ; - - /// Adapt the octree according to the data access - bool adapt( data_access *ref = NULL ) ; - - /// Draw the octree with wireframe - bool draw_wire() ; - - /// Draw the octree with dots - bool draw_centers() ; - - /// Dual function type - typedef bool hash_dual_walker( HashOctree &fo, Key *keys ) ; - - /// Walk on the dual cubes - bool dual_cubes_walk( hash_dual_walker &walker ) ; - - /// Build the isosurface using dual marching cubes - bool build_isosurface( data_access *ref = NULL ) ; - - /// Draw the isosurface on-the-fly using dual marching cubes - bool direct_draw_isosurface( data_access *ref = NULL ) ; - - /// Draw the dual octree with wireframe - bool draw_dual() ; - - /// Do nothing, just for dual generation timing - bool dual_timing() ; - -//----------------------------------------------------------------------------- -// iterators -public: - /// Create an iterator traversing the tree from the root - inline cell_iterator cells_begin() { return cell_iterator( *this ) ; } - - /// Create an iterator traversing the leaves of the tree from the root - inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; } - -//----------------------------------------------------------------------------- -// search operations -public: - /// Find cells of the octree at a given position - bool find_leaf( real x, real y, real z, geom_cell &cell ) const ; - - /// Find cells of the octree inside a given box of center x,y,z and half side r - bool find_radius( real x, real y, real z, real r, List &cells ) const ; - - /// Find adjacent cells of the octree to a given cell - bool adjacent( const geom_cell &cell, List &cells ) const ; - - /// Leaf test based on the field value - bool is_leaf( Key k ) const { return !is_inv( _hash[k].data ) ; } - -//----------------------------------------------------------------------------- -// I/O -public: - - /// Draws the intersecting cells of a plane with the octree with color - void draw_plane ( real nx, real ny, real nz, real d ) ; - - /// Draws the intersection of a plane with the octree with color - void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ; - - /// Draws the isosurface of level l inside the dual graph - void draw_iso () { _mc.draw_surf() ; } - -//_____________________________________________________________________________ -// Iterator Cell -public : - /// Auxiliary structure to traverse the octree - class geom_cell : public Cube - //--------------------------------------------------------------------------- - { - friend class HashOctree ; - - protected: - Key _key ; ///< octree cell - real _field ; ///< field associated to the cell - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor: Constructs an iterator from a cell - geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {} - - /// Destructor - ~geom_cell() {} - - /// Copy constructor - geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {} - - /// Assignment operator - geom_cell &operator = ( const geom_cell &i ) - { Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; } - - - //--------------------------------------------------------------------------- - // Public constant accessors - public : - /// key const accessor - inline Key key() const { return _key ; } - /// key accessor - inline Key &key() { return _key ; } - - /// id const accessor - inline real operator*() const { return _field ; } - - //--------------------------------------------------------------------------- - // Tests - public : - /// equality operator - inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; } - - /// inequality operator - inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; } - - /// leaf test - inline bool is_leaf() const { return !is_inv(*(*this)) ; } - - /// validation operator - inline bool operator ()() const { return key() != KEY_INV ; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// sons - inline bool sons( geom_cell *s /*[8]*/, const HashField &hash ) - { - if( is_leaf() ) return false ; - - Key k = _key << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - s[i]._key = k | i ; - s[i]._field = hash[k|i].data ; - (Cube&)s[i] = key2cube(s[i]._key) ; - } - return true ; - } - - /// get son from side i - inline bool son( int i , geom_cell &s, const HashField &hash ) - { - if( is_leaf() ) return false ; - s._key = (key() << 3) | i ; - s._field = hash[s._key].data ; - (Cube&)s = key2cube(s._key) ; - return true ; - } - }; - - const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; } - const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; } - - - -//_____________________________________________________________________________ -// Cell Iterator -public : - /// Octree cell iterator : Traverse the octree returning basic information on the cells - class cell_iterator - //--------------------------------------------------------------------------- - { - friend class HashOctree ; - - protected: - /// Octree traversal iterator - HashField::iterator _it ; - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor : Constructs an iterator from a cell - cell_iterator( HashOctree &o ) : _it( o._hash.begin() ) {} - - /// Destructor - ~cell_iterator() {} - - /// Copy constructor - cell_iterator( const cell_iterator &i ) : _it(i._it) {} - - /// Assignment operator - cell_iterator &operator = ( const cell_iterator &i ) - { _it = i._it; return *this; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const cell_iterator &i ) const { return _it == i._it ; } - - /// inequality operator - inline bool operator !=( const cell_iterator &i ) const { return _it != i._it ; } - - /// validation operator - inline bool operator ()() const { return _it() ; } - - /// next position - inline cell_iterator &operator ++() { ++_it ; return *this ; } - - //--------------------------------------------------------------------------- - // Accessors - public : - // cell accessor - inline geom_cell top() const { return geom_cell( key(), *_it ) ; } - - /// id accessor - inline real &operator*() { return *_it ; } - - /// level accessor - inline Level lv() { return key_level(_it.key()) ; } - - /// size accessor - inline real sz() { return Cube(0,0,0,lv()).sz() ; } - - /// key accessor - inline Key key() const { return _it.key() ; } - - /// points accessor - inline bool is_leaf() const { return !is_inv(*_it) ; } - - /// Draws the cell wire with opengl - void draw_wire () const { top().draw_wire () ; } - - }; - - - /// Octree leaf iterator : Traverse the octree returning basic information on the leaves - class leaf_iterator : public cell_iterator - //--------------------------------------------------------------------------- - { - public : - leaf_iterator( HashOctree &o ) : cell_iterator( o ) - { if( (*this)() && !this->is_leaf() ) ++(*this) ; } - - - /// next position - inline leaf_iterator &operator ++() - { - cell_iterator &it = *this ; - do ++it ; while ( it() && !it.is_leaf() ) ; - return *this ; - } - } ; -} ; -//_____________________________________________________________________________ - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_ptr.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_ptr.h deleted file mode 100644 index 79b0c9ff99..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/hash_ptr.h +++ /dev/null @@ -1,292 +0,0 @@ -/** - * @file hash_ptr.h - * @author Thomas Lewiner - * @version - * @date - * - * @brief - * - */ -//________________________________________________ - - -#ifndef _HASH_H_ -# error This header should not be included directly! include hash.h instead -#endif // _HASH_H_ - -#pragma once - -#define HASH_HAS_ERASE 1 - -#include // memset -#include -#include //printf -#include "mlist.h" // memset - -#include "morton.h" - -//_____________________________________________________________________________ -// Class hash -template < typename Data > class Hash -//----------------------------------------------------------------------------- -{ -public: - typedef uint cntr ; -// static const cntr HASH_BITS = 16 ; -// static const cntr NON_HASH_BITS = 64-HASH_BITS ; - static const cntr HASH_SIZE = ((cntr)1< KeyBucket ; - typedef typename KeyBucket::iterator keybucket_iterator ; - typedef typename KeyBucket::const_iterator keybucket_const_iterator ; - -protected: -// KeyBucket _hash[HASH_SIZE] ; - KeyBucket *_hash ; // allocate dynamically since stack memory is limited - -public: - // Constructor & Desctructor - Hash () { _hash = new KeyBucket[HASH_SIZE] ; } - ~Hash () { delete [] _hash ; } - - void reset() - { - cntr n = HASH_SIZE ; - KeyBucket *ptr = _hash ; - for( ; n > 0 ; --n, ++ptr ) - { - (*ptr).clear() ; - } - KD_INV.key = KEY_INV ; - } - - cntr size() const - { - cntr s = 0 ; - cntr n = HASH_SIZE ; - KeyBucket *ptr = _hash ; - for( ; n > 0 ; --n, ++ptr ) - s += ptr->size() ; - return s ; - } - - void stats() const - { - static const cntr MAX_COLLISION = 32 ; - cntr colls[MAX_COLLISION] ; - memset( colls, 0, MAX_COLLISION*sizeof(cntr) ) ; - KeyBucket *ptr = _hash ; - for( cntr n = HASH_SIZE ; n > 0 ; --n, ++ptr ) - { - cntr s = ptr->size() ; - if( s >= MAX_COLLISION ) s = MAX_COLLISION-1 ; - ++colls[s] ; - } - - printf( "Hashtable collisions: [\t") ; - for( cntr n = 0 ; n < MAX_COLLISION ; ++n ) - printf( "%d\t", colls[n] ) ; - printf( "\t]\n") ; - } - - inline cntr hash( Key k ) const ; - - bool insert( KeyData d ) - { - cntr h = hash( d.key ) ; - KeyBucket &l = _hash[h] ; - return l.insert_unique( d ) ; - } - - const KeyData operator[] ( Key k ) const - { - cntr h = hash( k ) ; - KeyData kd ; kd.key = k ; - keybucket_const_iterator it = _hash[h].cfind( kd ) ; - if( !it() ) return KD_INV ; - return *it ; - } - - KeyData &operator[] ( Key k ) - { - cntr h = hash( k ) ; - KeyData kd ; kd.key = k ; - keybucket_iterator it = _hash[h].find( kd ) ; - if( !it() ) return KD_INV ; - return *it ; - } - - KeyData erase( Key k ) - { - cntr h = hash( k ) ; - KeyData kd ; kd.key = k ; - if( _hash[h].remove( kd ) ) - return kd ; - return KD_INV ; - } - - bool contains( Key k ) const { return (*this)[k].key == k ; } - - - //------------------------------------------------ - // iterators - public : - /// iterator - class iterator - { - public : - // constructors - /// default constructors - iterator( Hash &hash_, Key id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE) - { - while( _ptr != _last && _ptr->empty() ) - ++_ptr ; - if( _ptr != _last ) - _l_it = _ptr->begin() ; - } - - /// destructor - ~iterator() {} - - /// copy constructor - iterator( const iterator &it ) : _ptr(it._ptr), _last(it._last), _l_it(it._l_it) {} - - /// assignment operator - iterator &operator = ( const iterator &it ) - { _ptr = it._ptr; _last = it._last; _l_it = it._l_it ; return *this; } - - //----------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const iterator &it ) const { return _ptr == it._ptr && _l_it == it._l_it ; } - /// inequality operator - inline bool operator !=( const iterator &it ) const { return _ptr != it._ptr || _l_it != it._l_it ; } - - /// validation operator - inline bool operator ()() const { return _ptr != _last ; } - - /// key accessor - inline const Key &key() const { return (*_l_it).key ; } - - /// value accessor - inline const Data &operator * () const { return (*_l_it).data ; } - - /// value accessor - inline Data &operator * () { return (*_l_it).data ; } - - /// accesses the next position - inline iterator &operator ++() { - if( !(++_l_it)() ) - { - while( _ptr != _last && (*(++_ptr)).empty() ) ; - if( _ptr != _last ) - _l_it = _ptr->begin() ; - } - return *this ; - } - - //----------------------------------------------------------------------------- - // Elements - private : - KeyBucket *_ptr ; ///< position pointer - const KeyBucket *_last ; ///< last position pointer - keybucket_iterator _l_it ; ///< list iterator inside a bucket - }; - - //------------------------------------------------ - // const_iterator - public : - /// const_iterator - class const_iterator - { - public : - // constructors - /// default constructors - const_iterator( Hash &hash_, Key id_ = 0 ) : _ptr(hash_._hash+id_), _last(hash_._hash+HASH_SIZE) - { - while( _ptr != _last && _ptr->empty() ) - ++_ptr ; - if( _ptr != _last ) - _l_it = _ptr->cbegin() ; - } - - /// destructor - ~const_iterator() {} - - /// copy constructor - const_iterator( const const_iterator &it ) : _ptr(it._ptr), _last(it._last), _l_it(it._l_it) {} - - /// assignment operator - const_iterator &operator = ( const const_iterator &it ) - { _ptr = it._ptr; _last = it._last; _l_it = it._l_it ; return *this; } - - //----------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const const_iterator &it ) const { return _ptr == it._ptr && _l_it == it._l_it ; ; } - /// inequality operator - inline bool operator !=( const const_iterator &it ) const { return _ptr != it._ptr || _l_it != it._l_it ; ; } - - /// validation operator - inline bool operator ()() const { return _ptr != _last ; } - - /// key accessor - inline const Key &key() const { return (*_l_it).key ; } - - /// value accessor - inline const Data &operator * () const { return (*_l_it).data ; } - - /// accesses the next position - inline const_iterator &operator ++() { - if( !(++_l_it)() ) - { - while( _ptr != _last && (*(++_ptr)).empty() ) ; - if( _ptr != _last ) - _l_it = _ptr->cbegin() ; - } - return *this ; - } - - //----------------------------------------------------------------------------- - // Elements - private : - const KeyBucket * _ptr ; ///< position pointer - const KeyBucket * const _last ; ///< last position pointer - keybucket_const_iterator _l_it ; ///< list iterator inside a bucket - }; - - public : - /// Node iterator creation - iterator begin( cntr id = 0 ) { return iterator( *this, id ) ; } - /// Node const iterator creation - const_iterator cbegin( cntr id = 0 ) { return const_iterator( *this, id ) ; } -}; -//_____________________________________________________________________________ - - -/// hash function specification: no inversion -template <> inline Hash::cntr Hash::hash( Key k ) const { return k & HASH_MASK ; } - -/// hash function specification: inversion -template <> inline Hash::cntr Hash::hash( Key k ) const { return (k>>NON_HASH_BITS) & HASH_MASK ; } diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/implfuns.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/implfuns.h deleted file mode 100644 index 76e61cc4ed..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/implfuns.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * @file implfuns.h - * @author Thomas Lewiner - * @version - * @date - * - * @brief - * - */ -//________________________________________________ - - -#pragma once - -#define NFUNS 38 - -// implicit functions -const char *fun_list[NFUNS] = -{ - "Type Formula" , - "Sphere" , - "Ellipsoid" , - "Hyperboloid" , - "Plane" , - "Cubic" , - "Cushin" , - "Cassini" , - "Tangle cube" , - "Chair" , - "Cyclide" , - "2 Spheres" , - "2 Torii" , - "Heart" , - "Smile" , - "Spheres in" , - "Spheres dif" , - "Cross cap" , - "Weird cube" , - "Klein bottle" , - "Steiner's roman" , - "Hunt's surface" , - "Cayley cubic" , - "Clebsch cubic" , - "Barth sextic" , - "Barth decic" , - "Steiner relative", - "Mitre" , - "Glob tear" , - "Piri tear" , - "Gumdrop torus" , - "Bretzel" , - "Blob" , - "Bifolia" , - "Lemniscate" , - "Planes" , - "Cylinders" , - "Torus" , -} ; - -// implicit functions -const char *fun_def [NFUNS] = -{ - /* Type Formula */ "f(x,y,z)", - /* Sphere */ "4*x^2-4*x+2.51+4*y^2-4*y+4*z^2-4*z", - /* Ellipsoid */ "8*x^2-8*x+3.51+4*y^2-4*y+4*z^2-4*z", - /* Hyperboloid */ "8*x^2-8*x-.1-4*y^2+4*y-4*z^2+4*z", - /* Plane */ "x+y+z", - /* Cubic */ "16*y^2-16*y+10-64*x^3+96*x^2-44*x", - /* Cushin */ "112.5*z+81*y*z^2+51.75*x+119.25*y-135*y*z-38.8125+162*x^3-81*x^4+162*y^3+216*z^3-81*y^4-81*z^4-162*x*y-132.75*x^2-200.25*y^2-220.5*z^2+162*x*y^2+81*x*z-81*x*z^2-81*x^2*z-162*x^2*y^2-81*y^2*z^2+162*x^2*y+135*y^2*z+81*z^2*x^2", - /* Cassini */ "-167.6778*z-267.2672*y*z^2-167.6778*x-205.1322*y+267.2672*y*z+59.74405625-267.2672*x^3+133.6336*x^4-267.2672*y^3-267.2672*z^3+133.6336*y^4+133.6336*z^4+267.2672*x*y+301.3114*x^2+338.7658*y^2+301.3114*z^2-267.2672*x*y^2+267.2672*x*z-267.2672*x*z^2-267.2672*x^2*z+267.2672*x^2*y^2+267.2672*y^2*z^2-267.2672*x^2*y-267.2672*y^2*z+267.2672*z^2*x^2", - /* Tangle cube */ "-468*z-468*x-468*y+1296*y^4+1764*x^2+1764*y^2+1764*z^2+1296*z^4-2592*x^3+119.8-2592*y^3+1296*x^4-2592*z^3", - /* Chair */ "-18250*z-36000*y*z^2-2250*x-18250*y+52000*y*z+4626.5625-20000*x^3+10000*x^4-20000*y^3-4000*z^3+10000*y^4+2000*z^4-12000*x*y+12250*x^2+28250*y^2+20250*z^2+12000*x*y^2+20000*x*z-36000*x*z^2-20000*x^2*z-12000*x^2*y^2+36000*y^2*z^2+12000*x^2*y-52000*y^2*z+36000*z^2*x^2", - /* Cyclide */ "-11.23227514*x^2-6.0015984*x^4-6.0015984*y^4-6.0015984*z^4-13.56959251*z^2+12.0031968*y*z^2+12.0031968*z^3+6.027648307*x+7.256824512*y-13.25842291*y^2+12.0031968*y^3+12.0031968*x^2*z-9.79449408*x*y+9.79449408*x*y^2-9.79449408*x*z+9.79449408*x*z^2-12.0031968*x^2*y^2-12.0031968*y^2*z^2-12.0031968*z^2*x^2+7.567994112*z+12.0031968*y^2*z+12.0031968*x^2*y-12.0031968*y*z-2.289346823+9.79449408*x^3", - /* 2 Spheres */ "(40000*x^2-52400*x+48853+40000*y^2-52400*y+40000*z^2-52400*z)*(4000*x^2-2800*x+1207+4000*y^2-2800*y+4000*z^2-2800*z)", - /* 2 Torii */ "-6.929911075*x -6.559601218*z -40.61779736*z^3 +56.91300912*z^4 -17.17986918*y^7 +4.294967296*y^8 -55.95084095*z^5 +38.69346103*z^6 +38.69346103*x^6 +4.294967296*z^8 -17.17986918*x^7 +37.0828483*y^6 +4.294967296*x^8 -17.17986918*z^7 +20.40667127*z^2 -51.53960755*y^3*z^4 -89.2368375*x^4*y -41.69153918*x^3 +51.53960755*x*z^5 -51.11900275*y^5 -51.53960755*x^2*z^5 -51.53960755*y^5*z^2 +92.57432908*x^3*y +87.74249087*y^3*z -5.938337301*y +17.84876088*y^2 -35.13389168*y^3 +1.174097113 -51.53960755*y^2*z^5 +51.53960755*x^5*y -62.4313134*x*y^2 +50.14452444*y^4 +51.53960755*y^5*z -67.27041824*x^2*z -62.06100354*y*z^2 +114.4697704*y^2*z^4 +17.17986918*y^2*z^6 +88.81623269*y^3*x +112.8591576*y^4*z^2 +114.4697704*x^4*y^2 -87.08935385*y^4*z +25.76980378*y^4*z^4 +103.0792151*x^3*z^3 +103.0792151*y^3*z^3 -87.08935385*y^4*x +112.8591576*y^4*x^2 +90.42684543*y*z^3 +51.53960755*y*z^5 +116.0803831*x^2*z^4 +17.17986918*x^2*z^6 -146.2614203*x^3*z^2 +94.72181273*x^3*z +25.76980378*x^4*z^4 -51.53960755*x^4*z^3 -88.16309567*y*z^4 +25.43751542*y*z -90.31057932*x*z^4 -90.31057932*x^4*z +116.0803831*x^4*z^2 -139.2820984*y^3*z^2 -17.17986918*y^6*z -140.3558402*y^3*x^2 +17.17986918*x^6*z^2 +94.72181273*x*z^3 +17.17986918*y^6*z^2 -143.0401948*x^3*y^2 -17.17986918*x^6*z -17.17986918*x*z^6 -51.53960755*x^3*z^4 +51.53960755*x^5*z -51.53960755*x^5*z^2 +103.0792151*x^3*y^3 +17.17986918*x^6*y^2 -17.17986918*x^6*y +51.53960755*y^5*x -17.17986918*y*z^6 -51.53960755*y^5*x^2 -17.17986918*y^6*x +17.17986918*y^6*x^2 +25.76980378*x^4*y^4 -143.0401948*y^2*z^3 -146.2614203*x^2*z^3 +26.71500605*x*y +28.49944647*x*z -67.27041824*x*z^2 +125.3614762*x^2*y^2 +123.7508635*y^2*z^2 -60.82070066*y^2*z +131.8111938*z^2*x^2 +21.31385204*x^2 +51.53960755*y^4*z*x +103.0792151*y^2*z^3*x +51.53960755*y^2*z^2*x^4 -51.53960755*y^4*z^2*x +103.0792151*y^3*z^2*x -103.0792151*y^2*z^2*x^3 -51.53960755*x^4*y^2*z +103.0792151*x^2*z^3*y -51.53960755*x^2*z^4*y +103.0792151*x^3*y^2*z -51.53960755*y^2*z^4*x +51.53960755*y^4*z^2*x^2 -103.0792151*y^3*z^2*x^2 +51.53960755*y^2*z^4*x^2 -103.0792151*y^2*z^3*x^2 +51.53960755*x*z^4*y +51.53960755*x^4*y*z -51.53960755*y^4*z*x^2 -103.0792151*x^3*y*z -51.53960755*x^4*y*z^2 +103.0792151*x^3*y*z^2 -103.0792151*x*z^3*y -103.0792151*y^3*z*x +103.0792151*y^3*z*x^2 +125.8603256*y*z^2*x -177.3999332*x^2*y*z^2 -177.3999332*x^2*z*y^2 +125.8603256*y^2*z*x -177.3999332*x*y^2*z^2 +228.9395407*y^2*z^2*x^2 -74.32071807*y*z*x +125.8603256*y*z*x^2 -64.41223599*x^2*y -51.53960755*x^5*y^2 +57.44988003*x^4 -55.95084095*x^5 -51.53960755*x^4*y^3 -51.53960755*x^3*y^4 -51.53960755*y^4*z^3", - /* Heart */ "-697.347066*z-2684.277024*y*z^2-1347.168628*x-687.693448*y+926.747328*y^2*z^4+3706.989312*y^3*x+926.747328*y^4*z^2+3706.989312*x^4*y^2-926.747328*y^4*z-1853.494656*y^4*x+1853.494656*y^4*x^2+1972.308416*y*z^3+1853.494656*x^2*z^4-7413.978624*x^3*z^2+7413.978624*x^3*z-926.747328*y*z^4+1668.419376*y*z-1853.494656*x*z^4+7413.978624*x^3*y-3706.989312*x^4*z+3706.989312*x^4*z^2+1853.494656*y^3*z-1853.494656*y^3*z^2-3706.989312*y^3*x^2+3718.870688*x*z^3-7413.978624*x^3*y^2-3706.989312*x^4*y-1972.308416*y^2*z^3-3718.870688*x^2*z^3+195.187199+3706.989312*y*z^2*x-3706.989312*x^2*y*z^2-3706.989312*x^2*z*y^2+3706.989312*y^2*z*x-3706.989312*x*y^2*z^2+3706.989312*y^2*z^2*x^2-8788.562432*x^3+10572.59674*x^4-1888.224832*y^3-1920.898616*z^3+1716.401856*y^4+1716.401856*z^4-926.747328*z^5+308.915776*z^6-7413.978624*x^5+2471.326208*x^6-926.747328*y^5+308.915776*y^6+3158.618112*x*y+4505.78674*x^2+1477.347976*y^2+1511.506932*z^2-3706.989312*y*z*x-5012.112768*x*y^2+3706.989312*y*z*x^2+3167.529144*x*z-5029.934832*x*z^2-6874.518456*x^2*z+8719.10208*x^2*y^2+3611.024352*y^2*z^2-6865.607424*x^2*y-2595.166704*y^2*z+8736.924144*z^2*x^2", - /* Smile */ "-12348*z-435632*y^3-27216*y*z^2-17834.8125*x-35974.25*y-327680*y^7+733184*y^6-891648*y^4*x+11664*y*z^3+972*x^3*z+21168*y*z+2304*y^3*z+8748*x*z^3+46656*x^6*y^2-58320*x^6*y+5162.816406-1100160*y^3*x^2+11664*y*z^2*x+5184*y^2*z*x-72987.75*x^3+95610.375*x^4-20412*z^3+6561*z^4+65536*y^8-89667*x^5+60507*x^6-26244*x^7+6561*x^8+41910.1875*x^2+23814*z^2+712044*x^2*y^2-257499*x^2*y-18144*y*z*x+3888*y*z*x^2-311040*x^4*y^3+174960*x^5*y-139968*x^5*y^2+622080*x^3*y^3+552960*y^5*x-552960*y^5*x^2-147456*y^6*x+1016064*y^4*x^2+789888*y^3*x+340632*x^3*y-957440*y^5-315900*x^4*y-408060*x*y^2-248832*x^3*y^4+147456*y^6*x^2+124416*x^4*y^4-660960*x^3*y^2+155243*y^2+797792*y^4+447120*x^4*y^2+120591*x*y+15876*x*z-20412*x*z^2-6804*x^2*z+7776*y^2*z^2-12096*y^2*z+4374*z^2*x^2", - /* Spheres in */ "-(8*(4*x^2-4*x+3+4*y^2-4*y+4*z^2-4*z))*(-1+sqrt(4*x^2-4*x+3+4*y^2-4*y+4*z^2-4*z))", - /* Spheres dif */ "-496*z-4416*y*z^2-560*x-560*y+6912*y^2*z^4+1024*y^2*z^6+9728*y^3*x+7296*y^4*z^2+13056*x^4*y^2-7680*y^4*z-6144*x^4*y^3+1536*y^4*z^4+6144*x^3*z^3+6144*y^3*z^3-9984*y^4*x+13056*y^4*x^2+5760*y*z^3+3072*y*z^5-3072*x^2*z^5+6912*x^2*z^4+1024*x^2*z^6-9472*x^3*z^2+6144*x^5*y-6144*x^5*y^2+7680*x^3*z+1536*x^4*z^4-3072*x^4*z^3-5376*y*z^4-3072*y^3*z^4+4608*y^4*z*x+6144*y^2*z^3*x+3072*y^2*z^2*x^4-3072*y^4*z^2*x+6144*y^3*z^2*x-6144*y^2*z^2*x^3-4608*x^4*y^2*z+6144*x^2*z^3*y-3072*x^2*z^4*y+9216*x^3*y^2*z-3072*y^2*z^4*x+3072*y^4*z^2*x^2-6144*y^3*z^2*x^2+3072*y^2*z^4*x^2-6144*y^2*z^3*x^2+3072*x*z^4*y+4608*x^4*y*z-4608*y^4*z*x^2-9216*x^3*y*z-3072*x^4*y*z^2+6144*x^3*y*z^2-6144*x*z^3*y-9216*y^3*z*x+9216*y^3*z*x^2+2112*y*z-5376*x*z^4+9728*x^3*y-7680*x^4*z+7296*x^4*z^2+7680*y^3*z-9472*y^3*z^2-1536*y^6*z-15872*y^3*x^2+1024*x^6*z^2+5760*x*z^3+1024*y^6*z^2-3072*y^4*z^3-15872*x^3*y^2-1536*x^6*z+3072*x*z^5-1024*x*z^6-3072*x^3*z^4+4608*x^5*z-3072*x^5*z^2+12288*x^3*y^3+2048*x^6*y^2-2048*x^6*y+6144*y^5*x-1024*y*z^6-6144*y^5*x^2+4608*y^5*z-3072*y^5*z^2-9984*x^4*y-2048*y^6*x-6144*x^3*y^4+2048*y^6*x^2+3072*x^4*y^4-8832*y^2*z^3-8832*x^2*z^3-3072*y^2*z^5+96+8448*y*z^2*x-11520*x^2*y*z^2-15360*x^2*z*y^2+10752*y^2*z*x-11520*x*y^2*z^2+14592*y^2*z^2*x^2-3776*x^3+5600*x^4-3776*y^3-2560*z^3+5600*y^4+3440*z^4-2048*y^7+512*y^8-3328*z^5+2304*z^6-5888*x^5+4352*x^6-5888*y^5+256*z^8-2048*x^7+4352*y^6+512*x^8-1024*z^7+2496*x*y+1808*x^2+1808*y^2+1392*z^2-6144*y*z*x-6336*x*y^2+10752*y*z*x^2+2112*x*z-4416*x*z^2-5184*x^2*z+13248*x^2*y^2+8640*y^2*z^2-6336*x^2*y-5184*y^2*z+8640*z^2*x^2", - /* Cross cap */ ".4*sqrt(100*x-10)*x^2-0.08*sqrt(100*x-10)*x+0.008*sqrt(100*x-10)+.4*sqrt(100*x-10)*y^2-0.08*sqrt(100*x-10)*y+1.6*sqrt(100*x-10)*z^2-.8*sqrt(100*x-10)*z+.1*sqrt(100*y-10)*y^2-0.02*sqrt(100*y-10)*y+0.001*sqrt(100*y-10)+.4*sqrt(100*y-10)*z^2-.4*sqrt(100*y-10)*z", - /* Weird cube */ "59136*z-10240*y^3-10240*x^3+59136*x+59136*y+204800*z^2*x^2+204800*y^2*z^2-23232+204800*x^2*y^2-102400*x^2*y-102400*x^2*z-297216*x*z+128000*z^2-512000*y*z*x^2+128000*x^2+1566720*y*z*x-102400*x*z^2-512000*y*z^2*x-512000*y^2*z*x-102400*z^3-297216*y*z+102400*y^3*x-102400*y*z^2+102400*x^3*z+102400*x^3*y-102400*x*y^2+128000*y^2+102400*y*z^3-297216*x*y+102400*y^3*z-102400*y^2*z+102400*x*z^3", - /* Klein bottle */ "-244615.68*y^3-304335.36*x^3-96138.60864*y-786432*z^5-453427.2*y^3*z^2+1139015.68*z^4-139968*y^4*x-255052.8*y^3*x^2+248832*x^4*z^2-248832*x^4*z+33252.70426+46656*x^6+46656*y^6+1051729.92*y^2*z^2+493102.08*x^2*y^2+442368*x^2*z^4-497664*x^3*z^2-403046.4*y*z^4-442368*x*z^4-344176.128*x^2*y-705392.64*x^2*z+497664*y^2*z^2*x^2+480030.72*x*z-484761.6*y*z*x+555332.4032*z^2+453427.2*y*z*x^2+243162.3168*x^2-931184.64*x*z^2+453427.2*y*z^2*x+525312*y^2*z*x-991887.36*z^3+392220.672*y*z+255052.8*y^3*x-779599.872*y*z^2+525312*x^3*z+255052.8*x^3*y-127526.4*y^5-127526.4*x^4*y-366958.08*x*y^2-497664*x*y^2*z^2+262144*z^6-497664*x^2*z*y^2-453427.2*x^2*y*z^2+1106288.64*z^2*x^2-139968*x^5-279936*x^3*y^2-884736*x^2*z^3-120681.6768*x+196337.664*y^2-191443.7632*z+231206.4*y^4+261895.68*x^4-884736*y^2*z^3+806092.8*y*z^3+442368*y^2*z^4+248832*y^4*z^2+139968*x^4*y^2-248832*y^4*z+139968*y^4*x^2+232316.928*x*y+453427.2*y^3*z-623185.92*y^2*z+933888*x*z^3", - /* Steiner's roman */ "0.03125*y^2+.125*y*z*x-0.00390625-0.0625*y^2*z-0.0625*y*z^2+0.03125*z^2-0.0625*x^2*z+0.03125*x^2+0.0625*x^2*y^2+0.0625*z^2*x^2+0.0625*y^2*z^2-0.0625*x^2*y-0.0625*x*y^2-0.0625*x*z^2", - /* Hunt's surface */ "-321408*y-559872*z^5+1446336*z^4+933120*z^2*x^2-1990656*y^2*z^3+559872*x^4*z^2+1990656*y*z^2*x-559872*x^4*z-1990656*x^3*y^2-3538944*y^3*x^2+1119744*x*z^3-3538944*y^3*z^2-1959552*z^3-1469664*x^3+37719-1119744*x^3*z^2+1119744*x^3*z-1658880*y*z^2-1769472*y^4*z+1990656*y*z^3+1990656*x^3*y+3538944*y^3*z+3428352*y^2*z^2+1534464*x*y+186624*x^6+559872*x^2*z^4-995328*y*z^4-559872*x*z^4-373248*x^2*z-186624*x*z-3334144*y^3+4288512*y^4+1201392*x^4+1990656*y^2*z*x-1990656*x*y^2*z^2+3538944*y^3*x+1769472*y^4*z^2+1769472*y^4*x^2-1769472*y^4*x+1990656*y*z*x^2+802872*x^2-1990656*y*z*x-3303936*x*y^2-2433024*y^2*z-373248*x*z^2+663552*y*z-995328*x^4*y+4299264*x^2*y^2+1990656*y^2*z^2*x^2+186624*z^6-559872*x^5-3145728*y^5+1048576*y^6-2529792*x^2*y-161352*x-229392*z-1990656*x^2*y*z^2-1990656*x^2*z*y^2+1115856*z^2+995328*y^2*z^4+995328*x^4*y^2-1119744*x^2*z^3+1464192*y^2", - /* Cayley cubic */ "264-512*z-512*x-512*y+320*y^2-320*x^2*y-320*x^2*z-320*x*y^2+672*x*y-320*x*z^2+672*x*z-320*y^2*z-320*y*z^2+672*y*z+320*z^2+320*x^2", - /* Clebsch cubic */ "8154-15300*z-15300*x-15300*y+4176*y^2+4176*z^2+24480*x*y+24480*y*z+5184*x^3-12096*x*y^2-12096*y^2*z-12096*x*z^2-12096*y*z^2+24480*x*z-12096*x^2*y-12096*x^2*z+4176*x^2+3456*y*z*x+5184*z^3+5184*y^3", - /* Barth sextic */ "-2846.637681*z-75426.87093*y*z^2-2846.637681*x-2846.637681*y+224595.2132*y^3*z^2+42893.86887*y^2*z^4+85787.73774*y^3*x-42893.86887*y^4*x+42893.86887*y^4*x^2+85787.73774*y*z^3-85787.73774*x^3*z^2+85787.73774*x^3*z-42893.86887*y*z^4+32533.00206*y*z-42893.86887*x^4*z+42893.86887*x^4*z^2-85787.73774*y^3*x^2-85787.73774*y^2*z^3+571.8691769+36870.73567*x^3-18435.36784*x^4+36870.73567*y^3+36870.73567*z^3-18435.36784*y^4-18435.36784*z^4+32533.00206*x*y-15588.73016*x^2-15588.73016*y^2-15588.73016*z^2-112297.6066*x^2*z^4+112297.6066*x*z^4+277614.9509*y^2*z^2*x^2-75426.87093*x*y^2-277614.9509*y*z*x+277614.9509*y*z*x^2+277614.9509*y*z^2*x+277614.9509*y^2*z*x-224595.2132*x^3*y+112297.6066*x^4*y-277614.9509*x*y^2*z^2-277614.9509*x^2*z*y^2-277614.9509*x^2*y*z^2+224595.2132*x^3*y^2+224595.2132*x^2*z^3-112297.6066*y^4*z^2-112297.6066*x^4*y^2+112297.6066*y^4*z+32533.00206*x*z+79764.60454*x*z^2-75426.87093*x^2*z-36870.73567*x^2*y^2-36870.73567*y^2*z^2-224595.2132*y^3*z-224595.2132*x*z^3+79764.60454*x^2*y+79764.60454*y^2*z-36870.73567*z^2*x^2", - /* Barth decic */ "25.33143961*y^2*z^2*x^4 +25.15700632*y^4*z^2*x -34.82908387*y^2*z^4 +8.917960033*y^4*z^2 +0.04360832264*y^4*z^4 +16.49570037*y^4*z +8.917960033*x^4*y^2 -42.37063678*x^4*y^3 -34.82908387*y^4*x^2 +2.299854983*y^7*z^2 +25.37005208*x^4*y^5 +33.65896395*x^6*y^2*z -100.9768918*x^3*y^2*z^4 +1.198101193*x^3 +246.5161156*y^2*z^2*x^2 +25.36672152*x^3*y^4 +6.515326172*y^6*x^2 +44.38789864*y^2*z*x +6.273208191*y^5*z^2 +0.05111641659 +201.9537837*x^2*z^3*y^3 -8.109285345*x^3*z^2 +117.9808071*y^2*z^3*x +0.8487421525*x^8 -8.109285345*y^3*x^2 +6.515326172*x^6*z^2 +33.83339724*x^3*y^3 +50.48844592*x^4*y^2*z^4 -33.65896395*y^6*z*x +100.9768918*x^5*y*z +6.273208191*x^2*z^5 +100.9768918*x^4*y^3*z -201.9537837*x^3*y*z^3 -4.774233544*x^2*z^6 -21.54557109*x^5*y -3.716625642*x^3*z +6.273208191*x^5*y^2 +0.04360832264*x^4*z^4 -100.9768918*x^2*z^3*y^4 +33.65896395*y^2*z^6*x +16.49570037*x*z^4 +16.49570037*x^4*y -120.2077842*x^2*y*z^2 +9.865021177*x*z^6 -42.37063678*x^3*z^4 -3.39496861*x^7 -15.2723629*x^4*z^5 -2.299854983*x*z^7 +25.15700632*x^2*z^4*y +117.9808071*x^3*y^2*z +25.15700632*y^2*z^4*x +50.48844592*x^2*z^4*y^4 -25.60810291*x^3*y^2 -14.9720102*x^6*z -100.9768918*x^5*y^2*z -100.9768918*x^2*z^4*y^3 +6.515326172*y^2*z^6 -3.716625642*y^3*x -5.046246117*y*z^2 -100.9768918*x^4*y^3*z^2 -50.48844592*y^4*z^4*x +100.9768918*x^3*y^4*z +2.299854983*x^7*y^2 -3.940860141*y^8*x +5.090787632*y^6*z^4 -15.2723629*x^5*y^4 +0.8487421525*y^8 +2.299854983*x^2*z^7 -0.5749637458*x^2*z^8 -75.64545224*y^4*z*x -100.9768918*y^5*z*x^2 -50.48844592*x^4*y*z^4 +25.33143961*y^4*z^2*x^2 +1.198101193*z^3 +100.9768918*y^5*z*x +0.9611245006*y^5 -120.2077842*x^2*z*y^2 +3.940860141*y^2*z^8 -10.18157526*x^6*y^3 -8.456684027*x^4*y^6 +201.9537837*x^3*y^2*z^3 -100.9768918*x^2*z^5*y +19.60032929*y*z^4 -15.76344056*x^7*z^2 -3.940860141*x^8*z +0.2347202588*x^3*y +19.60032929*x^4*z +9.865021177*y^6*z -19.05645904*y*z*x -10.25601137*x^5*z +9.865021177*x^6*y +0.4659238756*x^2 -0.3389589536*x -0.3389589536*y +1.198101193*y^3 -3.380386036*y^4 -3.380386036*x^4 -8.109285345*y^2*z^3 -25.60810291*x^2*z^3 -4.774233544*x^6*y^2 +117.9808071*y^3*z^2*x -218.9576989*y^2*z^2*x^3 +25.15700632*x^4*y^2*z +117.9808071*x^2*z^3*y +100.9768918*x^2*z^5*y^2 +33.65896395*y^6*z*x^2 -33.65896395*x^6*y*z +100.9768918*y^4*z^3*x -50.48844592*x^4*y^4*z -50.74010416*x^3*y^5 -3.39496861*y^7 -5.892963096*x*z^2 -5.046246117*x^2*z -100.9768918*y^5*z^2*x -100.9768918*y^2*z^5*x -21.54557109*y^5*z +0.9611245006*z^5 +18.5125231*z^2*x^2 +25.15700632*x^4*y*z^2 -17.00391526*x^3*y*z -33.65896395*x*z^6*y +100.9768918*y^3*z^4*x +5.090787632*x^4*z^6 -34.82908387*x^4*z^2 +2.567983615*x*z +100.9768918*x^3*y*z^4 +3.940860141*x^8*z^2 -8.456684027*x^6*z^4 +16.91336805*y^3*z^6 +30.54472579*y^5*z^3 -15.76344056*y^7*x^2 +15.76344056*y^7*x +30.54472579*x^3*z^5 +25.37005208*x^5*z^4 +25.37005208*y^4*z^5 -10.18157526*y^6*z^3 +33.65896395*x^2*z^6*y -100.9768918*x^4*y^2*z^3 -15.2723629*y^5*z^4 -50.74010416*y^3*z^5 -100.9768918*x^3*y^4*z^2 +50.48844592*x^4*y^4*z^2 -201.9537837*x^3*y^3*z +0.5749637458*y^8*z -0.5749637458*y^8*z^2 +35.62606345*y^5*x^2 -100.9768918*x^5*y*z^2 +3.640421878*z^6 +0.9611245006*x^5 -21.54557109*x*z^5 +0.4659238756*y^2 -33.65896395*x^6*y^2*z^2 -33.65896395*y^6*z^2*x^2 +0.5749637458*x^8*y -0.5749637458*x^8*y^2 +0.2347202588*x*z^3 +3.640421878*x^6 +25.36672152*x^4*z^3 +25.36672152*y^3*z^4 +0.4659238756*z^2 -0.3389589536*z -120.2077842*x*y^2*z^2 +100.9768918*x*z^5*y +30.54472579*x^5*y^3 +16.91336805*x^6*z^3 -33.65896395*x^2*z^6*y^2 +33.65896395*x^6*y*z^2 +201.9537837*x^3*y^3*z^2 +2.567983615*x*y +18.5125231*x^2*y^2 -15.76344056*y^2*z^7 +5.090787632*x^6*y^4 -3.940860141*y*z^8 +100.9768918*y^5*z^2*x^2 +0.04360832264*x^4*y^4 +35.62606345*x^5*z^2 +117.9808071*x^3*y*z^2 -17.00391526*x*z^3*y +35.62606345*y^2*z^5 -4.774233544*y^6*z^2 -42.37063678*y^4*z^3 +0.5749637458*x*z^8 +3.940860141*y^8*x^2 -2.299854983*x^7*y -3.380386036*z^4 +0.2347202588*y^3*z -25.60810291*y^3*z^2 +16.91336805*x^3*y^6 +3.640421878*y^6 +33.83339724*x^3*z^3 +33.83339724*y^3*z^3 +19.60032929*y^4*x +8.917960033*x^2*z^4 -10.25601137*y*z^5 -3.716625642*y*z^3 -5.892963096*y^2*z -5.892963096*x^2*y +33.65896395*y^6*z^2*x +100.9768918*x^5*y^2*z^2 +44.38789864*y*z*x^2 +44.38789864*y*z^2*x -3.39496861*z^7 -10.18157526*x^3*z^6 +100.9768918*x^4*y*z^3 -5.046246117*x*y^2 -10.25601137*y^5*x -14.9720102*y*z^6 +15.76344056*y*z^7 +0.8487421525*z^8 -75.64545224*x*z^4*y -75.64545224*x^4*y*z +25.15700632*y^4*z*x^2 +18.5125231*y^2*z^2 -14.9720102*y^6*x -8.456684027*y^4*z^6 +2.567983615*y*z +15.76344056*x^7*z -218.9576989*y^3*z^2*x^2 +25.33143961*y^2*z^4*x^2 -218.9576989*y^2*z^3*x^2 -17.00391526*y^3*z*x +117.9808071*y^3*z*x^2 -201.9537837*y^3*z^3*x -50.74010416*x^5*z^3 -2.299854983*y^7*z", - /* Steiner relative */ "2-8*y*z*x-2*z-2*x-10*y+8*y^2-16*x*y^2-16*x^2*y+16*x^2*y^2+20*x*y-16*z^2*x^2+16*x^2*z+16*x*z^2+20*y*z-16*y*z^2-16*y^2*z+16*y^2*z^2-12*x*z", - /* Mitre */ "4-8*z-16*x-12*y+28*y^2-16*x*y^2-16*x^2*y+16*x^2*y^2+16*x*y+16*z^2*x^2-16*x^2*z-16*x*z^2+16*y*z-16*y*z^2-16*y^2*z+16*y^2*z^2+16*x*z+8*z^2+16*y^4+16*x^4-32*x^3+32*x^2-32*y^3", - /* Glob tear */ "16*x^5-32*x^4+24*x^3-8*x^2+x-2-4*y^2+4*y-4*z^2+4*z", - /* Piri tear */ "x^4-1*x^3+y^2-1*y+.5+z^2-1*z", - /* Gumdrop torus */ "-1792*z-2048*y*z^2-2368*x-1792*y+2048*y*z-2048*x^3+1024*x^4-2048*y^3-2048*z^3+1024*y^4+1024*z^4+4352*x*y+3392*x^2+2816*y^2+2816*z^2+641-4352*x*y^2+4352*x*z-4352*x*z^2-4352*x^2*z+4352*x^2*y^2+2048*y^2*z^2-4352*x^2*y-2048*y^2*z+4352*z^2*x^2", - /* Bretzel */ "-1*z-4.5*x-2.53125*y+7.59375*y^2-18*x*y^2+18*x*y+72*x^4*y^2-72*x^4*y-144*x^3*y^2+144*x^3*y+z^2+5.0625*y^4+674*x^4+.55640625-196*x^3+38.5*x^2-1408*x^5+256*x^8-1024*x^7+1664*x^6+90*x^2*y^2-90*x^2*y-10.125*y^3", - /* Blob */ "9*x^2-8.1*x+4.895+9*y^2-8.1*y+9*z^2-9*z+sin(12*x-5.4)+sin(12*y-5.4)+sin(12*z-6)", - /* Bifolia */ "4-16*z-16*x+4*y^2+8*x^2*y^2+32*z^2*x^2-32*x^2*z-8*x*y^2-32*x*z^2+32*x*z+8*y^2*z^2-8*y^2*z+32*z^2+y^4+16*z^4+16*x^4-32*x^3+32*x^2-32*z^3-12*x^2*y+12*x*y-6*y-12*y*z^2+12*y*z", - /* Lemniscate */ "16*x^4-32*x^3+20*x^2-4*x+2+4*y^2-4*y+4*z^2-4*z", - /* Planes */ "x*y", - /* Cylinders */ "((4*x-2)^2+(4*y-2)^2)^4+((4*x-2)^2+(4*z-2)^2)^4-((4*x-2)^2+(4*y-2)^2)^4*((4*x-2)^2+(4*z-2)^2)^4", - /* Torus */ "(1.4-sqrt((6*x-3)^2+(6*y-3)^2))^2+(6*z-3)^2-1.44" -} ; diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/leaf_octree.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/leaf_octree.cpp deleted file mode 100644 index 179975cf47..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/leaf_octree.cpp +++ /dev/null @@ -1,1120 +0,0 @@ -/** - * \file leaf_octree.cpp - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure without intermediate nodes, hashtable and optimized operations - */ -//_____________________________________________________________________________ - - -#ifndef WIN32 -#pragma implementation -#endif // WIN32 - - -#include -#include "leaf_octree.h" - -#ifdef HASH_HAS_ERASE - -//_____________________________________________________________________________ -// Create the root -void LeafOctree::init() -//----------------------------------------------------------------------------- -{ - _max_field = R_INV ; - _opt_level = L_INV ; - memset( _level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - - HashField::KeyData kd ; - kd.data = 0.0 ; - kd.key = 1 ; - _hash.insert( kd ) ; - - _level_dist[0] = 1 ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -/// Compute the optimal level -void LeafOctree::compute_opt_level() -//----------------------------------------------------------------------------- -{ - Level left = 0 ; - Level right = MAX_LEVEL ; - uint leftsum = 0 ; - uint rightsum = 0 ; - while( left < right ) - { - uint leftsum_old = leftsum ; - if( leftsum <= rightsum ) - { - leftsum += _level_dist[ left ] ; - ++left ; - } - if( leftsum_old >= rightsum ) - { - rightsum += _level_dist[ right ] ; - --right ; - } - } - _opt_level = right ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Check that each point scan or scribble is in the right node -bool LeafOctree::check () -//----------------------------------------------------------------------------- -{ - bool result = true ; - - uint level_dist[MAX_LEVEL+1] ; - memset( level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - { - Key k = it.key() ; - level_dist[ key_level(k) ] ++ ; - - Key ks = k << 3 ; - HashField::KeyData kd ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( node_exists( ks|i, kd ) ) - printf("(leaf) Invalid leaf %d: has son %d\n", (int)k, (int)ks|i ) ; - } - - if( node_exists( k>>3, kd ) ) - printf("(leaf) Invalid leaf %d: has father %d\n", (int)k, (int)k>>3 ) ; - } - - for( Level lv = 0 ; lv <= MAX_LEVEL ; ++lv ) - { - if( _level_dist[lv] != level_dist[lv] ) - { - printf("(leaf) Invalid level statistic %d: %d != %d\n", (int)lv, (int)_level_dist[lv], (int)level_dist[lv] ) ; - result = false ; - } - } - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Deletes the content of the octree -void LeafOctree::clear_octree() -//----------------------------------------------------------------------------- -{ - _hash.reset() ; - _verts.reset() ; - _max_field = R_INV ; - _opt_level = L_INV ; - memset( _level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// set the values of each leaf from the implicit function -bool LeafOctree::set_impl( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - _max_field = -FLT_MAX ; - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - { - real v = (*ref).value_at( it.top() ) ; - *it = v ; - v = fabs(v) ; - if( _max_field < v ) _max_field = v ; - } - -// printf( "max field: %f\n", max_field() ) ; - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool LeafOctree::refine( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - clear() ; init() ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it = geom_root() ; // the only cell - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - _hash.erase( it.key() ) ; - - HashField::KeyData kd ; - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - s.push( geom_cell( kd.key, kd.data ) ) ; - } - - Level lv = it.lv() ; - _level_dist[ lv ] -= 1 ; - _level_dist[lv+1] += 8 ; - } - - compute_opt_level() ; - return refined ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool LeafOctree::adapt( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - - // need to go for a stack structure - // this is horribly heavy, but the adaptation destroys the leaf iterator! - std::stack< geom_cell > s ; - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - s.push( it.top() ) ; - - - bool refined = false ; - while( !s.empty() ) - { - geom_cell it = s.top() ; - s.pop() ; - - HashField::KeyData kd ; - if( !node_exists( it.key(), kd ) ) continue ; - - // try to refine - std::stack< geom_cell > ref_s ; - ref_s.push( it ) ; - - bool it_refined = false ; - while( !ref_s.empty() ) - { - geom_cell r_it = ref_s.top() ; ref_s.pop() ; - - // test for subdivision - if( !(*ref).need_refine( r_it ) ) continue ; - refined = it_refined = true ; - - // subdivides the cell in the tree - _hash.erase( r_it.key() ) ; - - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = r_it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - ref_s.push( geom_cell( kd.key, kd.data ) ) ; - } - - Level lv = r_it.lv() ; - _level_dist[ lv ] -= 1 ; - _level_dist[lv+1] += 8 ; - } - if( it_refined ) continue ; - - - // no need refine the current leaf: check parent - geom_cell father( it.key() >> 3, 0.0 ) ; - if( (*ref).need_refine( father ) ) continue ; // need to refine father = no need to simplify: OK! - - // need to simplify? check on brothers and nephews - std::stack< Key > nephews_s; - Key fk = father.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( (fk | i) == it.key() ) continue ; - nephews_s.push( fk|i ) ; - } - std::stack< std::pair > nephews_keys ; - bool keep_refined = false ; - while( !nephews_s.empty() ) - { - Key n_it = nephews_s.top() ; nephews_s.pop() ; - - if( !node_exists( n_it, kd ) ) - { - // look down for nephews - fk = n_it << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - nephews_s.push( fk|i ) ; - continue ; - } - - geom_cell g_it = geom_key( n_it ) ; - nephews_keys.push( std::make_pair(n_it,g_it.lv()) ) ; - if( (*ref).need_refine( g_it ) ) - { - keep_refined = true ; - break ; - } - } - - if( keep_refined ) continue ; - refined = true ; - - // delete cell, brothers, nephews - nephews_keys.push( std::make_pair(it.key(),it.lv()) ) ; - while( !nephews_keys.empty() ) - { - _hash.erase( nephews_keys.top().first ) ; - _level_dist[ nephews_keys.top().second ] -= 1 ; - nephews_keys.pop() ; - } - - // recurse on father - kd.key = father.key() ; - kd.data = 0.0 ; - _hash.insert( kd ) ; - _level_dist[ father.lv() ] += 1 ; - s.push( father ) ; - } - - compute_opt_level() ; - return refined ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with wireframe -bool LeafOctree::draw_wire() -//----------------------------------------------------------------------------- -{ - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - it.draw_wire() ; - - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with dots -bool LeafOctree::draw_centers() -//----------------------------------------------------------------------------- -{ - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - { - ::glTexCoord1f( (GLfloat)fabs(*it / max_field()) ) ; - it.top().draw() ; - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Compute primal vertices -bool LeafOctree::compute_primal_verts() -//----------------------------------------------------------------------------- -{ - - // add all the inner vertices - for( leaf_iterator l_it = leaves_begin() ; l_it() ; ++l_it ) - { - Key verts_k[8] ; - Level lv = vertices_keys( l_it.key(), verts_k ) ; - - HashVerts::KeyData kd ; - kd.data = lv ; - Key *v_ptr = verts_k ; - for( int i = 0 ; i < 8 ; ++i, ++v_ptr ) - { - kd.key = *v_ptr ; - if( kd.key == KEY_INV ) continue ; - - HashVerts::KeyData &hk = _verts[ kd.key ] ; - if( hk.key == KEY_INV ) - _verts.insert( kd ) ; - else if( hk.data < kd.data ) - hk.data = kd.data ; - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Octree dual caller -bool LeafOctree::dual_cubes_walk( leaf_dual_walker &walker ) -//----------------------------------------------------------------------------- -{ - bool result = compute_primal_verts() ; - - for( HashVerts::const_iterator v_it = _verts.cbegin() ; v_it() ; ++v_it ) - { - const Level lv = *v_it ; - Key dual_verts[8] ; - dual_vertices_keys( v_it.key(), lv, dual_verts ) ; - - Key *dv_ptr = dual_verts ; - for( int i = 0 ; i < 8 ; ++i, ++dv_ptr ) - { - // find_at, only the level too high case - Key &ki = *dv_ptr ; - HashField::KeyData kd ; - while( ki != 0 && !node_exists(ki,kd) ) - ki >>= 3; - } - result &= walker( *this, dual_verts ) ; - } - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Isosurface walker -bool leaf_isosurface_walker( LeafOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MarchingCubes &mc = fo.mc() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - /** indexes of the cube */ - Key *indexes = mc.indexes() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const Key k = keys[j] ; - LeafOctree::geom_cell c = fo.geom_key(k) ; - cube[i] = *c ; - - space[i] = (Point)c ; - indexes[i] = k ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool LeafOctree::build_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc.dat_access() = ref ; - _verts.reset() ; - - - printf( "Build isosurface... " ) ; - bool result = false ; - - //_________________________________________________________________________ - // Dual Marching Cubes - - _mc.init_all() ; - - result = dual_cubes_walk( leaf_isosurface_walker ) ; - - _mc.clean_temps() ; - - printf( "generated %d vertices and %d faces!\n", _mc.nverts(), _mc.ntrigs() ) ; - - return result ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Isosurface drawing walker -bool leaf_direct_isosurface_walker( LeafOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MC_Draw &mc = fo.mc_draw() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const LeafOctree::geom_cell c = fo.geom_key( keys[j] ) ; - cube[i] = *c ; - - space[i] = (Point)c ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool LeafOctree::direct_draw_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc_draw.dat_access() = ref ; - _verts.reset() ; - - - bool result = false ; - - // Dual Marching Cubes - ::glBegin( GL_TRIANGLES ) ; - { - result = dual_cubes_walk( leaf_direct_isosurface_walker ) ; - } - ::glEnd() ; // GL_TRIANGLES - - return result ; -} -//_____________________________________________________________________________ - - - - - - -//_____________________________________________________________________________ -// Draw walker -bool leaf_draw_walker( LeafOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - Cube cells[8] ; - for( int i = 0 ; i < 8 ; ++i ) - cells[i] = key2cube( keys[i] ) ; - - ((Point)cells[0]).draw() ; - ((Point)cells[1]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[3]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[2]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[0]).draw() ; - - ((Point)cells[4]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[5]).draw() ; - ((Point)cells[7]).draw() ; - - ((Point)cells[7]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[6]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[0]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[7]).draw() ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Draw the dual octree with wireframe -bool LeafOctree::draw_dual() -//----------------------------------------------------------------------------- -{ - _verts.reset() ; - - ::glBegin( GL_LINES ) ; - bool result = dual_cubes_walk( leaf_draw_walker ) ; - ::glEnd() ; // GL_LINES - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Do nothing walker, just for dual generation timing -bool leaf_timing_walker( LeafOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - return true ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Do nothing, just for dual generation timing -bool LeafOctree::dual_timing() -//----------------------------------------------------------------------------- -{ - _verts.reset() ; - - return dual_cubes_walk( leaf_timing_walker ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Prints statistics about the octree -void LeafOctree::stats() const -//----------------------------------------------------------------------------- -{ - int s = _hash.size() ; - printf( " number of nodes:\t%d\n", s ) ; -#if USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyBucket) ) ) ; - _hash.stats() ; -#else // USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyData ) ) ) ; -#endif // USE_HASH_PTR - - printf( " leaves' levels:\t" ) ; - for( Level l = 0 ; l <= MAX_LEVEL; ++l ) - printf( "\t%d", _level_dist[l] ) ; - printf( "\n" ) ; - - s = _verts.size() ; - printf( " number of dual nodes:\t%d\n", s ) ; -#if USE_HASH_PTR - printf( " total memory of dual:\t%d\n", (int) ( s * sizeof(HashVerts::KeyBucket) ) ) ; - _verts.stats() ; -#else // USE_HASH_PTR - printf( " total memory of dual:\t%d\n", (int) ( s * sizeof(HashVerts::KeyData ) ) ) ; -#endif // USE_HASH_PTR -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// search operations - - -//_____________________________________________________________________________ -// Find cells of the octree at a given position -bool LeafOctree::find_leaf( Key k, Level o_lv, geom_cell &n ) const -//----------------------------------------------------------------------------- -{ - - Level shift = 3*(MAX_LEVEL-o_lv) ; - Key k_up = k >> shift ; - - HashField::KeyData kd_up ; - if( node_exists(k_up,kd_up) ) - { - n = geom_cell( kd_up ) ; - return true ; - } - - Key k_dw = k_up ; - HashField::KeyData kd_dw ; - - bool b_up, b_dw ; - do - { - b_up = k_up != KEY_INV ; - b_dw = shift > 2 ; - - if( b_up ) - { - k_up >>= 3; - if( node_exists(k_up,kd_up) ) - { - n = geom_cell( kd_up ) ; - return true ; - } - } - - if( b_dw ) - { - shift -= 3 ; - k_dw = k >> shift ; - if( node_exists(k_dw,kd_dw) ) - { - n = geom_cell( kd_dw ) ; - return true ; - } - } - } - while( b_up || b_dw ) ; - - return false ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find cells of the octree inside a given box of center x,y and half side r -bool LeafOctree::find_radius( real x, real y, real z, real r, List &cells ) const -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - Level lv_b = (Level)floor( log(r)/log(0.5) ) ; - Key k_b = cube2key( Cube(x,y,z,lv_b) ) ; - - Key neighbors[27] ; - neighbor_keys( k_b, neighbors ) ; - neighbors[13] = k_b ; - - Key *k_ptr = neighbors ; - for( int dir = 0 ; dir < 27 ; ++dir, ++k_ptr ) - { - Key k = *k_ptr ; - if( k == KEY_INV ) continue ; - - // look up (faster...) - Key k_up = k ; - bool found_up = false ; - HashField::KeyData kd ; - do - { - if( node_exists(k_up,kd) ) - { - geom_cell gc(kd) ; - real sz = gc.sz() + r ; - - // test directly with the key? - if( fabs( x-gc.x() ) <= sz && fabs( y-gc.y() ) <= sz && fabs( z-gc.z() ) <= sz ) - cells.insert_unique( gc ) ; - - found_up = true ; - break ; - } - k_up >>= 3 ; - } while( k_up != 0 ) ; - - if( found_up ) continue ; - - // look down - std::stack s ; - Key k_dw = k << 3 ; - ++lv_b ; - for( int i = 0 ; i < 8 ; ++i ) - // test directly with the key before insertion? - s.push( k_dw | i ) ; - - while( !s.empty() ) - { - k_dw = s.top() ; - s.pop() ; - if( node_exists(k_dw,kd) ) - { - geom_cell gc(kd) ; - real sz = gc.sz() + r ; - - // test directly with the key? - if( fabs( x-gc.x() ) <= sz && fabs( y-gc.y() ) <= sz && fabs( z-gc.z() ) <= sz ) - cells.insert( gc ) ; - - continue ; - } - - if( ++lv_b > MAX_LEVEL ) break ; - k_dw <<= 3 ; - for( int i = 0 ; i < 8 ; ++i ) - // test directly with the key before insertion? - s.push( k_dw | i ) ; - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find neighbor cells of the octree to a given cell -bool LeafOctree::adjacent( Key k, List &cells ) const -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - Key neighbors[27] ; - neighbor_keys( k, neighbors ) ; - - Key *k_ptr = neighbors ; - for( int dir = 0 ; dir < 27 ; ++dir, ++k_ptr ) - { - Key ki = *k_ptr ; - if( ki == KEY_INV ) continue ; - - HashField::KeyData kd ; - if( node_exists(ki,kd) ) - { - cells.insert( geom_cell(kd) ); - continue ; - } - - // look up (faster) - do - { - ki >>= 3 ; - if( key_contains( ki,k ) ) ki = 0 ; - } while( ki !=0 && !node_exists(ki,kd) ) ; - - if( ki > 0 ) - { - cells.insert_unique( geom_cell(kd) ) ; - continue ; - } - - ki = *k_ptr ; - - std::stack subneighbors ; - subneighbor_keys(ki, dir, subneighbors ) ; - while( !subneighbors.empty() ) - { - Key ski = subneighbors.top() ; - subneighbors.pop() ; - - if( node_exists(ski,kd) ) - cells.insert( geom_cell(kd) ); - else - { - if( key_level(ski) >= MAX_LEVEL ) break ; - subneighbor_keys(ski, dir, subneighbors ) ; - } - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// I/O - -//_____________________________________________________________________________ -// Draws the intersecting cells of a plane with the octree with color -void LeafOctree::draw_plane ( real nx, real ny, real nz, real d ) -//----------------------------------------------------------------------------- -{ - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - real px,py,pz, mx,my,mz ; - - ::glLineWidth( 1.0f ) ; - ::glDisable( GL_LIGHTING ) ; - ::glBegin( GL_LINES ) ; - { - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - { - geom_cell n = it.top() ; - real sz_ = n.sz() ; - - // get the coordinates of the extremum vertices - if( fx ) { px = n.cx() + sz_ ; mx = n.cx() - sz_ ; } - else { px = n.cx() - sz_ ; mx = n.cx() + sz_ ; } - if( fy ) { py = n.cy() + sz_ ; my = n.cy() - sz_ ; } - else { py = n.cy() - sz_ ; my = n.cy() + sz_ ; } - if( fz ) { pz = n.cz() + sz_ ; mz = n.cz() - sz_ ; } - else { pz = n.cz() - sz_ ; mz = n.cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - { - ::glTexCoord1f( (GLfloat)fabs(*n/max_field()) ) ; - n.draw_wire() ; - } - } - } - ::glEnd() ; // GL_LINES -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draws the intersection of a plane with the octree with color -void LeafOctree::draw_slice ( real nx, real ny, real nz, real d, float alpha ) -//----------------------------------------------------------------------------- -{ - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - real px,py,pz, mx,my,mz ; - - ::glDisable( GL_LIGHTING ) ; - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - { - geom_cell n = it.top() ; - real sz_ = n.sz() ; - - // get the coordinates of the extremum vertices - if( fx ) { px = n.cx() + sz_ ; mx = n.cx() - sz_ ; } - else { px = n.cx() - sz_ ; mx = n.cx() + sz_ ; } - if( fy ) { py = n.cy() + sz_ ; my = n.cy() - sz_ ; } - else { py = n.cy() - sz_ ; my = n.cy() + sz_ ; } - if( fz ) { pz = n.cz() + sz_ ; mz = n.cz() - sz_ ; } - else { pz = n.cz() - sz_ ; mz = n.cz() + sz_ ; } - - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - { - // retrieves the signs of each cube corner - real val[8] ; - real v = nx * n.cx() + ny * n.cy() + nz * n.cz() + d ; - int zeros = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - val[i] = v + nx * ((i&1)?sz_:-sz_) + ny * ((i&2)?sz_:-sz_) + nz * ((i&4)?sz_:-sz_) ; - if( fabs(val[i]) < R_EPSILON ) { val[i] = R_EPSILON ; ++zeros ; } - } - - //_________________________________________________________________________ - // degenerated intersection - if( zeros > 0 ) - { - int npos = 0, nneg = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) continue ; - if( val[i] < 0 ) - ++nneg ; - else - ++npos ; - } - float def = (nneg>npos) ? (float)R_EPSILON : -(float)R_EPSILON ; - - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) val[i] = def ; - } - // continue ; - } - - //_________________________________________________________________________ - // Continuation method - int v0=-1, v1=-1 ; // current edge vertices - - // get the first intersection - static int edges[12][2] = { {0,1}, {0,2}, {0,4}, {1,3}, {1,5}, {2,3}, {2,6}, {3,7}, {4,5}, {4,6}, {5,7}, {6,7} } ; - for( int e = 0 ; e < 12 ; ++e ) - { - if( val[ edges[e][0] ] * val[ edges[e][1] ] < 0 ) - { - v0 = edges[e][0] ; - v1 = edges[e][1] ; - break ; - } - } - int ov0 = v0, ov1 = v1 ; - - - // equation of previous face adjacent to v0v1: v>>c & 1 == s (c-th coordinate equal to +/- 1) - int pf = -1 ; bool ps ; - if ( (v0 & 1) == (v1 & 1) ) { pf = 0 ; ps = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( (v0 & 2) == (v1 & 2) ) { pf = 1 ; ps = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( (v0 & 4) == (v1 & 4) )*/ { pf = 2 ; ps = ((v0 & 4) >> 2 ) == 1 ; } - - // printf( "cube %d %d %d %d %d %d %d %d, march : (%d,%d) ", val[0]>0, val[1]>0, val[2]>0, val[3]>0, val[4]>0, val[5]>0, val[6]>0, val[7]>0, v0, v1 ) ; - - //_________________________________________________________________________ - // marching - - GLfloat color = (GLfloat)fabs(*n / max_field()) ; - //cmap.gl_color( at(*n) ) ; - ::glBegin( GL_POLYGON ) ; - { - do - { - // equation of next face adjacent to v0v1 - int nf = -1 ; bool ns ; - if ( pf != 0 && ((v0 & 1) == (v1 & 1)) ) { nf = 0 ; ns = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( pf != 1 && ((v0 & 2) == (v1 & 2)) ) { nf = 1 ; ns = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( pf != 2 && ((v0 & 4) == (v1 & 4)) )*/ { nf = 2 ; ns = ((v0 & 4) >> 2 ) == 1 ; } - - /* equivalent construction - // get the direction perpendicular to v0v1 - int of = (v0 ^ v1) & 7 ; // only bit of difference - of = of==1 ? 0 : (of==2 ? 1 : 2) ; - - // compute the equation of the next face adjacent to v0v1 - int nf = 3 - (pf+of) ; // third option: {pf,nf,of}={0,1,2} - bool ns = (v0 >> nf) & 1 ; // value of the edge on that direction - */ - - // compute the two next vertices (invert the pf-th bit - int v2 = ps ? ( v0 & (~(1< 0) | ((val[v2] > 0) << 1) | ((val[v1] > 0) << 2) | ((val[v0] > 0) << 3) ; - if( c > 7 ) c = (~c)&7 ; // consider v0 as negative, and thus v1 as positive - /* - if( c < 4 ) - { // degenerated intesection - printf( "degenerated intersection %d!\n", c ) ; - } - */ - - //_______________________________________________________________________ - // method of continuity on the cube surface - switch( c ) - { - case 4 : v0 = v3 ; break ; - case 5 : v0 = v2 ; v1 = v3 ; break ; - case 6 : /* impossible case */ break ; - case 7 : v1 = v2 ; break ; - } - - - - - real cx = n.cx(); - real cy = n.cy(); - real cz = n.cz(); - real sz = sz_; - real a0 = val[v0]; - int i0 = v0; - real a1 = val[v1]; - int i1 = v1; - - real w0 = a1 / (a1-a0) ; - real w1 = a0 / (a0-a1) ; - - real x = cx + w0 * ((i0&1)?sz:-sz) + w1 * ((i1&1)?sz:-sz); - real y = cy + w0 * ((i0&2)?sz:-sz) + w1 * ((i1&2)?sz:-sz); - real z = cz + w0 * ((i0&4)?sz:-sz) + w1 * ((i1&4)?sz:-sz); - - ::glTexCoord1d( color ) ; - ::glVertex3d(x, y, z) ; - - // next face - pf = nf ; ps = ns ; - - // printf( "(%d,%d) ", v0, v1 ) ; - } while( v0 != ov0 || v1 != ov1 ) ; - // printf( "\n" ) ; - } - ::glEnd() ; // GL_POLYGON - - } - } -} -//_____________________________________________________________________________ - - -#endif // HASH_HAS_ERASE diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/leaf_octree.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/leaf_octree.h deleted file mode 100644 index a427ee32c6..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/leaf_octree.h +++ /dev/null @@ -1,332 +0,0 @@ -/** - * \file leaf_octree.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure without intermediate nodes, hashtable and optimized operations - */ -//_____________________________________________________________________________ - - -#pragma once - -#ifndef WIN32 -#pragma interface -#endif // WIN32 - - -#include "mlist.h" -#include "cube.h" -#include "hash.h" -#include "MarchingCubes.h" -#include "mc_draw.h" -#include "data_access.h" - - -#ifdef HASH_HAS_ERASE - - -//_____________________________________________________________________________ -// LeafOctree -/// \class LeafOctree LeafOctree.h -class LeafOctree -//----------------------------------------------------------------------------- -{ -// forward declaration -public: - class geom_cell ; - class leaf_iterator ; - -// Elements -protected: - /// Octree cell data structure - typedef Hash HashField ; - - /// Hashtable of the octree nodes - HashField _hash ; - - /// Level distribution of the octree - uint _level_dist[MAX_LEVEL+1] ; - - /// Optimal level for direct search in the octree - Level _opt_level ; - - /// Maximal field of the octree - real _max_field ; - - /// Isosurface - MarchingCubes _mc ; - - /// Isosurface Draw - MC_Draw _mc_draw ; - -private: - /// Octree vertices data structure - typedef Hash HashVerts ; - /// Hashtable of the octree vertices - HashVerts _verts ; - - -//----------------------------------------------------------------------------- -// Constructors -public: - /// Default constructor: Constructs a octree with and empty root - LeafOctree() { init() ; } - - /// Destructor: Free memory - ~LeafOctree() { clear() ; } - - - /// Create the root - void init() ; - - /// Memory cleaning - void clear() { clear_octree() ; _mc.clean_all() ; } - - /// Delete the content of the octree - void clear_octree() ; - - /// Compute the optimal level - void compute_opt_level() ; - - /// Check that only the leaves have data - bool check () ; - - /// Prints statistics about the octree - void stats() const ; - - - /// Return the maximal level of the octree - Level max_level() const { Level lv = MAX_LEVEL ; while( lv > 0 && !_level_dist[lv] ) --lv ; return lv ; } - - /// Return the optimal level of the octree - Level opt_level() const { return _opt_level ; } - - /// Return the optimal level of the octree - Level &opt_level() { return _opt_level ; } - - /// Return the maximal field of the octree - real max_field() const { return _max_field ; } - - /// Return the isosurface - MarchingCubes &mc() { return _mc ; } - - /// Return the isosurface draw - MC_Draw &mc_draw() { return _mc_draw ; } - - /// set the values of each leaf from the implicit function - bool set_impl( data_access *ref = NULL ) ; - - /// Refine the octree according to the data access - bool refine( data_access *ref = NULL ) ; - - /// Adapt the octree according to the data access - bool adapt( data_access *ref = NULL ) ; - - /// Draw the octree with wireframe - bool draw_wire() ; - - /// Draw the octree with dots - bool draw_centers() ; - - /// Dual function type - typedef bool leaf_dual_walker( LeafOctree &fo, Key *keys ) ; - - /// Compute primal vertices - bool compute_primal_verts() ; - - /// Walk on the dual cubes - bool dual_cubes_walk( leaf_dual_walker &walker ) ; - - /// Build the isosurface using dual marching cubes - bool build_isosurface( data_access *ref = NULL ) ; - - /// Draw the isosurface on-the-fly using dual marching cubes - bool direct_draw_isosurface( data_access *ref = NULL ) ; - - /// Draw the dual octree with wireframe - bool draw_dual() ; - - /// Do nothing, just for dual generation timing - bool dual_timing() ; - -//----------------------------------------------------------------------------- -// iterators -public: - /// Create an iterator traversing the leaves of the tree from the root - inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; } - -//----------------------------------------------------------------------------- -// search operations -public: - /// Find cells of the octree at a given position - bool find_leaf( Key k, Level o_lv, geom_cell &cell ) const ; - bool find_leaf( Key k, geom_cell &cell ) const { return find_leaf( k, opt_level(), cell ) ; } - bool find_leaf( real x, real y, real z, geom_cell &cell ) const { return find_leaf( cube2key( Cube(x,y,z,MAX_LEVEL) ), opt_level(), cell ) ; } - - /// Find cells of the octree inside a given box of center x,y,z and half side r - bool find_radius( real x, real y, real z, real r, List &cells ) const ; - - /// Find adjacent cells of the octree to a given cell - bool adjacent( Key k, List &cells ) const ; - bool adjacent( const geom_cell &cell, List &cells ) const { return adjacent( cell.key(), cells ) ; } - - /// Node existence - bool node_exists( Key k, HashField::KeyData &kd ) const { kd = _hash[k] ; return kd.key != KEY_INV ; } - - //----------------------------------------------------------------------------- -// I/O -public: - - /// Draws the intersecting cells of a plane with the octree with color - void draw_plane ( real nx, real ny, real nz, real d ) ; - - /// Draws the intersection of a plane with the octree with color - void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ; - - /// Draws the isosurface of level l inside the dual graph - void draw_iso () { _mc.draw_surf() ; } - -//_____________________________________________________________________________ -// Iterator Cell -public : - /// Auxiliary structure to traverse the octree - class geom_cell : public Cube - //--------------------------------------------------------------------------- - { - friend class LeafOctree ; - - protected: - Key _key ; ///< octree cell - real _field ; ///< field associated to the cell - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor - geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {} - - /// Default constructor - geom_cell( HashField::KeyData kd ) : Cube(key2cube(kd.key)), _key(kd.key), _field(kd.data) {} - - /// Destructor - ~geom_cell() {} - - /// Copy constructor - geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {} - - /// Assignment operator - geom_cell &operator = ( const geom_cell &i ) - { Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; } - - - //--------------------------------------------------------------------------- - // Public constant accessors - public : - /// key const accessor - inline Key key() const { return _key ; } - /// key accessor - inline Key &key() { return _key ; } - - /// id const accessor - inline real operator*() const { return _field ; } - - //--------------------------------------------------------------------------- - // Tests - public : - /// equality operator - inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; } - - /// inequality operator - inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; } - - /// validation operator - inline bool operator ()() const { return key() != KEY_INV ; } - }; - - const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; } - const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; } - - - -//_____________________________________________________________________________ -// Cell Iterator -public : - /// Octree cell iterator : Traverse the octree returning basic information on the cells - class leaf_iterator - //--------------------------------------------------------------------------- - { - friend class LeafOctree ; - - protected: - /// Octree traversal iterator - HashField::iterator _it ; - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor : Constructs an iterator from a cell - leaf_iterator( LeafOctree &o ) : _it( o._hash.begin() ) {} - - /// Destructor - ~leaf_iterator() {} - - /// Copy constructor - leaf_iterator( const leaf_iterator &i ) : _it(i._it) {} - - /// Assignment operator - leaf_iterator &operator = ( const leaf_iterator &i ) - { _it = i._it; return *this; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const leaf_iterator &i ) const { return _it == i._it ; } - - /// inequality operator - inline bool operator !=( const leaf_iterator &i ) const { return _it != i._it ; } - - /// validation operator - inline bool operator ()() const { return _it() ; } - - /// next position - inline leaf_iterator &operator ++() { ++_it ; return *this ; } - - //--------------------------------------------------------------------------- - // Accessors - public : - // cell accessor - inline geom_cell top() const { return geom_cell( key(), *_it ) ; } - - /// id accessor - inline real &operator*() { return *_it ; } - - /// level accessor - inline Level lv() { return key_level(_it.key()) ; } - - /// size accessor - inline real sz() { return Cube(0,0,0,lv()).sz() ; } - - /// key accessor - inline Key key() const { return _it.key() ; } - - /// points accessor - inline bool is_leaf() const { return !is_inv(*_it) ; } - - /// Draws the cell wire with opengl - void draw_wire () const { top().draw_wire () ; } - - }; -} ; -//_____________________________________________________________________________ - - -#else // HASH_HAS_ERASE - -#include "opt_octree.h" -typedef OptOctree LeafOctree ; - -#endif // HASH_HAS_ERASE - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mc_draw.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mc_draw.cpp deleted file mode 100644 index a1a76351cf..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mc_draw.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/** - * @file md_draw.cpp - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.2 - * @date 12/08/2002 - * - * @brief MC_Draw Direct Draw Algorithm - */ -//________________________________________________ - - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma implementation -#endif // WIN32 - -#include -#include -#include -#include -#include -#include -#include "mc_draw.h" -#include "LookUpTable.h" - - -//_____________________________________________________________________________ -// print cube for debug -void MC_Draw::print_cube() { printf( "\t%f %f %f %f %f %f %f %f\n", _cube[0], _cube[1], _cube[2], _cube[3], _cube[4], _cube[5], _cube[6], _cube[7]) ; } -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// main algorithm -bool MC_Draw::tesselate_cube( real iso ) -//----------------------------------------------------------------------------- -{ - for( int p = 0 ; p < 8 ; ++p ) - { - real &v = _cube[p] ; - v -= iso ; - if( fabs( v ) < R_EPSILON ) v = R_EPSILON ; - } - - if( !compute_intersection_points() ) return false ; - - _lut_entry = 0 ; - for( int p = 0 ; p < 8 ; ++p ) - { - if( _cube[p] > 0 ) _lut_entry += 1 << p ; - } - - return process_cube( ) ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Compute the intersection points -bool MC_Draw::compute_intersection_points() -//----------------------------------------------------------------------------- -{ - bool res = false ; - res |= add_vertex( 0,1 ) ; - res |= add_vertex( 1,2 ) ; - res |= add_vertex( 2,3 ) ; - res |= add_vertex( 3,0 ) ; - - res |= add_vertex( 4,5 ) ; - res |= add_vertex( 5,6 ) ; - res |= add_vertex( 6,7 ) ; - res |= add_vertex( 7,4 ) ; - - res |= add_vertex( 0,4 ) ; - res |= add_vertex( 1,5 ) ; - res |= add_vertex( 2,6 ) ; - res |= add_vertex( 3,7 ) ; - - return res ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Test a face -// if face>0 return true if the face contains a part of the surface -bool MC_Draw::test_face( schar face ) -//----------------------------------------------------------------------------- -{ - real A,B,C,D ; - - switch( face ) - { - case -1 : case 1 : A = _cube[0] ; B = _cube[4] ; C = _cube[5] ; D = _cube[1] ; break ; - case -2 : case 2 : A = _cube[1] ; B = _cube[5] ; C = _cube[6] ; D = _cube[2] ; break ; - case -3 : case 3 : A = _cube[2] ; B = _cube[6] ; C = _cube[7] ; D = _cube[3] ; break ; - case -4 : case 4 : A = _cube[3] ; B = _cube[7] ; C = _cube[4] ; D = _cube[0] ; break ; - case -5 : case 5 : A = _cube[0] ; B = _cube[3] ; C = _cube[2] ; D = _cube[1] ; break ; - case -6 : case 6 : A = _cube[4] ; B = _cube[7] ; C = _cube[6] ; D = _cube[5] ; break ; - default : printf( "Invalid face code %d\n", face ) ; print_cube() ; A = B = C = D = 0 ; - }; - - if( fabs( A*C - B*D ) < R_EPSILON ) - return face >= 0 ; - return face * A * ( A*C - B*D ) >= 0 ; // face and A invert signs -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Test the interior of a cube -// if s == 7, return true if the interior is empty -// if s ==-7, return false if the interior is empty -bool MC_Draw::test_interior( schar s ) -//----------------------------------------------------------------------------- -{ - real t, At=0, Bt=0, Ct=0, Dt=0, a, b ; - char test = 0 ; - char edge = -1 ; // reference edge of the triangulation - - switch( _case ) - { - case 4 : - case 10 : - a = ( _cube[4] - _cube[0] ) * ( _cube[6] - _cube[2] ) - ( _cube[7] - _cube[3] ) * ( _cube[5] - _cube[1] ) ; - b = _cube[2] * ( _cube[4] - _cube[0] ) + _cube[0] * ( _cube[6] - _cube[2] ) - - _cube[1] * ( _cube[7] - _cube[3] ) - _cube[3] * ( _cube[5] - _cube[1] ) ; - t = - b / (2*a) ; - if( t<0 || t>1 ) return s>0 ; - - At = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - break ; - - case 6 : - case 7 : - case 12 : - case 13 : - switch( _case ) - { - case 6 : edge = test6 [_config][2] ; break ; - case 7 : edge = test7 [_config][4] ; break ; - case 12 : edge = test12[_config][3] ; break ; - case 13 : edge = tiling13_5_1[_config][_subconfig][0] ; break ; - } - switch( edge ) - { - case 0 : - t = _cube[0] / ( _cube[0] - _cube[1] ) ; - At = 0 ; - Bt = _cube[3] + ( _cube[2] - _cube[3] ) * t ; - Ct = _cube[7] + ( _cube[6] - _cube[7] ) * t ; - Dt = _cube[4] + ( _cube[5] - _cube[4] ) * t ; - break ; - case 1 : - t = _cube[1] / ( _cube[1] - _cube[2] ) ; - At = 0 ; - Bt = _cube[0] + ( _cube[3] - _cube[0] ) * t ; - Ct = _cube[4] + ( _cube[7] - _cube[4] ) * t ; - Dt = _cube[5] + ( _cube[6] - _cube[5] ) * t ; - break ; - case 2 : - t = _cube[2] / ( _cube[2] - _cube[3] ) ; - At = 0 ; - Bt = _cube[1] + ( _cube[0] - _cube[1] ) * t ; - Ct = _cube[5] + ( _cube[4] - _cube[5] ) * t ; - Dt = _cube[6] + ( _cube[7] - _cube[6] ) * t ; - break ; - case 3 : - t = _cube[3] / ( _cube[3] - _cube[0] ) ; - At = 0 ; - Bt = _cube[2] + ( _cube[1] - _cube[2] ) * t ; - Ct = _cube[6] + ( _cube[5] - _cube[6] ) * t ; - Dt = _cube[7] + ( _cube[4] - _cube[7] ) * t ; - break ; - case 4 : - t = _cube[4] / ( _cube[4] - _cube[5] ) ; - At = 0 ; - Bt = _cube[7] + ( _cube[6] - _cube[7] ) * t ; - Ct = _cube[3] + ( _cube[2] - _cube[3] ) * t ; - Dt = _cube[0] + ( _cube[1] - _cube[0] ) * t ; - break ; - case 5 : - t = _cube[5] / ( _cube[5] - _cube[6] ) ; - At = 0 ; - Bt = _cube[4] + ( _cube[7] - _cube[4] ) * t ; - Ct = _cube[0] + ( _cube[3] - _cube[0] ) * t ; - Dt = _cube[1] + ( _cube[2] - _cube[1] ) * t ; - break ; - case 6 : - t = _cube[6] / ( _cube[6] - _cube[7] ) ; - At = 0 ; - Bt = _cube[5] + ( _cube[4] - _cube[5] ) * t ; - Ct = _cube[1] + ( _cube[0] - _cube[1] ) * t ; - Dt = _cube[2] + ( _cube[3] - _cube[2] ) * t ; - break ; - case 7 : - t = _cube[7] / ( _cube[7] - _cube[4] ) ; - At = 0 ; - Bt = _cube[6] + ( _cube[5] - _cube[6] ) * t ; - Ct = _cube[2] + ( _cube[1] - _cube[2] ) * t ; - Dt = _cube[3] + ( _cube[0] - _cube[3] ) * t ; - break ; - case 8 : - t = _cube[0] / ( _cube[0] - _cube[4] ) ; - At = 0 ; - Bt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Ct = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Dt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - break ; - case 9 : - t = _cube[1] / ( _cube[1] - _cube[5] ) ; - At = 0 ; - Bt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Ct = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - Dt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - break ; - case 10 : - t = _cube[2] / ( _cube[2] - _cube[6] ) ; - At = 0 ; - Bt = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - Ct = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - Dt = _cube[3] + ( _cube[7] - _cube[3] ) * t ; - break ; - case 11 : - t = _cube[3] / ( _cube[3] - _cube[7] ) ; - At = 0 ; - Bt = _cube[2] + ( _cube[6] - _cube[2] ) * t ; - Ct = _cube[1] + ( _cube[5] - _cube[1] ) * t ; - Dt = _cube[0] + ( _cube[4] - _cube[0] ) * t ; - break ; - default : printf( "Invalid edge %d\n", edge ) ; print_cube() ; break ; - } - break ; - - default : printf( "Invalid ambiguous case %d\n", _case ) ; print_cube() ; break ; - } - - if( At >= 0 ) test ++ ; - if( Bt >= 0 ) test += 2 ; - if( Ct >= 0 ) test += 4 ; - if( Dt >= 0 ) test += 8 ; - switch( test ) - { - case 0 : return s>0 ; - case 1 : return s>0 ; - case 2 : return s>0 ; - case 3 : return s>0 ; - case 4 : return s>0 ; - case 5 : if( At * Ct - Bt * Dt < R_EPSILON ) return s>0 ; break ; - case 6 : return s>0 ; - case 7 : return s<0 ; - case 8 : return s>0 ; - case 9 : return s>0 ; - case 10 : if( At * Ct - Bt * Dt >= R_EPSILON ) return s>0 ; break ; - case 11 : return s<0 ; - case 12 : return s>0 ; - case 13 : return s<0 ; - case 14 : return s<0 ; - case 15 : return s<0 ; - } - - return s<0 ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Process a unit cube -bool MC_Draw::process_cube( ) -//----------------------------------------------------------------------------- -{ - if( _originalMC ) - { - char nt = 0 ; - while( casesClassic[_lut_entry][3*nt] != -1 ) nt++ ; - draw_triangle( casesClassic[_lut_entry], nt ) ; - return true ; - } - - int v12 = -1 ; - _case = cases[_lut_entry][0] ; - _config = cases[_lut_entry][1] ; - _subconfig = 0 ; - - switch( _case ) - { - case 0 : - break ; - - case 1 : - draw_triangle( tiling1[_config], 1 ) ; - break ; - - case 2 : - draw_triangle( tiling2[_config], 2 ) ; - break ; - - case 3 : - if( test_face( test3[_config]) ) - draw_triangle( tiling3_2[_config], 4 ) ; // 3.2 - else - draw_triangle( tiling3_1[_config], 2 ) ; // 3.1 - break ; - - case 4 : - if( test_interior( test4[_config]) ) - draw_triangle( tiling4_1[_config], 2 ) ; // 4.1.1 - else - draw_triangle( tiling4_2[_config], 6 ) ; // 4.1.2 - break ; - - case 5 : - draw_triangle( tiling5[_config], 3 ) ; - break ; - - case 6 : - if( test_face( test6[_config][0]) ) - draw_triangle( tiling6_2[_config], 5 ) ; // 6.2 - else - { - if( test_interior( test6[_config][1]) ) - draw_triangle( tiling6_1_1[_config], 3 ) ; // 6.1.1 - else - { - comp_c_vertex() ; - draw_triangle( tiling6_1_2[_config], 9 , v12) ; // 6.1.2 - } - } - break ; - - case 7 : - if( test_face( test7[_config][0] ) ) _subconfig += 1 ; - if( test_face( test7[_config][1] ) ) _subconfig += 2 ; - if( test_face( test7[_config][2] ) ) _subconfig += 4 ; - switch( _subconfig ) - { - case 0 : - draw_triangle( tiling7_1[_config], 3 ) ; break ; - case 1 : - draw_triangle( tiling7_2[_config][0], 5 ) ; break ; - case 2 : - draw_triangle( tiling7_2[_config][1], 5 ) ; break ; - case 3 : - comp_c_vertex() ; - draw_triangle( tiling7_3[_config][0], 9, v12 ) ; break ; - case 4 : - draw_triangle( tiling7_2[_config][2], 5 ) ; break ; - case 5 : - comp_c_vertex() ; - draw_triangle( tiling7_3[_config][1], 9, v12 ) ; break ; - case 6 : - comp_c_vertex() ; - draw_triangle( tiling7_3[_config][2], 9, v12 ) ; break ; - case 7 : - if( test_interior( test7[_config][3]) ) - draw_triangle( tiling7_4_2[_config], 9 ) ; - else - draw_triangle( tiling7_4_1[_config], 5 ) ; - break ; - }; - break ; - - case 8 : - draw_triangle( tiling8[_config], 2 ) ; - break ; - - case 9 : - draw_triangle( tiling9[_config], 4 ) ; - break ; - - case 10 : - if( test_face( test10[_config][0]) ) - { - if( test_face( test10[_config][1]) ) - draw_triangle( tiling10_1_1_[_config], 4 ) ; // 10.1.1 - else - { - comp_c_vertex() ; - draw_triangle( tiling10_2[_config], 8, v12 ) ; // 10.2 - } - } - else - { - if( test_face( test10[_config][1]) ) - { - comp_c_vertex() ; - draw_triangle( tiling10_2_[_config], 8, v12 ) ; // 10.2 - } - else - { - if( test_interior( test10[_config][2]) ) - draw_triangle( tiling10_1_1[_config], 4 ) ; // 10.1.1 - else - draw_triangle( tiling10_1_2[_config], 8 ) ; // 10.1.2 - } - } - break ; - - case 11 : - draw_triangle( tiling11[_config], 4 ) ; - break ; - - case 12 : - if( test_face( test12[_config][0]) ) - { - if( test_face( test12[_config][1]) ) - draw_triangle( tiling12_1_1_[_config], 4 ) ; // 12.1.1 - else - { - comp_c_vertex() ; - draw_triangle( tiling12_2[_config], 8, v12 ) ; // 12.2 - } - } - else - { - if( test_face( test12[_config][1]) ) - { - comp_c_vertex() ; - draw_triangle( tiling12_2_[_config], 8, v12 ) ; // 12.2 - } - else - { - if( test_interior( test12[_config][2]) ) - draw_triangle( tiling12_1_1[_config], 4 ) ; // 12.1.1 - else - draw_triangle( tiling12_1_2[_config], 8 ) ; // 12.1.2 - } - } - break ; - - case 13 : - if( test_face( test13[_config][0] ) ) _subconfig += 1 ; - if( test_face( test13[_config][1] ) ) _subconfig += 2 ; - if( test_face( test13[_config][2] ) ) _subconfig += 4 ; - if( test_face( test13[_config][3] ) ) _subconfig += 8 ; - if( test_face( test13[_config][4] ) ) _subconfig += 16 ; - if( test_face( test13[_config][5] ) ) _subconfig += 32 ; - switch( subconfig13[_subconfig] ) - { - case 0 :/* 13.1 */ - draw_triangle( tiling13_1[_config], 4 ) ; break ; - - case 1 :/* 13.2 */ - draw_triangle( tiling13_2[_config][0], 6 ) ; break ; - case 2 :/* 13.2 */ - draw_triangle( tiling13_2[_config][1], 6 ) ; break ; - case 3 :/* 13.2 */ - draw_triangle( tiling13_2[_config][2], 6 ) ; break ; - case 4 :/* 13.2 */ - draw_triangle( tiling13_2[_config][3], 6 ) ; break ; - case 5 :/* 13.2 */ - draw_triangle( tiling13_2[_config][4], 6 ) ; break ; - case 6 :/* 13.2 */ - draw_triangle( tiling13_2[_config][5], 6 ) ; break ; - - case 7 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][0], 10, v12 ) ; break ; - case 8 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][1], 10, v12 ) ; break ; - case 9 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][2], 10, v12 ) ; break ; - case 10 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][3], 10, v12 ) ; break ; - case 11 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][4], 10, v12 ) ; break ; - case 12 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][5], 10, v12 ) ; break ; - case 13 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][6], 10, v12 ) ; break ; - case 14 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][7], 10, v12 ) ; break ; - case 15 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][8], 10, v12 ) ; break ; - case 16 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][9], 10, v12 ) ; break ; - case 17 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][10], 10, v12 ) ; break ; - case 18 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3[_config][11], 10, v12 ) ; break ; - - case 19 :/* 13.4 */ - comp_c_vertex() ; - draw_triangle( tiling13_4[_config][0], 12, v12 ) ; break ; - case 20 :/* 13.4 */ - comp_c_vertex() ; - draw_triangle( tiling13_4[_config][1], 12, v12 ) ; break ; - case 21 :/* 13.4 */ - comp_c_vertex() ; - draw_triangle( tiling13_4[_config][2], 12, v12 ) ; break ; - case 22 :/* 13.4 */ - comp_c_vertex() ; - draw_triangle( tiling13_4[_config][3], 12, v12 ) ; break ; - - case 23 :/* 13.5 */ - _subconfig = 0 ; - if( test_interior( test13[_config][6] ) ) - draw_triangle( tiling13_5_1[_config][0], 6 ) ; - else - draw_triangle( tiling13_5_2[_config][0], 10 ) ; - break ; - case 24 :/* 13.5 */ - _subconfig = 1 ; - if( test_interior( test13[_config][6] ) ) - draw_triangle( tiling13_5_1[_config][1], 6 ) ; - else - draw_triangle( tiling13_5_2[_config][1], 10 ) ; - break ; - case 25 :/* 13.5 */ - _subconfig = 2 ; - if( test_interior( test13[_config][6] ) ) - draw_triangle( tiling13_5_1[_config][2], 6 ) ; - else - draw_triangle( tiling13_5_2[_config][2], 10 ) ; - break ; - case 26 :/* 13.5 */ - _subconfig = 3 ; - if( test_interior( test13[_config][6] ) ) - draw_triangle( tiling13_5_1[_config][3], 6 ) ; - else - draw_triangle( tiling13_5_2[_config][3], 10 ) ; - break ; - - case 27 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][0], 10, v12 ) ; break ; - case 28 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][1], 10, v12 ) ; break ; - case 29 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][2], 10, v12 ) ; break ; - case 30 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][3], 10, v12 ) ; break ; - case 31 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][4], 10, v12 ) ; break ; - case 32 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][5], 10, v12 ) ; break ; - case 33 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][6], 10, v12 ) ; break ; - case 34 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][7], 10, v12 ) ; break ; - case 35 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][8], 10, v12 ) ; break ; - case 36 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][9], 10, v12 ) ; break ; - case 37 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][10], 10, v12 ) ; break ; - case 38 :/* 13.3 */ - comp_c_vertex() ; - draw_triangle( tiling13_3_[_config][11], 10, v12 ) ; break ; - - case 39 :/* 13.2 */ - draw_triangle( tiling13_2_[_config][0], 6 ) ; break ; - case 40 :/* 13.2 */ - draw_triangle( tiling13_2_[_config][1], 6 ) ; break ; - case 41 :/* 13.2 */ - draw_triangle( tiling13_2_[_config][2], 6 ) ; break ; - case 42 :/* 13.2 */ - draw_triangle( tiling13_2_[_config][3], 6 ) ; break ; - case 43 :/* 13.2 */ - draw_triangle( tiling13_2_[_config][4], 6 ) ; break ; - case 44 :/* 13.2 */ - draw_triangle( tiling13_2_[_config][5], 6 ) ; break ; - - case 45 :/* 13.1 */ - draw_triangle( tiling13_1_[_config], 4 ) ; break ; - - default : - printf("Marching Cubes: Impossible case 13?\n" ) ; print_cube() ; - } - break ; - - case 14 : - draw_triangle( tiling14[_config], 4 ) ; - break ; - }; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Adding triangles -void MC_Draw::draw_triangle( const char* trig_, char n, int v12 ) -//----------------------------------------------------------------------------- -{ - for( int t = 0 ; t < 3*n ; t++ ) - { - switch( trig_[t] ) - { - case 0 : _verts[0][1].draw() ; break ; - case 1 : _verts[1][2].draw() ; break ; - case 2 : _verts[2][3].draw() ; break ; - case 3 : _verts[3][0].draw() ; break ; - case 4 : _verts[4][5].draw() ; break ; - case 5 : _verts[5][6].draw() ; break ; - case 6 : _verts[6][7].draw() ; break ; - case 7 : _verts[7][4].draw() ; break ; - case 8 : _verts[0][4].draw() ; break ; - case 9 : _verts[1][5].draw() ; break ; - case 10 : _verts[2][6].draw() ; break ; - case 11 : _verts[3][7].draw() ; break ; - case 12 : _c_vert .draw() ; break ; - default : break ; - } - } -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Adding vertices -bool MC_Draw::add_vertex( char i, char j ) -//----------------------------------------------------------------------------- -{ - real ci = _cube[i] ; - real cj = _cube[j] ; - if( ci * cj >= 0 ) { _verts[i][j] = P_INV ; return false ; } - - _dat_access->interpolate( ci,cj, _space[i],_space[j], _verts[i][j] ) ; - - return true ; -} -//----------------------------------------------------------------------------- - -bool MC_Draw::comp_c_vertex( ) -//----------------------------------------------------------------------------- -{ - real u = 0 ; - - _c_vert.x() = _c_vert.y() = _c_vert.z() = 0 ; - - // Computes the average of the intersection points of the cube - Point &v01 = _verts[0][1] ; if( v01 != P_INV ) { ++u ; _c_vert += v01 ; } - Point &v12 = _verts[1][2] ; if( v12 != P_INV ) { ++u ; _c_vert += v12 ; } - Point &v23 = _verts[2][3] ; if( v23 != P_INV ) { ++u ; _c_vert += v23 ; } - Point &v30 = _verts[3][0] ; if( v30 != P_INV ) { ++u ; _c_vert += v30 ; } - Point &v45 = _verts[4][5] ; if( v45 != P_INV ) { ++u ; _c_vert += v45 ; } - Point &v56 = _verts[5][6] ; if( v56 != P_INV ) { ++u ; _c_vert += v56 ; } - Point &v67 = _verts[6][7] ; if( v67 != P_INV ) { ++u ; _c_vert += v67 ; } - Point &v74 = _verts[7][4] ; if( v74 != P_INV ) { ++u ; _c_vert += v74 ; } - Point &v04 = _verts[0][4] ; if( v04 != P_INV ) { ++u ; _c_vert += v04 ; } - Point &v15 = _verts[1][5] ; if( v15 != P_INV ) { ++u ; _c_vert += v15 ; } - Point &v26 = _verts[2][6] ; if( v26 != P_INV ) { ++u ; _c_vert += v26 ; } - Point &v37 = _verts[3][7] ; if( v37 != P_INV ) { ++u ; _c_vert += v37 ; } - - _c_vert /= u ; - - return u > 0 ; -} -//_____________________________________________________________________________ - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mc_draw.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mc_draw.h deleted file mode 100644 index c2099ee787..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mc_draw.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file mc_draw.h - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.2 - * @date 12/08/2002 - * - * @brief MarchingCubes Direct Draw - */ -//________________________________________________ - - -#pragma once - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma interface -#endif // WIN32 - -#include -#include "point.h" -#include "data_access.h" - - -//_____________________________________________________________________________ -/** Marching Cubes algorithm wrapper */ -/** \class MarchingCubes Direct Draw - * \brief Marching Cubes Direct Draw. - */ -class MC_Draw -//----------------------------------------------------------------------------- -{ -// Constructors -public : - /** - * Main and default constructor - * \brief constructor - */ - MC_Draw () : _originalMC(true) {} - /** Destructor */ - ~MC_Draw () {} - -//----------------------------------------------------------------------------- -// Accessors -public : - /** - * selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes - * \param originalMC true for the original Marching Cubes - */ - inline void set_method ( const bool originalMC = false ) { _originalMC = originalMC ; } - -//----------------------------------------------------------------------------- -// Algorithm -public : - /** retrieves the isovalues at the cube vertices */ - real *cube () { return _cube ; } - /** retrieves the geometry of the cube */ - Point *space () { return _space; } - /** retrieves the data accessor */ - data_access *&dat_access() { return _dat_access ; } - - /** - * Main algorithm - * \param iso isovalue - */ - bool tesselate_cube( real iso ) ; - -protected : - /** tesselates one cube */ - bool process_cube () ; - /** tests if the components of the tesselation of the cube should be connected by the interior of an ambiguous face */ - bool test_face ( schar face ) ; - /** tests if the components of the tesselation of the cube should be connected through the interior of the cube */ - bool test_interior( schar s ) ; - - -//----------------------------------------------------------------------------- -// Operations -protected : - /** computes almost all the vertices of the mesh by interpolation along the cubes edges */ - bool compute_intersection_points() ; - - /** adds a vertex on edge cube[i] cube[j] */ - bool add_vertex( char i, char j ) ; - - /** compute a vertex inside the current cube */ - bool comp_c_vertex() ; - - /** - * routine to add a triangle to the mesh - * \param trig the code for the triangle as a sequence of edges index - * \param n the number of triangles to produce - * \param v12 the index of the interior vertex to use, if necessary - */ - void draw_triangle ( const char* trig, char n, int v12 = -1 ) ; - - /** prints cube for debug */ - void print_cube() ; - -//----------------------------------------------------------------------------- -// Elements -protected : - bool _originalMC ; /**< selects wether the algorithm will use the enhanced topologically controlled lookup table or the original MarchingCubes */ - - real _cube[8] ; /**< values of the implicit function on the active cube */ - Point _space[8] ; /**< coordinates of the active cube */ - Point _verts[8][8] ; /**< coordinates of the vertices, per edge */ - Point _c_vert ; /**< coordinates of the central vertex */ - uchar _lut_entry ; /**< cube sign representation in [0..255] */ - uchar _case ; /**< case of the active cube in [0..15] */ - uchar _config ; /**< configuration of the active cube */ - uchar _subconfig ; /**< subconfiguration of the active cube */ - data_access *_dat_access ; /**< data accessor */ -}; -//_____________________________________________________________________________ - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mem_octree.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mem_octree.cpp deleted file mode 100644 index 9aa6df57ba..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mem_octree.cpp +++ /dev/null @@ -1,1111 +0,0 @@ -/** - * \file mem_octree.cpp - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with hashtable and optimized operations without auxiliary memory - */ -//_____________________________________________________________________________ - - -#ifndef WIN32 -#pragma implementation -#endif // WIN32 - - -#include -#include "mem_octree.h" - - -//_____________________________________________________________________________ -// Create the root -void MemOctree::init() -//----------------------------------------------------------------------------- -{ - _max_field = R_INV ; - _opt_level = L_INV ; - memset( _level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - - HashField::KeyData kd ; - kd.key = 1 ; - kd.data = 0.0 ; - _hash.insert( kd ) ; - - _level_dist[0] = 1 ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -/// Compute the optimal level -void MemOctree::compute_opt_level() -//----------------------------------------------------------------------------- -{ - Level left = 0 ; - Level right = MAX_LEVEL ; - uint leftsum = 0 ; - uint rightsum = 0 ; - while( left < right ) - { - uint leftsum_old = leftsum ; - if( leftsum <= rightsum ) - { - leftsum += _level_dist[ left ] ; - ++left ; - } - if( leftsum_old >= rightsum ) - { - rightsum += _level_dist[ right ] ; - --right ; - } - } - _opt_level = right ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Check that each point scan or scribble is in the right node -bool MemOctree::check () -//----------------------------------------------------------------------------- -{ - bool result = true ; - - uint level_dist[MAX_LEVEL+1] ; - memset( level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - if( is_leaf( it.key() ) ) - level_dist[ key_level(it.key()) ] ++ ; - Key k = it.key() << 3 ; - bool has_son = false ; - bool all_sons = true ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( _hash[ k | i ].key != KEY_INV ) - has_son = true ; - else - all_sons = false ; - } - - if( it.is_leaf() && has_son ) - { - printf("(mem) Invalid leaf %d: value %f\n", (int)k, _hash[k].data ) ; - result = false ; - } - - if( has_son && !all_sons ) - { - printf("(mem) Invalid subdivision %d: value %f\n", (int)k, _hash[k].data ) ; - result = false ; - } - } - - for( Level lv = 0 ; lv <= MAX_LEVEL ; ++lv ) - { - if( _level_dist[lv] != level_dist[lv] ) - { - printf("(mem) Invalid level statistic %d: %d != %d\n", (int)lv, (int)_level_dist[lv], (int)level_dist[lv] ) ; - result = false ; - } - } - - return result ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Deletes the content of the octree -void MemOctree::clear_octree() -//----------------------------------------------------------------------------- -{ - _hash .reset() ; - _max_field = R_INV ; - _opt_level = L_INV ; - memset( _level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// set the values of each leaf from the implicit function -bool MemOctree::set_impl( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - _max_field = -FLT_MAX ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - if( it.is_leaf() ) - { - real v = (*ref).value_at( it.top() ) ; - *it = v ; - v = fabs(v) ; - if( _max_field < v ) _max_field = v ; - } -// else -// *it = R_INV ; - } - -// printf( "max field: %f\n", max_field() ) ; - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool MemOctree::refine( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - clear() ; init() ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it = geom_root() ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - _hash[it.key()].data = it._field = R_INV ; - HashField::KeyData kd ; - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - s.push( geom_cell( kd.key, kd.data ) ) ; - } - Level lv = it.lv() ; - _level_dist[ lv ] -= 1 ; - _level_dist[lv+1] += 8 ; - } - - compute_opt_level() ; - - return refined ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool MemOctree::adapt( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - -#ifdef HASH_HAS_ERASE - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it = geom_root() ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - geom_cell sons[8] ; - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; -// printf( "mem key %d\n", (int) it.key() ) ; - - // look for the leaves - if( !it.is_leaf() ) - { - if( !(*ref).need_refine( it ) ) - { - std::stack< std::pair > del_s ; // avoid level recomputation - del_s.push( std::make_pair( it.key(), it.lv() ) ) ; - while( !del_s.empty() ) - { - Key n = del_s.top().first << 3 ; - Level lv = del_s.top().second + 1 ; - del_s.pop() ; - - for( int i = 0 ; i < 8 ; ++i ) - { - HashField::KeyData kd = _hash.erase( n|i ) ; - if( !is_inv( kd.data ) ) // is_leaf(n) - { - _level_dist[ lv ] -- ; - continue ; - } - del_s.push( std::make_pair( n|i, lv ) ) ; - } - } - - refined = true ; - _level_dist[it.lv()] += 1 ; - _hash[it.key()].data = 0.0 ; // leaf now! - continue ; - } - - it.sons( sons, _hash ) ; - for( int i = 0 ; i < 8 ; ++i ) - s.push( sons[i] ) ; - - continue ; - } - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - _hash[it.key()].data = it._field = R_INV ; - HashField::KeyData kd ; - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - s.push( geom_cell( kd.key, kd.data ) ) ; - } - - Level lv = it.lv() ; - _level_dist[ lv ] -= 1 ; - _level_dist[lv+1] += 8 ; - } - - compute_opt_level() ; - return refined ; - -#else // HASH_HAS_ERASE - // no remotion in the hash table! - return refine( ref ) ; -#endif // HASH_HAS_ERASE -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with wireframe -bool MemOctree::draw_wire() -//----------------------------------------------------------------------------- -{ - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - it.draw_wire() ; - - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with dots -bool MemOctree::draw_centers() -//----------------------------------------------------------------------------- -{ - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - ::glTexCoord1f( (GLfloat)fabs(*it / max_field()) ) ; - it.top().draw() ; - } - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Octree dual caller -bool MemOctree::dual_cubes_walk( mem_dual_walker &walker ) -//----------------------------------------------------------------------------- -{ - bool result = true ; - - // add all the inner vertices - for( leaf_iterator l_it = leaves_begin() ; l_it() ; ++l_it ) - { - Key verts_k[8] ; - Level lv = vertices_keys( l_it.key(), verts_k ) ; - - Key *v_ptr = verts_k ; - for( int i = 0 ; i < 8 ; ++i, ++v_ptr ) - { - Key k = *v_ptr ; - if( k == KEY_INV ) continue ; - - Key dual_verts[8] ; - dual_vertices_keys( k, lv, dual_verts ) ; - - bool run_walker = true ; - Key *dv_ptr = dual_verts ; - for( int j = 0 ; j < 8 ; ++j, ++dv_ptr ) - { - if( j == i ) continue ; - - HashField::KeyData kd ; - - // neighbor has bigger size: skip - // must be processed by the deepest level - if( !node_exists(*dv_ptr,kd) ) - continue ; - - // neighbor is deeper: break - // will be processed by that neighbor - if( !is_leaf(kd) ) - { - run_walker = false ; - break ; - } - - // neighbor has same level - // choose the first one in the order - if( j < i ) - { - run_walker = false ; - break ; - } - } - - if( run_walker ) - { - dv_ptr = dual_verts ; - for( int j = 0 ; j < 8 ; ++j, ++dv_ptr ) - { - // find_at, only the level too high case - Key &ki = *dv_ptr ; - HashField::KeyData kd ; - while( ki != 0 && !node_exists(ki,kd) ) - ki >>= 3; - } - result &= walker( *this, dual_verts ) ; - } - } - } - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Isosurface walker -bool mem_isosurface_walker( MemOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MarchingCubes &mc = fo.mc() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - /** indexes of the cube */ - Key *indexes = mc.indexes() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const Key k = keys[j] ; - MemOctree::geom_cell c = fo.geom_key(k) ; - cube[i] = *c ; - - space[i] = (Point)c ; - indexes[i] = k ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool MemOctree::build_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc.dat_access() = ref ; - - printf( "Build isosurface... " ) ; - bool result = false ; - - //_________________________________________________________________________ - // Dual Marching Cubes - - _mc.init_all() ; - - result = dual_cubes_walk( mem_isosurface_walker ) ; - - _mc.clean_temps() ; - - printf( "generated %d vertices and %d faces!\n", _mc.nverts(), _mc.ntrigs() ) ; - - return result ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Isosurface drawing walker -bool mem_direct_isosurface_walker( MemOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MC_Draw &mc = fo.mc_draw() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const MemOctree::geom_cell c = fo.geom_key( keys[j] ) ; - cube[i] = *c ; - - space[i] = (Point)c ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool MemOctree::direct_draw_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc_draw.dat_access() = ref ; - - bool result = false ; - - // Dual Marching Cubes - ::glBegin( GL_TRIANGLES ) ; - { - result = dual_cubes_walk( mem_direct_isosurface_walker ) ; - } - ::glEnd() ; // GL_TRIANGLES - - return result ; -} -//_____________________________________________________________________________ - - - - - - -//_____________________________________________________________________________ -// Draw walker -bool mem_draw_walker( MemOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - Cube cells[8] ; - for( int i = 0 ; i < 8 ; ++i ) - cells[i] = key2cube( keys[i] ) ; - - ((Point)cells[0]).draw() ; - ((Point)cells[1]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[3]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[2]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[0]).draw() ; - - ((Point)cells[4]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[5]).draw() ; - ((Point)cells[7]).draw() ; - - ((Point)cells[7]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[6]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[0]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[7]).draw() ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Draw the dual octree with wireframe -bool MemOctree::draw_dual() -//----------------------------------------------------------------------------- -{ - ::glBegin( GL_LINES ) ; - bool result = dual_cubes_walk( mem_draw_walker ) ; - ::glEnd() ; // GL_LINES - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Do nothing walker, just for dual generation timing -bool mem_timing_walker( MemOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - return true ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Do nothing, just for dual generation timing -bool MemOctree::dual_timing() -//----------------------------------------------------------------------------- -{ - return dual_cubes_walk( mem_timing_walker ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Prints statistics about the octree -void MemOctree::stats() const -//----------------------------------------------------------------------------- -{ - int s = _hash.size() ; - printf( " number of nodes:\t%d\n", s ) ; -#if USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyBucket) ) ) ; - _hash.stats() ; -#else // USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyData ) ) ) ; -#endif // USE_HASH_PTR - - printf( " leaves' levels:\t" ) ; - for( Level l = 0 ; l <= MAX_LEVEL; ++l ) - printf( "\t%d", _level_dist[l] ) ; - printf( "\n" ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// search operations - - -//_____________________________________________________________________________ -// Find cells of the octree at a given position -bool MemOctree::find_leaf( Key k, Level o_lv, geom_cell &n ) const -//----------------------------------------------------------------------------- -{ - - Level shift = 3*(MAX_LEVEL-o_lv) ; - Key ki = k >> shift ; - HashField::KeyData kd ; - - // level too high - if( !node_exists(ki,kd) ) - { - do - { - ki >>= 3; - } - while( ki !=0 && !node_exists(ki,kd) ) ; - } - // level correct or too low - else - { - HashField::KeyData kd_temp ; - do - { - kd_temp = kd ; - shift -= 3 ; - ki = k >> shift ; - } - while( ki !=0 && node_exists(ki,kd) ) ; - kd = kd_temp ; - } - n = geom_cell( kd ) ; - - return kd.key != KEY_INV ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find cells of the octree inside a given box of center x,y and half side r -bool MemOctree::find_radius( real x, real y, real z, real r, List &cells ) const -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - Level lv_b = (Level)floor( log(r)/log(0.5) ) ; - Key k_b = cube2key( Cube(x,y,z,lv_b) ) ; - - Key neighbors[27] ; - neighbor_keys( k_b, neighbors ) ; - - std::stack s ; - s.push( k_b ) ; - - Key *k_ptr = neighbors ; - for( int dir = 0 ; dir < 27 ; ++dir, ++k_ptr ) - s.push( *k_ptr ) ; - - while( !s.empty() ) - { - Key ki = s.top() ; - s.pop() ; - if( ki == KEY_INV ) continue ; - - HashField::KeyData kd ; - if( node_exists(ki,kd) ) - { - if( is_leaf( kd ) ) - { - geom_cell gc(kd) ; - real sz = gc.sz() + r ; - - // test directly with the key? - if( fabs( x-gc.x() ) <= sz && fabs( y-gc.y() ) <= sz && fabs( z-gc.z() ) <= sz ) - cells.insert( gc ) ; - } - else - { - Key ski = ki << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - // test directly with the key before insertion? - s.push( ski | i ) ; - } - } - else - { - HashField::KeyData kd ; - do - { - ki >>= 3 ; - } while( ki !=0 && !node_exists(ki,kd) ) ; - - if( ki > 0 ) - { - geom_cell gc(kd) ; - real sz = gc.sz() + r ; - - // test directly with the key? - if( fabs( x-gc.x() ) <= sz && fabs( y-gc.y() ) <= sz && fabs( z-gc.z() ) <= sz ) - cells.insert_unique( gc ) ; - } - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find neighbor cells of the octree to a given cell -bool MemOctree::adjacent( Key k, List &cells ) const -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - Key neighbors[27] ; - neighbor_keys( k, neighbors ) ; - - Key *k_ptr = neighbors ; - for( int dir = 0 ; dir < 27 ; ++dir, ++k_ptr ) - { - Key ki = *k_ptr ; - if( ki == KEY_INV ) continue ; - - HashField::KeyData kd ; - if( node_exists(ki,kd) ) - { - if( is_leaf( kd ) ) cells.insert( geom_cell(kd) ); - else - { - std::stack subneighbors ; - subneighbor_keys(ki, dir, subneighbors ) ; - while( !subneighbors.empty() ) - { - Key ski = subneighbors.top() ; - subneighbors.pop() ; - - real sdi ; - if( is_leaf( ski, sdi ) ) - cells.insert( geom_cell( ski, sdi ) ) ; - else - subneighbor_keys(ski, dir, subneighbors ) ; - } - } - } - else - { - HashField::KeyData kd ; - do - { - ki >>= 3 ; - } while( ki !=0 && !node_exists(ki,kd) ) ; - - if( ki > 0 ) - cells.insert_unique( geom_cell(kd) ) ; - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// I/O - -//_____________________________________________________________________________ -// Draws the intersecting cells of a plane with the octree with color -void MemOctree::draw_plane ( real nx, real ny, real nz, real d ) -//----------------------------------------------------------------------------- -{ - geom_cell n = geom_root() ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - //_____________________________________________________________________________ - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - //_____________________________________________________________________________ - - ::glLineWidth( 1.0f ) ; - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - - if( n.is_leaf() ) - { - - ::glTexCoord1f( (GLfloat)fabs(*n/max_field()) ) ; - ::glBegin( GL_LINES ) ; - n.draw_wire() ; - ::glEnd() ; // GL_LINES - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons, _hash ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draws the intersection of a plane with the octree with color -void MemOctree::draw_slice ( real nx, real ny, real nz, real d, float alpha ) -//----------------------------------------------------------------------------- -{ - geom_cell n = geom_root() ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - - - //_____________________________________________________________________________ - - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - if( n.is_leaf() ) - { - // retrieves the signs of each cube corner - real val[8] ; - real v = nx * n.cx() + ny * n.cy() + nz * n.cz() + d ; - real sz_ = n.sz() ; - int zeros = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - val[i] = v + nx * ((i&1)?sz_:-sz_) + ny * ((i&2)?sz_:-sz_) + nz * ((i&4)?sz_:-sz_) ; - if( fabs(val[i]) < R_EPSILON ) { val[i] = R_EPSILON ; ++zeros ; } - } - - //_________________________________________________________________________ - // degenerated intersection - if( zeros > 0 ) - { - int npos = 0, nneg = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) continue ; - if( val[i] < 0 ) - ++nneg ; - else - ++npos ; - } - float def = (nneg>npos) ? (float)R_EPSILON : -(float)R_EPSILON ; - - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) val[i] = def ; - } - // continue ; - } - - //_________________________________________________________________________ - // Continuation method - int v0=-1, v1=-1 ; // current edge vertices - - // get the first intersection - static int edges[12][2] = { {0,1}, {0,2}, {0,4}, {1,3}, {1,5}, {2,3}, {2,6}, {3,7}, {4,5}, {4,6}, {5,7}, {6,7} } ; - for( int e = 0 ; e < 12 ; ++e ) - { - if( val[ edges[e][0] ] * val[ edges[e][1] ] < 0 ) - { - v0 = edges[e][0] ; - v1 = edges[e][1] ; - break ; - } - } - int ov0 = v0, ov1 = v1 ; - - - // equation of previous face adjacent to v0v1: v>>c & 1 == s (c-th coordinate equal to +/- 1) - int pf = -1 ; bool ps ; - if ( (v0 & 1) == (v1 & 1) ) { pf = 0 ; ps = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( (v0 & 2) == (v1 & 2) ) { pf = 1 ; ps = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( (v0 & 4) == (v1 & 4) )*/ { pf = 2 ; ps = ((v0 & 4) >> 2 ) == 1 ; } - - // printf( "cube %d %d %d %d %d %d %d %d, march : (%d,%d) ", val[0]>0, val[1]>0, val[2]>0, val[3]>0, val[4]>0, val[5]>0, val[6]>0, val[7]>0, v0, v1 ) ; - - //_________________________________________________________________________ - // marching - - GLfloat color = (GLfloat)fabs(*n / max_field()) ; - //cmap.gl_color( at(*n) ) ; - ::glBegin( GL_POLYGON ) ; - { - do - { - // equation of next face adjacent to v0v1 - int nf = -1 ; bool ns ; - if ( pf != 0 && ((v0 & 1) == (v1 & 1)) ) { nf = 0 ; ns = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( pf != 1 && ((v0 & 2) == (v1 & 2)) ) { nf = 1 ; ns = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( pf != 2 && ((v0 & 4) == (v1 & 4)) )*/ { nf = 2 ; ns = ((v0 & 4) >> 2 ) == 1 ; } - - /* equivalent construction - // get the direction perpendicular to v0v1 - int of = (v0 ^ v1) & 7 ; // only bit of difference - of = of==1 ? 0 : (of==2 ? 1 : 2) ; - - // compute the equation of the next face adjacent to v0v1 - int nf = 3 - (pf+of) ; // third option: {pf,nf,of}={0,1,2} - bool ns = (v0 >> nf) & 1 ; // value of the edge on that direction - */ - - // compute the two next vertices (invert the pf-th bit - int v2 = ps ? ( v0 & (~(1< 0) | ((val[v2] > 0) << 1) | ((val[v1] > 0) << 2) | ((val[v0] > 0) << 3) ; - if( c > 7 ) c = (~c)&7 ; // consider v0 as negative, and thus v1 as positive - /* - if( c < 4 ) - { // degenerated intesection - printf( "degenerated intersection %d!\n", c ) ; - } - */ - - //_______________________________________________________________________ - // method of continuity on the cube surface - switch( c ) - { - case 4 : v0 = v3 ; break ; - case 5 : v0 = v2 ; v1 = v3 ; break ; - case 6 : /* impossible case */ break ; - case 7 : v1 = v2 ; break ; - } - - - - - real cx = n.cx(); - real cy = n.cy(); - real cz = n.cz(); - real sz = sz_; - real a0 = val[v0]; - int i0 = v0; - real a1 = val[v1]; - int i1 = v1; - - real w0 = a1 / (a1-a0) ; - real w1 = a0 / (a0-a1) ; - - real x = cx + w0 * ((i0&1)?sz:-sz) + w1 * ((i1&1)?sz:-sz); - real y = cy + w0 * ((i0&2)?sz:-sz) + w1 * ((i1&2)?sz:-sz); - real z = cz + w0 * ((i0&4)?sz:-sz) + w1 * ((i1&4)?sz:-sz); - - ::glTexCoord1d( color ) ; - ::glVertex3d(x, y, z) ; - - // next face - pf = nf ; ps = ns ; - - // printf( "(%d,%d) ", v0, v1 ) ; - } while( v0 != ov0 || v1 != ov1 ) ; - // printf( "\n" ) ; - } - ::glEnd() ; // GL_POLYGON - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons, _hash ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mem_octree.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mem_octree.h deleted file mode 100644 index a161235b44..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mem_octree.h +++ /dev/null @@ -1,367 +0,0 @@ -/** - * \file mem_octree.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with hashtable and optimized operations without auxiliary memory - */ -//_____________________________________________________________________________ - - -#pragma once - - -#ifndef WIN32 -#pragma interface -#endif // WIN32 - - -#include "mlist.h" -#include "cube.h" -#include "hash.h" -#include "MarchingCubes.h" -#include "mc_draw.h" -#include "data_access.h" - - - -//_____________________________________________________________________________ -// MemOctree -/// \class MemOctree MemOctree.h -class MemOctree -//----------------------------------------------------------------------------- -{ -// forward declaration -public: - class geom_cell ; - class cell_iterator ; - class leaf_iterator ; - -// Elements -protected: - /// Octree cell data structure - typedef Hash HashField ; - - /// Hashtable of the octree nodes - HashField _hash ; - - /// Level distribution of the octree - uint _level_dist[MAX_LEVEL+1] ; - - /// Memimal level for direct search in the octree - Level _opt_level ; - - /// Maximal field of the octree - real _max_field ; - - /// Isosurface - MarchingCubes _mc ; - - /// Isosurface Draw - MC_Draw _mc_draw ; - -//----------------------------------------------------------------------------- -// Constructors -public: - /// Default constructor: Constructs a octree with and empty root - MemOctree() { init() ; } - - /// Destructor: Free memory - ~MemOctree() { clear() ; } - - - /// Create the root - void init() ; - - /// Memory cleaning - void clear() { clear_octree() ; _mc.clean_all() ; } - - /// Delete the content of the octree - void clear_octree() ; - - /// Compute the optimal level - void compute_opt_level() ; - - /// Check that only the leaves have data - bool check () ; - - /// Prints statistics about the octree - void stats() const ; - - /// Return the maximal level of the octree - Level max_level() const { Level lv = MAX_LEVEL ; while( lv > 0 && !_level_dist[lv] ) --lv ; return lv ; } - - /// Return the optimal level of the octree - Level opt_level() const { return _opt_level ; } - - /// Return the optimal level of the octree - Level &opt_level() { return _opt_level ; } - - /// Return the maximal field of the octree - real max_field() const { return _max_field ; } - - /// Return the isosurface - MarchingCubes &mc() { return _mc ; } - - /// Return the isosurface draw - MC_Draw &mc_draw() { return _mc_draw ; } - - /// set the values of each leaf from the implicit function - bool set_impl( data_access *ref = NULL ) ; - - /// Refine the octree according to the data access - bool refine( data_access *ref = NULL ) ; - - /// Adapt the octree according to the data access - bool adapt( data_access *ref = NULL ) ; - - /// Draw the octree with wireframe - bool draw_wire() ; - - /// Draw the octree with dots - bool draw_centers() ; - - /// Dual function type - typedef bool mem_dual_walker( MemOctree &fo, Key *keys ) ; - - /// Walk on the dual cubes - bool dual_cubes_walk( mem_dual_walker &walker ) ; - - /// Build the isosurface using dual marching cubes - bool build_isosurface( data_access *ref = NULL ) ; - - /// Draw the isosurface on-the-fly using dual marching cubes - bool direct_draw_isosurface( data_access *ref = NULL ) ; - - /// Draw the dual octree with wireframe - bool draw_dual() ; - - /// Do nothing, just for dual generation timing - bool dual_timing() ; - -//----------------------------------------------------------------------------- -// iterators -public: - /// Create an iterator traversing the tree from the root - inline cell_iterator cells_begin() { return cell_iterator( *this ) ; } - - /// Create an iterator traversing the leaves of the tree from the root - inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; } - -//----------------------------------------------------------------------------- -// search operations -public: - /// Find cells of the octree at a given position - bool find_leaf( Key k, Level o_lv, geom_cell &cell ) const ; - bool find_leaf( Key k, geom_cell &cell ) const { return find_leaf( k, opt_level(), cell ) ; } - bool find_leaf( real x, real y, real z, geom_cell &cell ) const { return find_leaf( cube2key( Cube(x,y,z,MAX_LEVEL) ), opt_level(), cell ) ; } - - /// Find cells of the octree inside a given box of center x,y,z and half side r - bool find_radius( real x, real y, real z, real r, List &cells ) const ; - - /// Find adjacent cells of the octree to a given cell - bool adjacent( Key k, List &cells ) const ; - bool adjacent( const geom_cell &cell, List &cells ) const { return adjacent( cell.key(), cells ) ; } - - /// Leaf test based on the field value - bool is_leaf( const HashField::KeyData &kd ) const { return !is_inv( kd.data ) ; } - - /// Leaf test based on the field value - bool is_leaf( Key k, real &d ) const { const HashField::KeyData &kd = _hash[k] ; d = kd.data ; return is_leaf( kd ) ; } - - /// Leaf test based on the field value - bool is_leaf( Key k ) const { return is_leaf( _hash[k] ) ; } - - /// Node existence - bool node_exists( Key k, HashField::KeyData &kd ) const { kd = _hash[k] ; return kd.key != KEY_INV ; } - - //----------------------------------------------------------------------------- -// I/O -public: - - /// Draws the intersecting cells of a plane with the octree with color - void draw_plane ( real nx, real ny, real nz, real d ) ; - - /// Draws the intersection of a plane with the octree with color - void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ; - - /// Draws the isosurface of level l inside the dual graph - void draw_iso () { _mc.draw_surf() ; } - -//_____________________________________________________________________________ -// Iterator Cell -public : - /// Auxiliary structure to traverse the octree - class geom_cell : public Cube - //--------------------------------------------------------------------------- - { - friend class MemOctree ; - - protected: - Key _key ; ///< octree cell - real _field ; ///< field associated to the cell - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor - geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {} - - /// Default constructor - geom_cell( HashField::KeyData kd ) : Cube(key2cube(kd.key)), _key(kd.key), _field(kd.data) {} - - /// Destructor - ~geom_cell() {} - - /// Copy constructor - geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {} - - /// Assignment operator - geom_cell &operator = ( const geom_cell &i ) - { Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; } - - - //--------------------------------------------------------------------------- - // Public constant accessors - public : - /// key const accessor - inline Key key() const { return _key ; } - /// key accessor - inline Key &key() { return _key ; } - - /// id const accessor - inline real operator*() const { return _field ; } - - //--------------------------------------------------------------------------- - // Tests - public : - /// equality operator - inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; } - - /// inequality operator - inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; } - - /// leaf test - inline bool is_leaf() const { return !is_inv(*(*this)) ; } - - /// validation operator - inline bool operator ()() const { return key() != KEY_INV ; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// sons - inline bool sons( geom_cell *s /*[8]*/, const HashField &hash ) - { - if( is_leaf() ) return false ; - - Key k = _key << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - s[i]._key = k | i ; - s[i]._field = hash[k|i].data ; - (Cube&)s[i] = key2cube(s[i]._key) ; - } - return true ; - } - }; - - const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; } - const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; } - - - -//_____________________________________________________________________________ -// Cell Iterator -public : - /// Octree cell iterator : Traverse the octree returning basic information on the cells - class cell_iterator - //--------------------------------------------------------------------------- - { - friend class MemOctree ; - - protected: - /// Octree traversal iterator - HashField::iterator _it ; - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor : Constructs an iterator from a cell - cell_iterator( MemOctree &o ) : _it( o._hash.begin() ) {} - - /// Destructor - ~cell_iterator() {} - - /// Copy constructor - cell_iterator( const cell_iterator &i ) : _it(i._it) {} - - /// Assignment operator - cell_iterator &operator = ( const cell_iterator &i ) - { _it = i._it; return *this; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const cell_iterator &i ) const { return _it == i._it ; } - - /// inequality operator - inline bool operator !=( const cell_iterator &i ) const { return _it != i._it ; } - - /// validation operator - inline bool operator ()() const { return _it() ; } - - /// next position - inline cell_iterator &operator ++() { ++_it ; return *this ; } - - //--------------------------------------------------------------------------- - // Accessors - public : - // cell accessor - inline geom_cell top() const { return geom_cell( key(), *_it ) ; } - - /// id accessor - inline real &operator*() { return *_it ; } - - /// level accessor - inline Level lv() { return key_level(_it.key()) ; } - - /// size accessor - inline real sz() { return Cube(0,0,0,lv()).sz() ; } - - /// key accessor - inline Key key() const { return _it.key() ; } - - /// points accessor - inline bool is_leaf() const { return !is_inv(*_it) ; } - - /// Draws the cell wire with opengl - void draw_wire () const { top().draw_wire () ; } - - }; - - - /// Octree leaf iterator : Traverse the octree returning basic information on the leaves - class leaf_iterator : public cell_iterator - //--------------------------------------------------------------------------- - { - public : - leaf_iterator( MemOctree &o ) : cell_iterator( o ) - { if( (*this)() && !this->is_leaf() ) ++(*this) ; } - - - /// next position - inline leaf_iterator &operator ++() - { - cell_iterator &it = *this ; - do ++it ; while ( it() && !it.is_leaf() ) ; - return *this ; - } - } ; -} ; -//_____________________________________________________________________________ - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mlist.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mlist.h deleted file mode 100644 index 1a86fec0b2..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mlist.h +++ /dev/null @@ -1,502 +0,0 @@ -/** - * @file mlist.h - * @author Thomas Lewiner - * @version 0.3 - * @date 28/06/2004 - * - * @brief template list class - */ -//_____________________________________________________________________________ - - - -#pragma once - -#include // qsort - -typedef unsigned int lsize ; -typedef const lsize clsize ; - -//_____________________________________________________________________________ -/// template list class -template class List -//----------------------------------------------------------------------------- -{ -// types -public : - class node ; - class iterator ; - class const_iterator ; - -//----------------------------------------------------------------------------- -// default constructors -public : - /// default constructors - List() : _first((node*)NULL) {} - - /// one-element constructor - List( const T &val ) : _first((node*)NULL) { insert(val) ; } - - /// copy constructor (reverse order) - List( const List &l ) : _first((node*)NULL) - { - for( const_iterator it = l.cbegin() ; it() ; ++it ) - insert( *it ) ; - } - - /// assignment operator - List &operator = ( const List &l ) { if( this != &l) { clear() ; for( const_iterator it = l.cbegin() ; it() ; ++it ) insert( *it ) ; } return *this; } - - /// destructor - ~List() { clear() ; } - - /// number of elements of the list - clsize size() const { lsize n = 0 ; for( const_iterator it = cbegin() ; it() ; ++it ) ++n ; return n ; } - - /// number of elements of the list - bool size_greater( clsize m ) const { lsize n = 0 ; for( const_iterator it = cbegin() ; it() ; ++it ) { if(++n > m) return true ; } return false ; } - - /// number of elements of the list - bool size_greater_or_equal( clsize m ) const { if( m == 0 ) return true ; lsize n = 0 ; for( const_iterator it = cbegin() ; it() ; ++it ) { if(++n >= m) return true ; } return false ; } - - /// tests if the list has one element - bool empty () const { return _first == (node*)NULL ; } - - /// tests if the list has two elements - bool single() const { return !empty() && _first->next() == (node*)NULL ; } - - /// tests if the list has three elements - bool pair () const { return !empty() && _first->next() != (node*)NULL && _first->next()->next() == (node*)NULL ; } - - /// tests if the list has more than three elements - bool triple() const { return !empty() && _first->next() != (node*)NULL && _first->next()->next() != (node*)NULL ; } - - const T first () const { return _first->val() ; } ///< first element accessor - T &first () { return _first->val() ; } ///< first element accessor - const T second() const { return _first->next()->val() ; } ///< second element accessor - T &second() { return _first->next()->val() ; } ///< second element accessor - const T third () const { return _first->next()->next()->val() ; } ///< third element accessor - T &third () { return _first->next()->next()->val() ; } ///< third element accessor - - /// get the first two elements - bool firsts( T &t1, T &t2 ) const { if( !empty() ) { t1 = first() ; if( !single() ) { t2 = second() ; return true ; } } return false ; } - /// get the first three elements - bool firsts( T &t1, T &t2, T &t3 ) const { if( firsts( t1,t2 ) ) { if( !pair() ) t3 = third() ; return true ; } return false ; } - - const T top () const { return _first->val() ; } ///< first element accessor - T &top () { return _first->val() ; } ///< first element accessor - -//----------------------------------------------------------------------------- -// clear -public : - /// destructor - void clear() - { - node *p = _first ; - while( p != (node*)NULL ) - { - node *n = p->next() ; - delete p ; - p = n ; - } - _first = (node*)NULL ; - } - - /// emptyness test - inline bool empty() { return _first == (node*)NULL ; } - -//----------------------------------------------------------------------------- -// find and replace -public : - /// membership test - const_iterator cfind( const T &val ) const { for( const_iterator it = cbegin() ; it() ; ++it ) if( (*it) == val ) return it ; return cend() ; } - - /// membership test - iterator find( const T &val ) { for( iterator it = begin() ; it() ; ++it ) if( (*it) == val ) return it ; return end() ; } - - /// membership test (return also the last pointer for eventual remotion) - iterator find( const T &val, iterator &lst ) { lst = end() ; for( iterator it = begin() ; it() ; ++it ) { if( *it == val ) return it ; lst = it ; } return end() ; } - - /// membership test - clsize pos( const T &val ) const { lsize i = 0 ; for( const_iterator it = cbegin() ; it() ; ++it, ++i ) if( *it == val ) return i ; return (clsize)-1 ; } - - /// get the minimal element - const_iterator min_val() const { if( empty() ) return cend() ; const_iterator it = cbegin(), m = it ; for( ++it ; it() ; ++it ) { if( *it < *m ) m = it ; } return m ; } - - /// get the minimal element - iterator min_val() { if( empty() ) return end() ; iterator it = begin(), m = it ; for( ++it ; it() ; ++it ) { if( *it < *m ) m = it ; } return m ; } - - /// get the maximal element - const_iterator max_val() const { if( empty() ) return cend() ; const_iterator it = cbegin(), m = it ; for( ++it ; it() ; ++it ) { if( *it > *m ) m = it ; } return m ; } - - /// get the maximal element - iterator max_val() { if( empty() ) return end() ; iterator it = begin(), m = it ; for( ++it ; it() ; ++it ) { if( *it > *m ) m = it ; } return m ; } - - /// replacing the elements of a list - clsize replace( const T &old_val, const T &new_val ) - { - lsize n = 0 ; - for( iterator it = begin() ; it() ; ++it ) - if( *it == old_val ) { *it = new_val ; ++n ; } - return n ; - } - -//----------------------------------------------------------------------------- -// element insertion -public : - /// insertion at the beginning - inline void push_front( const T &val ) { _first = new node( val, _first ) ; } - - /// insertion in the middle - iterator push_after( const T &val, iterator i = begin() ) - { - if( i == end() ) { push_front( val ) ; return begin() ; } - i._node->next() = new node( val, i._node->next() ) ; - return ++i ; - } - - /// insertion at the end - iterator push_back( const T &val ) - { - return push_after( val, last() ) ; - } - - /// insertion - inline void insert( const T &val ) { push_front( val ) ; } - - /// insertion - inline void push( const T &val ) { push_front( val ) ; } - - /// insertion without duplicates - inline bool insert_unique( const T &val ) { if( !find(val)() ) {push_front( val ); return true;} return false; } - - - /// list insertion (reverse, at the begining) - void insert( const List &l ) - { for( const_iterator lit = l.cbegin() ; lit() ; ++lit ) insert( *lit ) ; } - - /// list insertion without duplicates (reverse, at the begining) - void insert_unique( const List &l ) - { for( const_iterator lit = l.cbegin() ; lit() ; ++lit ) insert_unique( *lit ) ; } - - /// list insertion (ordered) - void insert_ordered( const List &l ) - { - const_iterator lit = l.cbegin() ; - iterator it = push_back( *lit ) ; - for( ; lit() ; ++lit ) - it = push_after( *lit, it ) ; - } - - - /// copy a list and clear its content - void insert_and_clear( List &l ) - { - if( this == &l ) return ; - iterator lst = last() ; - if( lst() ) - lst._node->next() = l._first ; - else - _first = l._first ; - l._first = NULL ; - } - -//----------------------------------------------------------------------------- -// element remotion -public : - /// removing the first element of the list - void remove_first() - { - node *p = _first->next() ; - delete _first ; - _first = p ; - } - - /// removing the first element of the list - void pop() { remove_first() ; } - - /// removing elements from the list - void remove_next( iterator &prev ) - { - node *p ; - if( prev == end() ) - { p = _first->next() ; delete _first ; _first = p ; } - else if( prev._node ) - { p = prev._node->next() ; prev._node->next() = p->next() ; delete p ; } - } - - /// removing elements from the list - bool remove( T &val ) - { - iterator prev = end() ; - for( iterator it = begin() ; it() ; ) - { - if( *it != val ) { prev = it ; ++it ; continue ; } - val = *it ; - node *p ; - if( prev == end() ) - { p = _first->next() ; delete _first ; _first = p ; it = begin() ; } - else - { p = it._node ; prev._node->next() = it._node->next() ; delete p ; it = prev ; ++it ; } - return true ; - } - return false ; - } - - /// removing elements from the list - clsize remove_all( const T &val ) - { - lsize n = 0 ; - iterator prev = end() ; - for( iterator it = begin() ; it() ; ) - { - if( *it != val ) { prev = it ; ++it ; continue ; } - node *p ; - if( prev == end() ) - { p = _first->next() ; delete _first ; _first = p ; it = begin() ; } - else - { p = it._node ; prev._node->next() = it._node->next() ; delete p ; it = prev ; ++it ; } - ++n ; - if( !it() ) return n ; - } - return n ; - } - - -//----------------------------------------------------------------------------- -// sort -public : - /// array transform - void get_array( T *a, clsize sz /*= size()*/ ) - { - lsize i = 0 ; - for( const_iterator it = cbegin() ; it() && i < sz ; ++it, ++i ) - a[i] = *it ; - } - - /// array transform - T *get_array( clsize sz /*= size()*/ ) - { - T *a = new T[sz] ; - get_array( a,sz ) ; - return a ; - } - - /// array read - void set_array( clsize sz = 0, const T *a = (const T*)NULL ) - { - clear() ; - if( sz == 0 ) return ; - push_front( a[0] ) ; - iterator it = begin() ; - for( lsize i = 1 ; i < sz ; ++i ) - it = push_after( a[i], it ) ; - } - - /// sort - void sort( int compare(const void*,const void*) ) - { - clsize sz = size() ; - T *a = get_array( sz ) ; - qsort( (void*)a, sz, sizeof(T), compare ) ; - set_array( sz, a ) ; - delete [] a ; - } - -//----------------------------------------------------------------------------- -// Elements -private : - node *_first; ///< link to the first element - - - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// node representation -public : - /// node of a list - class node - { - public : - // constructors - /// default constructors - node( T val_, node *next_ = (node*)NULL ) : _val (val_) , _next (next_) {} - - /// destructor - ~node() {} - - /// copy constructor - node( const node &n ) : _val(n.val()), _next(n.next()) {} - - /// assignment operator - node &operator = ( const node &n ) - { _val = n.val(); _next = n.next(); return this; } - - //----------------------------------------------------------------------------- - // Accessors - public : - inline const T &val () const { return _val ; } ///< accesses the value of the node - inline const node *next() const { return _next ; } ///< accesses the next element - - inline T &val () { return _val ; } ///< accesses the value of the node - inline node *&next() { return _next ; } ///< accesses the next element - - //----------------------------------------------------------------------------- - // Elements - private : - T _val ; ///< value - node *_next; ///< link to the next element - }; - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// const_iterator -public : - /// list const iterator - class const_iterator - { - public : - // constructors - /// default constructors - const_iterator( node *n = (node*)NULL ) : _node(n) {} - - /// destructor - ~const_iterator() {} - - /// copy constructor - const_iterator( const const_iterator &i ) : _node(i._node) {} - - /// assignment operator - const_iterator &operator = ( const const_iterator &i ) - { _node = i._node; return *this; } - - friend class List ; - - //----------------------------------------------------------------------------- - // Operations - public : - inline bool operator ==( const const_iterator &i ) const { return _node == i._node ; } ///< equality operator - inline bool operator !=( const const_iterator &i ) const { return _node != i._node ; } ///< inequality operator - inline bool operator ()() const { return _node != (node*)NULL ; } ///< validation operator - inline const T &operator * () const { return _node->val() ; } ///< value accessor - inline const_iterator &operator ++() { _node = _node->next() ; return *this ; } ///< accesses the next position - - //----------------------------------------------------------------------------- - // Elements - private : - node *_node; ///< node position - }; - -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -// iterator -public : - /// list iterator - class iterator - { - public : - // constructors - /// default constructors - iterator( node *n = (node*)NULL ) : _node(n) {} - - /// destructor - ~iterator() {} - - /// copy constructor - iterator( const iterator &i ) : _node(i._node) {} - - /// assignment operator - iterator &operator = ( const iterator &i ) - { _node = i._node; return *this; } - - friend class List ; - - //----------------------------------------------------------------------------- - // Operations - public : - inline bool operator ==( const iterator &i ) const { return _node == i._node ; } ///< equality operator - inline bool operator !=( const iterator &i ) const { return _node != i._node ; } ///< inequality operator - inline bool operator ()() const { return _node != (node*)NULL ; } ///< validation operator - inline T &operator * () const { return _node->val() ; } ///< value accessor - inline iterator &operator ++() { _node = _node->next() ; return *this ; } ///< accesses the next position - - //----------------------------------------------------------------------------- - // Elements - private : - node *_node; ///< node position - }; - -//----------------------------------------------------------------------------- -// iterator creation -public : - inline const_iterator cbegin() const { return const_iterator( _first ) ; } ///< iterator creation - inline const_iterator cend () const { return const_iterator( (node*)NULL ) ; } ///< iterator end - inline iterator begin() { return iterator( _first ) ; } ///< iterator creation - inline iterator end () { return iterator( (node*)NULL ) ; } ///< iterator end - - /// last position - iterator last () { iterator lst = end(), it = begin() ; while( it() ) { lst = it ; ++it ; } return lst ; } -}; -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -/// template list class -template class Queue : public List -//----------------------------------------------------------------------------- -{ -//----------------------------------------------------------------------------- -// default constructors -public : - /// default constructors - Queue() : List() { _last = this->end() ; } - - /// one-element constructor - Queue( const T &val ) : List( val ) { _last = this->begin() ; } - - /// copy constructor (reverse order) - Queue( const Queue &q ) : List() - { for( typename List::const_iterator it = q.cbegin() ; it() ; ++it ) Queue::insert( *it ) ; } - - /// assignment operator - Queue &operator = ( const Queue &q ) - { if( this != &q) { this->clear() ; for( typename List::const_iterator it = q.cbegin() ; it() ; ++it ) insert( *it ) ; } return *this; } - - /// destructor - ~Queue() { this->clear() ; } - - -//----------------------------------------------------------------------------- -// element insertion -public : - /// insertion at the end - inline void insert( const T &val ) - { _last = push_after( val, _last ) ; } - - /// queue insertion - void insert( const Queue &l ) - { for( typename List::const_iterator lit = l.cbegin() ; lit() ; ++lit ) insert( *lit ) ; } - -//----------------------------------------------------------------------------- -// stqndqrd function -public : - /// first element - inline const T front() const { return this->first() ; } - - /// insertion at the end - inline void push( const T &val ) { this->insert( val ) ; } - - /// deletion at the beginning - inline void pop () { this->remove_first() ; if( this->empty() ) _last = this->end() ; } - - -//----------------------------------------------------------------------------- -// Elements -private : - typename List::iterator _last; ///< link to the last element -}; -//_____________________________________________________________________________ - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/morton.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/morton.cpp deleted file mode 100644 index 43799f63ef..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/morton.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/** - * \file morton.cpp - * \author Thomas Lewiner - * \author Rener Pereira de Castro - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * \brief Morton codes manipulation - * - * Morton codes manipulation - */ -//_____________________________________________________________________________ - - -#ifndef WIN32 -#pragma implementation -#endif // WIN32 - -#include "morton.h" - -//_____________________________________________________________________________ -// static -#ifdef UNIX -real R_INV = strtof("NAN(char-sequence)", NULL); //nanf(0) ; -#else -real R_INV = nan(0) ; -#endif - -Level L_INV = (Level)-1 ; -Point P_INV( R_INV, R_INV, R_INV ) ; -Cube C_INV( P_INV, L_INV ) ; -Key KEY_INV = 0 ; -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Static Members Aux - - -// 1 << ((dz==0)+(dy==0)+(dx==0)) -static const char nsubneighbors[27] = { 1, // Direction (-1,-1,-1) - 2, // Direction (-1,-1, 0) - 1, // Direction (-1,-1, 1) - 2, // Direction (-1, 0,-1) - 4, // Direction (-1, 0, 0) - 2, // Direction (-1, 0, 1) - 1, // Direction (-1, 1,-1) - 2, // Direction (-1, 1, 0) - 1, // Direction (-1, 1, 1) - 2, // Direction ( 0,-1,-1) - 4, // Direction ( 0,-1, 0) - 2, // Direction ( 0,-1, 1) - 4, // Direction ( 0, 0,-1) - 0, // Direction ( 0, 0, 0) - 4, // Direction ( 0, 0, 1) - 2, // Direction ( 0, 1,-1) - 4, // Direction ( 0, 1, 0) - 2, // Direction ( 0, 1, 1) - 1, // Direction ( 1,-1,-1) - 2, // Direction ( 1,-1, 0) - 1, // Direction ( 1,-1, 1) - 2, // Direction ( 1, 0,-1) - 4, // Direction ( 1, 0, 0) - 2, // Direction ( 1, 0, 1) - 1, // Direction ( 1, 1,-1) - 2, // Direction ( 1, 1, 0) - 1, // Direction ( 1, 1, 1) - }; - -static const char l3b[27][4] = { {7,-1,-1,-1},{6, 7,-1,-1},{6,-1,-1,-1},{5, 7,-1,-1},{4, 5, 6, 7},{4, 6,-1,-1},{ 5,-1,-1,-1}, - {4, 5,-1,-1},{4,-1,-1,-1},{3, 7,-1,-1},{2, 3, 6, 7},{2, 6,-1,-1},{1, 3, 5, 7},{-1,-1,-1,-1}, - {0, 2, 4, 6},{1, 5,-1,-1},{0, 1, 4, 5},{0, 4,-1,-1},{3,-1,-1,-1},{2, 3,-1,-1},{ 2,-1,-1,-1}, - {1, 3,-1,-1},{0, 1, 2, 3},{0, 2,-1,-1},{1,-1,-1,-1},{0, 1,-1,-1},{0,-1,-1,-1},}; -//_____________________________________________________________________________ -// Contraction and Dilatation Masks -static const uint three_2 = 9 ; -static const uint three_1 = 3 ; -static const uint three_0 = 1 ; -static const uint shift_2a = 18, shift_2b = 36 ; -static const uint shift_1a = 6, shift_1b = 12 ; -static const uint shift_0a = 2, shift_0b = 4 ; -static const Key dilate_mask_2 = (Key)0x7FC0000FF80001FFLL ; // bits 1 from 0-9, 27-36 and 54-63 -static const Key dilate_mask_1 = (Key)0x01C0E070381C0E07LL ; // bits 1 from 0-3, 9-12, 18-21,... -static const Key dilate_mask_0 = (Key)0x9249249249249249LL ; // bits 1 at 0,3,6,9,12,... -static const Key dilate_tz = (Key)0x4924924924924924LL ; // bits 1 at 2,5,8,11,14,... rigth to left -static const Key dilate_ty = (Key)0x2492492492492492LL ; // bits 1 at 1,4,7,10,13,... -static const Key dilate_tx = (Key)0x9249249249249249LL ; // bits 1 at 0,3,6,9,12,... -static const Key dilate_t1 = (Key)0xB6DB6DB6DB6DB6DBLL ; // bits 0 at 2,5,8,11,14,... = ~tz -static const Key dilate_t2 = (Key)0xDB6DB6DB6DB6DB6DLL ; // bits 0 at 1,4,7,10,13,... = ~ty -static const Key dilate_t3 = (Key)0x6DB6DB6DB6DB6DB6LL ; // bits 0 at 0,3,6,9,12,... = ~tx - -//_____________________________________________________________________________ -// Step Directions Find Neighbours - 26 (dz,dy,dx) -static const Key dir_neigh[27] = { (Key)0xFFFFFFFFFFFFFFFFLL , // Direction (-1,-1,-1) - (Key)0x6DB6DB6DB6DB6DB6LL , // Direction (-1,-1, 0) - (Key)0x6DB6DB6DB6DB6DB7LL , // Direction (-1,-1, 1) - (Key)0xDB6DB6DB6DB6DB6DLL , // Direction (-1, 0,-1) - (Key)0x4924924924924924LL , // Direction (-1, 0, 0) - (Key)0x4924924924924925LL , // Direction (-1, 0, 1) - (Key)0xDB6DB6DB6DB6DB6FLL , // Direction (-1, 1,-1) - (Key)0x4924924924924926LL , // Direction (-1, 1, 0) - (Key)0x4924924924924927LL , // Direction (-1, 1, 1) - (Key)0xB6DB6DB6DB6DB6DBLL , // Direction ( 0,-1,-1) - (Key)0x2492492492492492LL , // Direction ( 0,-1, 0) - (Key)0x2492492492492493LL , // Direction ( 0,-1, 1) - (Key)0x9249249249249249LL , // Direction ( 0, 0,-1) - (Key)0x0000000000000000LL , // Direction ( 0, 0, 0) - (Key)0x0000000000000001LL , // Direction ( 0, 0, 1) - (Key)0x924924924924924BLL , // Direction ( 0, 1,-1) - (Key)0x0000000000000002LL , // Direction ( 0, 1, 0) - (Key)0x0000000000000003LL , // Direction ( 0, 1, 1) - (Key)0xB6DB6DB6DB6DB6DFLL , // Direction ( 1,-1,-1) - (Key)0x2492492492492496LL , // Direction ( 1,-1, 0) - (Key)0x2492492492492497LL , // Direction ( 1,-1, 1) - (Key)0x924924924924924DLL , // Direction ( 1, 0,-1) - (Key)0x0000000000000004LL , // Direction ( 1, 0, 0) - (Key)0x0000000000000005LL , // Direction ( 1, 0, 1) - (Key)0x924924924924924FLL , // Direction ( 1, 1,-1) - (Key)0x0000000000000006LL , // Direction ( 1, 1, 0) - (Key)0x0000000000000007LL , // Direction ( 1, 1, 1) - }; - -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// octree depth level associated to a morton key ( = (bit length - 1) / 3 ) -Level key_level ( Key k ) -//_____________________________________________________________________________ -{ - static const real lg2_3 = 1.0 / (log(2)*3) ; - if( k == KEY_INV ) return L_INV ; - return (Level) floor( log(k) * lg2_3 ) ; -/* - Level count = 0 ; - do - { - k >>= 3 ; - ++count; - } - while( k > 0 ) ; - - return count-1 ; -*/ -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// containment text implemented directly onf the key -bool key_contains( Key k_big, Key k_small ) -//_____________________________________________________________________________ -{ - while( (k_small!=KEY_INV) && ((k_small>>3) != k_big) ) - k_small >>= 3; - return k_small != KEY_INV ; - // k_small & 7 -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// convert an octree cube to a morton key using integer contraction -Key cube2key ( const Cube &c ) -//_____________________________________________________________________________ -{ - uint level = c.lv(); - Key m = 1 << level ; - real sz = (real) m ; - - Key bz = (Key) floor( c.z() * sz ) ; - Key by = (Key) floor( c.y() * sz ) ; - Key bx = (Key) floor( c.x() * sz ) ; - /* - if( bz >= m ) bz = m-1 ; - if( by >= m ) by = m-1 ; - if( bx >= m ) bx = m-1 ; - */ - - if( level > three_2 ) - { - bz = ( bz | (bz << shift_2a) | (bz << shift_2b) ) & dilate_mask_2 ; - by = ( by | (by << shift_2a) | (by << shift_2b) ) & dilate_mask_2 ; - bx = ( bx | (bx << shift_2a) | (bx << shift_2b) ) & dilate_mask_2 ; - } - if( level > three_1 ) - { - bz = ( bz | (bz << shift_1a) | (bz << shift_1b) ) & dilate_mask_1 ; - by = ( by | (by << shift_1a) | (by << shift_1b) ) & dilate_mask_1 ; - bx = ( bx | (bx << shift_1a) | (bx << shift_1b) ) & dilate_mask_1 ; - } - if( level > three_0 ) - { - bz = ( bz | (bz << shift_0a) | (bz << shift_0b) ) & dilate_mask_0 ; - by = ( by | (by << shift_0a) | (by << shift_0b) ) & dilate_mask_0 ; - bx = ( bx | (bx << shift_0a) | (bx << shift_0b) ) & dilate_mask_0 ; - } - return (Key(1) << (3*level)) | (bz << 2) | (by << 1) | bx ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// convert a morton key to a key using integer dilation -const Cube key2cube ( Key key ) -//_____________________________________________________________________________ -{ - if( key == KEY_INV ) - return C_INV ; - - Level level = key_level( key ) ; - Key bz( (key >> 2) & dilate_mask_0 ) ; - Key by( (key >> 1) & dilate_mask_0 ) ; - Key bx( ( key ) & dilate_mask_0 ) ; - - if( level > three_0 ) - { - bz = ( bz | (bz >> shift_0a) | (bz >> shift_0b) ) & dilate_mask_1 ; - by = ( by | (by >> shift_0a) | (by >> shift_0b) ) & dilate_mask_1 ; - bx = ( bx | (bx >> shift_0a) | (bx >> shift_0b) ) & dilate_mask_1 ; - - if( level > three_1 ) - { - bz = ( bz | (bz >> shift_1a) | (bz >> shift_1b) ) & dilate_mask_2 ; - by = ( by | (by >> shift_1a) | (by >> shift_1b) ) & dilate_mask_2 ; - bx = ( bx | (bx >> shift_1a) | (bx >> shift_1b) ) & dilate_mask_2 ; - - if( level > three_2 ) - { - bz = bz | (bz >> shift_2a) | (bz >> shift_2b) ; - by = by | (by >> shift_2a) | (by >> shift_2b) ; - bx = bx | (bx >> shift_2a) | (bx >> shift_2b) ; - } - } - } - - Key length_mask = (1 << level) -1 ; - bz &= length_mask ; - by &= length_mask ; - bx &= length_mask ; - - Cube c ; - c.lv() = level ; - real sz = c.sz() ; - real sz2 = sz*2 ; - c.z() = (real)(bz) * sz2 + sz ; - c.y() = (real)(by) * sz2 + sz ; - c.x() = (real)(bx) * sz2 + sz ; - - return c ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// addition in dilated integer -Key addition_locate_code( const Key& N , const Key& DN ) -//----------------------------------------------------------------------------- -{ - return ( - ( ((N | dilate_t1) + (DN & dilate_tz)) & dilate_tz ) | - ( ((N | dilate_t2) + (DN & dilate_ty)) & dilate_ty ) | - ( ((N | dilate_t3) + (DN & dilate_tx)) & dilate_tx ) - ); -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// addition in dilated integer -Key substraction_locate_code( const Key& N , const Key& DN ) -//----------------------------------------------------------------------------- -{ - return ( - ( ((N & dilate_tz) - (DN & dilate_tz)) & dilate_tz ) | - ( ((N & dilate_ty) - (DN & dilate_ty)) & dilate_ty ) | - ( ((N & dilate_tx) - (DN & dilate_tx)) & dilate_tx ) - ); -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// generate a list of 27 neighbor keys of same level, with their direction, indexed by 9*(dz+1) + 3*(dy+1) + (dx+1) -bool neighbor_keys( Key k, Key *neighbors ) -//_____________________________________________________________________________ -{ - Level nbits_neigh = 3*key_level(k) ; - for( uint dir = 0 ; dir < 27 ; ++dir ) - { - Key &nk = neighbors[dir] ; - if( dir == 13 ) { nk = KEY_INV ; continue ; } - nk = addition_locate_code( k , dir_neigh[dir] ) ; - if( (nk >> nbits_neigh) != 1 ) - nk = KEY_INV ; - } - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// generate a list of the subneighbor keys from a neighbor direction -// returns the number of subneighbors -char subneighbor_keys( Key k, char dir, std::stack &subneighbors ) -//_____________________________________________________________________________ -{ - k <<= 3 ; - char nsub = nsubneighbors[dir] ; - for( char i = 0 ; i < nsub ; ++i ) - { - subneighbors.push( k | l3b[dir][i] ) ; - } - return nsub ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -void print_binary( const Key k ) -//_____________________________________________________________________________ -{ - printf( "0x" ) ; - for( char i = 63 ; i >= 0 ; --i ) - printf( "%c", (k>>i)&1 ? '1' : '0' ) ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// generate a list of 8 vertices keys -Level vertices_keys( Key k, Key *verts ) -//_____________________________________________________________________________ -{ - Level lv = key_level(k) ; - Key lv_k = 1 << (3*lv) ; - Key lv_K = lv_k << 1 ; - - for( int i = 0 ; i < 8 ; ++i ) - { - Key vk = addition_locate_code( k,i ) ; - - if( vk >= lv_K || !((vk-lv_k)&dilate_tx) || !((vk-lv_k)&dilate_ty) || !((vk-lv_k)&dilate_tz) ) - { - verts[i] = KEY_INV ; - continue ; - } - - verts[i] = vk << 3*(MAX_LEVEL - lv) ; - } - return lv ; - -/* - Level lv = key_level(k) ; - Key lv_k = 1 << (3*lv) ; - Key lv_K = lv_k << 1 ; - - Cube c = key2cube(k) ; - const real ix = c.x () ; - const real iy = c.y () ; - const real iz = c.z () ; - const real is = c.sz() ; - - for( int i = 0 ; i < 8 ; ++i ) - { - Key vk = addition_locate_code( k,i ) ; - Cube v( (i&1) ? ix+is : ix-is, - (i&2) ? iy+is : iy-is, - (i&4) ? iz+is : iz-is, - MAX_LEVEL ) ; - bool invalid = ( - v.x() <= 0.0 || v.x() >= 1 || - v.y() <= 0.0 || v.y() >= 1 || - v.z() <= 0.0 || v.z() >= 1 - ) ; - bool k_invalid = vk >= lv_K || !((vk-lv_k)&dilate_tx) || !((vk-lv_k)&dilate_ty) || !((vk-lv_k)&dilate_tz) ; - if( invalid != k_invalid ) - printf( "problem\n" ) ; - if( invalid ) - { - verts[i] = KEY_INV ; - continue ; - } - - vk <<= 3*(MAX_LEVEL - lv) ; - verts[i] = cube2key(v) ; - if( vk != verts[i] ) - printf( "problem\n" ) ; - } - return c.lv() ; -*/ -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// generate a list of 8 dual vertices keys from a vertex key and the deepest neighbor level -bool dual_vertices_keys( Key k, Level lv, Key *dual_verts ) -//_____________________________________________________________________________ -{ - Key dk = k >> (3*(MAX_LEVEL - lv)) ; - - for( int i = 0 ; i < 8 ; ++i ) - { - dual_verts[i] = substraction_locate_code( dk,i ) ; - } - - return true ; - -/* - Key dk = k >> (3*(MAX_LEVEL - lv)) ; - - Cube c = key2cube( k ) ; - c.lv() = lv ; - - const real ix = c.x () ; - const real iy = c.y () ; - const real iz = c.z () ; - const real is = c.sz() ; - -// print_binary( k ) ; -// printf( " <- \n" ) ; - for( int i = 0 ; i < 8 ; ++i ) - { - Cube dv( (i&1) ? ix+is : ix-is, - (i&2) ? iy+is : iy-is, - (i&4) ? iz+is : iz-is, - lv ) ; - - dual_verts[i] = cube2key(dv) ; - if( substraction_locate_code( dk,7-i) != dual_verts[i] ) - printf( "problem\n" ) ; -// print_binary( dual_verts[i] ) ; -// printf( "\n" ) ; -// print_binary( substraction_locate_code( dk,7-i) ) ; -// printf( "\n" ) ; - } -// printf( "\n" ) ; - - return true ; -*/ -} -//_____________________________________________________________________________ - - -// testar que dois cubos se intersectam??? - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/morton.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/morton.h deleted file mode 100644 index 63563ad7f8..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/morton.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * \file morton.h - * \author Thomas Lewiner - * \author Rener Pereira de Castro - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * \brief Morton codes manipulation - * - * Morton codes manipulation -*/ -//_____________________________________________________________________________ - - - -#pragma once - -#ifndef WIN32 -#pragma interface -#endif // WIN32 - - -#include -#include -#include -#include -#include "cube.h" - -typedef uint64_t Key; -extern Key KEY_INV ; -const uint MAX_LEVEL = (sizeof(Key)*8-1)/3 ; - -//_____________________________________________________________________________ - -/// octree depth level associated to a morton key ( = (bit length - 1) / 3 ) -Level key_level ( Key k ) ; - -/// containment text implemented directly onf the key -bool key_contains( Key k_big, Key k_small ) ; - -/// convert an octree cube to a morton key using integer contraction -Key cube2key ( const Cube &c ) ; - -/// convert a morton key to a key using integer dilation -const Cube key2cube ( Key k ) ; - -/// generate a list of 27 neighbor keys of same level, with their direction, indexed by 9*(dx+1) + 3*(dy+1) + (dz+1) -bool neighbor_keys( Key k, Key *neighbors ) ; - -/// generate a list of the subneighbor keys from a neighbor direction, and return the number of subneighbors -char subneighbor_keys( Key k, char dir, std::stack &subneighbors ) ; - -/// generate a list of 8 vertices keys from a cell key -Level vertices_keys( Key k, Key *verts ) ; - -/// generate a list of 8 dual vertices keys from a vertex key and the deepest neighbor level -bool dual_vertices_keys( Key k, Level lv, Key *dual_verts ) ; - -//_____________________________________________________________________________ - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mvector.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mvector.h deleted file mode 100644 index e38dc5bb00..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/mvector.h +++ /dev/null @@ -1,261 +0,0 @@ -/** - * \file mvector.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * \brief light array container - * - * Light array container - */ -//_____________________________________________________________________________ - - -#pragma once - -#include -#include // memcpy, memset -#include - -/// unsigned int alias -typedef unsigned int uint ; -/// const unsigned int alias -typedef const uint cuint ; - -/// default data size -#define INITIAL_MVECTOR_SIZE ((uint)1024) - - -//_____________________________________________________________________________ -// mvector -/// \class mvector mvector.h -template< typename Data > class mvector -//----------------------------------------------------------------------------- -{ -// Constructors -public : - /// Constructor - mvector() : _data((Data*)NULL), _allocated_size(0), _used_size(0) {} ; - - /// Destructor - ~mvector() { clear() ; } - - // no copy on purpose - -//------------------------------------------------ -// Operations -public : - /// delete the data - void clear() { free(_data) ; _data = (Data*)NULL ; _allocated_size = 0 ; _used_size = 0 ; _deleted.clear() ; } - - /// estimation of the memory that will be used - bool reserve( uint n ) - { - if( n < INITIAL_MVECTOR_SIZE ) n = INITIAL_MVECTOR_SIZE ; - if( n <= _allocated_size ) return true ; - - Data *temp = _data ; - _data = (Data*)malloc( n*sizeof(Data) ) ; - if( temp ) memcpy( _data, temp, _used_size*sizeof(Data) ) ; - memset( _data + _used_size, 0, (n-_used_size)*sizeof(Data) ) ; - free( temp ) ; - - _allocated_size = n ; - return _data != (Data*)NULL ; - } - - /// reserve space for n new elements - bool reserve_more( uint n ) - { - if( _used_size + n > _allocated_size + _deleted.size() ) - { - uint new_size = 2*_allocated_size ; - if( new_size < _used_size + n ) new_size = _used_size + n ; - //return reserve( 2*_allocated_size ) ; - return reserve( new_size ) ; - } - return true ; - } - - /// insert n new elements - bool allocate_more( uint n ) - { - if( !reserve_more( n ) ) return false ; - _used_size += n ; - return true ; - } - - /// add one more element and - Data &add( uint &id ) - { - if( _deleted.empty() ) - { - id = _used_size ; - allocate_more( 1 ) ; - } - else - { - id = _deleted.first() ; - _deleted.remove_first() ; - } - return at(id) ; - } - - /// lazy remotion - bool remove( uint id ) - { - if( id+1 == _used_size ) - --_used_size ; - else - _deleted.insert(id) ; - return true ; - } - - -//------------------------------------------------ -// Accessor -public : - /// size accessor - uint size() { return _used_size - _deleted.size() ; } - - /// size accessor - uint used_size() { return _used_size ; } - - /// non checked const accessor - const Data &at( uint id ) const { return _data[id] ; } - /// non checked accessor - Data &at( uint id ) { return _data[id] ; } - - /// non checked const accessor - const Data &operator[]( uint id ) const { return at(id) ; } - /// non checked accessor - Data &operator[]( uint id ) { return at(id) ; } - - /// non checked pointer accessor - Data *operator +( uint id ) { return _data + id ; } - - /// id range validity check - bool is_valid( uint id ) { return (id < size() && id>=0) ; } - - /// id validity check - bool is_deleted( uint id ) { return is_valid(id) && _deleted.find(id) () ; } - - -//------------------------------------------------ -// Elements -private : - /// main data array - Data *_data ; - - /// real data size - uint _allocated_size ; - - /// filled data size - uint _used_size ; - - /// deleted data - List _deleted ; - - -//------------------------------------------------ -// iterator -public : - /// iterator - class iterator - { - public : - // constructors - /// default constructors - iterator( mvector &vec_, uint id_ = 0 ) : _vec(vec_), _id(id_) {} - - /// destructor - ~iterator() {} - - /// copy constructor - iterator( const iterator &it ) : _vec(it._vec), _id(it._id) {} - - /// assignment operator - iterator &operator = ( const iterator &it ) - { _vec = it._vec; _id = it._id; return *this; } - - //----------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const iterator &it ) const { return &_vec == &it._vec && _id == it._id ; } - /// inequality operator - inline bool operator !=( const iterator &it ) const { return &_vec != &it._vec || _id != it._id ; } - - /// validation operator - inline bool operator ()() const { return _vec.is_valid( _id ) ; } - - /// id accessor - inline uint id () const { return _id ; } - - /// value accessor - inline const Data &operator * () const { return _vec[_id] ; } - - /// value accessor - inline Data &operator * () { return _vec[_id] ; } - - /// accesses the next position - inline iterator &operator ++() { do ++_id ; while( _vec.is_valid(_id) && _vec.is_deleted(_id) ) ; return *this ; } - - //----------------------------------------------------------------------------- - // Elements - private : - mvector &_vec ; ///< data vector - uint _id ; ///< node position - }; - - //------------------------------------------------ - // const_iterator - public : - /// const_iterator - class const_iterator - { - public : - // constructors - /// default constructors - const_iterator( const mvector &vec_, uint id_ = 0 ) : _vec(vec_), _id(id_) {} - - /// destructor - ~const_iterator() {} - - //----------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const const_iterator &it ) const { return &_vec == &it._vec && _id == it._id ; } - /// inequality operator - inline bool operator !=( const const_iterator &it ) const { return &_vec != &it._vec || _id != it._id ; } - - /// validation operator - inline bool operator ()() const { return _vec.is_valid( _id ) ; } - - /// id accessor - inline uint id () const { return _id ; } - - /// value accessor - inline const Data &operator * () const { return _vec[_id] ; } - - /// accesses the next position - inline const_iterator &operator ++() { do ++_id ; while( _vec.is_valid(_id) && _vec.is_deleted(_id) ) ; return *this ; } - - //----------------------------------------------------------------------------- - // Elements - private : - const mvector &_vec ; ///< data vector - uint _id ; ///< node position - }; - - public : - /// Node iterator creation - iterator begin( uint id = 0 ) { return iterator( *this, id ) ; } - /// Node const iterator creation - const_iterator cbegin( uint id = 0 ) { return const_iterator( *this, id ) ; } - -}; -//_____________________________________________________________________________ - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/opt_octree.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/opt_octree.cpp deleted file mode 100644 index 2e2b539ee8..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/opt_octree.cpp +++ /dev/null @@ -1,1121 +0,0 @@ -/** - * \file opt_octree.cpp - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with hashtable and optimized operations - */ -//_____________________________________________________________________________ - - -#ifndef WIN32 -#pragma implementation -#endif // WIN32 - - -#include -#include "opt_octree.h" - -/// invalid key -template<> Hash::KeyData Hash::KD_INV = { KEY_INV, L_INV } ; - - -//_____________________________________________________________________________ -// Create the root -void OptOctree::init() -//----------------------------------------------------------------------------- -{ - _max_field = R_INV ; - _opt_level = L_INV ; - memset( _level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - - HashField::KeyData kd ; - kd.key = 1 ; - kd.data = 0.0 ; - _hash.insert( kd ) ; - - _level_dist[0] = 1 ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -/// Compute the optimal level -void OptOctree::compute_opt_level() -//----------------------------------------------------------------------------- -{ - Level left = 0 ; - Level right = MAX_LEVEL ; - uint leftsum = 0 ; - uint rightsum = 0 ; - while( left < right ) - { - uint leftsum_old = leftsum ; - if( leftsum <= rightsum ) - { - leftsum += _level_dist[ left ] ; - ++left ; - } - if( leftsum_old >= rightsum ) - { - rightsum += _level_dist[ right ] ; - --right ; - } - } - _opt_level = right ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Check that each point scan or scribble is in the right node -bool OptOctree::check () -//----------------------------------------------------------------------------- -{ - bool result = true ; - - uint level_dist[MAX_LEVEL+1] ; - memset( level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - if( is_leaf( it.key() ) ) - level_dist[ key_level(it.key()) ] ++ ; - Key k = it.key() << 3 ; - bool has_son = false ; - bool all_sons = true ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( _hash[ k | i ].key != KEY_INV ) - has_son = true ; - else - all_sons = false ; - } - - if( it.is_leaf() && has_son ) - { - printf("(opt) Invalid leaf %d: value %f\n", (int)k, _hash[k].data ) ; - result = false ; - } - - if( has_son && !all_sons ) - { - printf("(opt) Invalid subdivision %d: value %f\n", (int)k, _hash[k].data ) ; - result = false ; - } - } - - for( Level lv = 0 ; lv <= MAX_LEVEL ; ++lv ) - { - if( _level_dist[lv] != level_dist[lv] ) - { - printf("(opt) Invalid level statistic %d: %d != %d\n", (int)lv, (int)_level_dist[lv], (int)level_dist[lv] ) ; - result = false ; - } - } - - return result ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Deletes the content of the octree -void OptOctree::clear_octree() -//----------------------------------------------------------------------------- -{ - _hash .reset() ; - _verts.reset() ; - _max_field = R_INV ; - _opt_level = L_INV ; - memset( _level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// set the values of each leaf from the implicit function -bool OptOctree::set_impl( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - _max_field = -FLT_MAX ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - if( it.is_leaf() ) - { - real v = (*ref).value_at( it.top() ) ; - *it = v ; - v = fabs(v) ; - if( _max_field < v ) _max_field = v ; - } -// else -// *it = R_INV ; - } - -// printf( "max field: %f\n", max_field() ) ; - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool OptOctree::refine( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - clear() ; init() ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it = geom_root() ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - _hash[it.key()].data = it._field = R_INV ; - HashField::KeyData kd ; - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - s.push( geom_cell( kd.key, kd.data ) ) ; - } - Level lv = it.lv() ; - _level_dist[ lv ] -= 1 ; - _level_dist[lv+1] += 8 ; - } - - compute_opt_level() ; - - return refined ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool OptOctree::adapt( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - -#ifdef HASH_HAS_ERASE - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it = geom_root() ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - geom_cell sons[8] ; - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; -// printf( "opt key %d\n", (int) it.key() ) ; - - // look for the leaves - if( !it.is_leaf() ) - { - if( !(*ref).need_refine( it ) ) - { - std::stack< std::pair > del_s ; // avoid level recomputation - del_s.push( std::make_pair( it.key(), it.lv() ) ) ; - while( !del_s.empty() ) - { - Key n = del_s.top().first << 3 ; - Level lv = del_s.top().second + 1 ; - del_s.pop() ; - - for( int i = 0 ; i < 8 ; ++i ) - { - HashField::KeyData kd = _hash.erase( n|i ) ; - if( !is_inv( kd.data ) ) // is_leaf(n) - { - _level_dist[ lv ] -- ; - continue ; - } - del_s.push( std::make_pair( n|i, lv ) ) ; - } - } - - refined = true ; - _level_dist[it.lv()] += 1 ; - _hash[it.key()].data = 0.0 ; // leaf now! - continue ; - } - - it.sons( sons, _hash ) ; - for( int i = 0 ; i < 8 ; ++i ) - s.push( sons[i] ) ; - - continue ; - } - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - _hash[it.key()].data = it._field = R_INV ; - HashField::KeyData kd ; - kd.data = 0.0 ; - - // recurse on the traversal - Key sk = it.key() << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - kd.key = sk | i ; - if( !_hash.insert( kd ) ) - { - printf( "hash table saturated!\n" ) ; - exit(1) ; - return false ; - } - - s.push( geom_cell( kd.key, kd.data ) ) ; - } - - Level lv = it.lv() ; - _level_dist[ lv ] -= 1 ; - _level_dist[lv+1] += 8 ; - } - - compute_opt_level() ; - return refined ; - -#else // HASH_HAS_ERASE - // no remotion in the hash table! - return refine( ref ) ; -#endif // HASH_HAS_ERASE -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with wireframe -bool OptOctree::draw_wire() -//----------------------------------------------------------------------------- -{ - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - it.draw_wire() ; - - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with dots -bool OptOctree::draw_centers() -//----------------------------------------------------------------------------- -{ - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - ::glTexCoord1f( (GLfloat)fabs(*it / max_field()) ) ; - it.top().draw() ; - } - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Compute primal vertices -bool OptOctree::compute_primal_verts() -//----------------------------------------------------------------------------- -{ - - // add all the inner vertices - for( leaf_iterator l_it = leaves_begin() ; l_it() ; ++l_it ) - { - Key verts_k[8] ; - Level lv = vertices_keys( l_it.key(), verts_k ) ; - - HashVerts::KeyData kd ; - kd.data = lv ; - Key *v_ptr = verts_k ; - for( int i = 0 ; i < 8 ; ++i, ++v_ptr ) - { - kd.key = *v_ptr ; - if( kd.key == KEY_INV ) continue ; - - HashVerts::KeyData &hk = _verts[ kd.key ] ; - if( hk.key == KEY_INV ) - _verts.insert( kd ) ; - else if( hk.data < kd.data ) - hk.data = kd.data ; - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Octree dual caller -bool OptOctree::dual_cubes_walk( opt_dual_walker &walker ) -//----------------------------------------------------------------------------- -{ - bool result = compute_primal_verts() ; - - for( HashVerts::const_iterator v_it = _verts.cbegin() ; v_it() ; ++v_it ) - { - const Level lv = *v_it ; - Key dual_verts[8] ; - dual_vertices_keys( v_it.key(), lv, dual_verts ) ; - - Key *dv_ptr = dual_verts ; - for( int i = 0 ; i < 8 ; ++i, ++dv_ptr ) - { - // find_at, only the level too high case - Key &ki = *dv_ptr ; - HashField::KeyData kd ; - while( ki != 0 && !node_exists(ki,kd) ) - ki >>= 3; - } - result &= walker( *this, dual_verts ) ; - } - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Isosurface walker -bool opt_isosurface_walker( OptOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MarchingCubes &mc = fo.mc() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - /** indexes of the cube */ - Key *indexes = mc.indexes() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const Key k = keys[j] ; - OptOctree::geom_cell c = fo.geom_key(k) ; - cube[i] = *c ; - - space[i] = (Point)c ; - indexes[i] = k ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool OptOctree::build_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc.dat_access() = ref ; - _verts.reset() ; - - printf( "Build isosurface... " ) ; - bool result = false ; - - //_________________________________________________________________________ - // Dual Marching Cubes - - _mc.init_all() ; - - result = dual_cubes_walk( opt_isosurface_walker ) ; - - _mc.clean_temps() ; - - printf( "generated %d vertices and %d faces!\n", _mc.nverts(), _mc.ntrigs() ) ; - - return result ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Isosurface drawing walker -bool opt_direct_isosurface_walker( OptOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - MC_Draw &mc = fo.mc_draw() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const OptOctree::geom_cell c = fo.geom_key( keys[j] ) ; - cube[i] = *c ; - - space[i] = (Point)c ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool OptOctree::direct_draw_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc_draw.dat_access() = ref ; - _verts.reset() ; - - bool result = false ; - - // Dual Marching Cubes - ::glBegin( GL_TRIANGLES ) ; - { - result = dual_cubes_walk( opt_direct_isosurface_walker ) ; - } - ::glEnd() ; // GL_TRIANGLES - - return result ; -} -//_____________________________________________________________________________ - - - - - - -//_____________________________________________________________________________ -// Draw walker -bool opt_draw_walker( OptOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - Cube cells[8] ; - for( int i = 0 ; i < 8 ; ++i ) - cells[i] = key2cube( keys[i] ) ; - - ((Point)cells[0]).draw() ; - ((Point)cells[1]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[3]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[2]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[0]).draw() ; - - ((Point)cells[4]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[5]).draw() ; - ((Point)cells[7]).draw() ; - - ((Point)cells[7]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[6]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[0]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[7]).draw() ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Draw the dual octree with wireframe -bool OptOctree::draw_dual() -//----------------------------------------------------------------------------- -{ - _verts.reset() ; - - ::glBegin( GL_LINES ) ; - bool result = dual_cubes_walk( opt_draw_walker ) ; - ::glEnd() ; // GL_LINES - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Do nothing walker, just for dual generation timing -bool opt_timing_walker( OptOctree &fo, Key *keys ) -//----------------------------------------------------------------------------- -{ - return true ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Do nothing, just for dual generation timing -bool OptOctree::dual_timing() -//----------------------------------------------------------------------------- -{ - _verts.reset() ; - - return dual_cubes_walk( opt_timing_walker ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Prints statistics about the octree -void OptOctree::stats() const -//----------------------------------------------------------------------------- -{ - int s = _hash.size() ; - printf( " number of nodes:\t%d\n", s ) ; -#if USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyBucket) ) ) ; - _hash.stats() ; -#else // USE_HASH_PTR - printf( " total memory:\t%d\n", (int) ( s * sizeof(HashField::KeyData ) ) ) ; -#endif // USE_HASH_PTR - - printf( " leaves' levels:\t" ) ; - for( Level l = 0 ; l <= MAX_LEVEL; ++l ) - printf( "\t%d", _level_dist[l] ) ; - printf( "\n" ) ; - - s = _verts.size() ; - printf( " number of dual nodes:\t%d\n", s ) ; -#if USE_HASH_PTR - printf( " total memory of dual:\t%d\n", (int) ( s * sizeof(HashVerts::KeyBucket) ) ) ; - _verts.stats() ; -#else // USE_HASH_PTR - printf( " total memory of dual:\t%d\n", (int) ( s * sizeof(HashVerts::KeyData ) ) ) ; -#endif // USE_HASH_PTR -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// search operations - - -//_____________________________________________________________________________ -// Find cells of the octree at a given position -bool OptOctree::find_leaf( Key k, Level o_lv, geom_cell &n ) const -//----------------------------------------------------------------------------- -{ - - Level shift = 3*(MAX_LEVEL-o_lv) ; - Key ki = k >> shift ; - HashField::KeyData kd ; - - // level too high - if( !node_exists(ki,kd) ) - { - do - { - ki >>= 3; - } - while( ki !=0 && !node_exists(ki,kd) ) ; - } - // level correct or too low - else - { - HashField::KeyData kd_temp ; - do - { - kd_temp = kd ; - shift -= 3 ; - ki = k >> shift ; - } - while( ki !=0 && node_exists(ki,kd) ) ; - kd = kd_temp ; - } - n = geom_cell( kd ) ; - - return kd.key != KEY_INV ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find cells of the octree inside a given box of center x,y and half side r -bool OptOctree::find_radius( real x, real y, real z, real r, List &cells ) const -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - Level lv_b = (Level)floor( log(r)/log(0.5) ) ; - Key k_b = cube2key( Cube(x,y,z,lv_b) ) ; - - Key neighbors[27] ; - neighbor_keys( k_b, neighbors ) ; - - std::stack s ; - s.push( k_b ) ; - - Key *k_ptr = neighbors ; - for( int dir = 0 ; dir < 27 ; ++dir, ++k_ptr ) - s.push( *k_ptr ) ; - - while( !s.empty() ) - { - Key ki = s.top() ; - s.pop() ; - if( ki == KEY_INV ) continue ; - - HashField::KeyData kd ; - if( node_exists(ki,kd) ) - { - if( is_leaf( kd ) ) - { - geom_cell gc(kd) ; - real sz = gc.sz() + r ; - - // test directly with the key? - if( fabs( x-gc.x() ) <= sz && fabs( y-gc.y() ) <= sz && fabs( z-gc.z() ) <= sz ) - cells.insert( gc ) ; - } - else - { - Key ski = ki << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - // test directly with the key before insertion? - s.push( ski | i ) ; - } - } - else - { - HashField::KeyData kd ; - do - { - ki >>= 3 ; - } while( ki !=0 && !node_exists(ki,kd) ) ; - - if( ki > 0 ) - { - geom_cell gc(kd) ; - real sz = gc.sz() + r ; - - // test directly with the key? - if( fabs( x-gc.x() ) <= sz && fabs( y-gc.y() ) <= sz && fabs( z-gc.z() ) <= sz ) - cells.insert_unique( gc ) ; - } - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find neighbor cells of the octree to a given cell -bool OptOctree::adjacent( Key k, List &cells ) const -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - Key neighbors[27] ; - neighbor_keys( k, neighbors ) ; - - Key *k_ptr = neighbors ; - for( int dir = 0 ; dir < 27 ; ++dir, ++k_ptr ) - { - Key ki = *k_ptr ; - if( ki == KEY_INV ) continue ; - - HashField::KeyData kd ; - if( node_exists(ki,kd) ) - { - if( is_leaf( kd ) ) cells.insert( geom_cell(kd) ); - else - { - std::stack subneighbors ; - subneighbor_keys(ki, dir, subneighbors ) ; - while( !subneighbors.empty() ) - { - Key ski = subneighbors.top() ; - subneighbors.pop() ; - - real sdi ; - if( is_leaf( ski, sdi ) ) - cells.insert( geom_cell( ski, sdi ) ) ; - else - subneighbor_keys(ski, dir, subneighbors ) ; - } - } - } - else - { - HashField::KeyData kd ; - do - { - ki >>= 3 ; - } while( ki !=0 && !node_exists(ki,kd) ) ; - - if( ki > 0 ) - cells.insert_unique( geom_cell(kd) ) ; - } - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// I/O - -//_____________________________________________________________________________ -// Draws the intersecting cells of a plane with the octree with color -void OptOctree::draw_plane ( real nx, real ny, real nz, real d ) -//----------------------------------------------------------------------------- -{ - geom_cell n = geom_root() ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - //_____________________________________________________________________________ - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - //_____________________________________________________________________________ - - ::glLineWidth( 1.0f ) ; - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - - if( n.is_leaf() ) - { - - ::glTexCoord1f( (GLfloat)fabs(*n/max_field()) ) ; - ::glBegin( GL_LINES ) ; - n.draw_wire() ; - ::glEnd() ; // GL_LINES - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons, _hash ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draws the intersection of a plane with the octree with color -void OptOctree::draw_slice ( real nx, real ny, real nz, real d, float alpha ) -//----------------------------------------------------------------------------- -{ - geom_cell n = geom_root() ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - - - //_____________________________________________________________________________ - - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - if( n.is_leaf() ) - { - // retrieves the signs of each cube corner - real val[8] ; - real v = nx * n.cx() + ny * n.cy() + nz * n.cz() + d ; - real sz_ = n.sz() ; - int zeros = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - val[i] = v + nx * ((i&1)?sz_:-sz_) + ny * ((i&2)?sz_:-sz_) + nz * ((i&4)?sz_:-sz_) ; - if( fabs(val[i]) < R_EPSILON ) { val[i] = R_EPSILON ; ++zeros ; } - } - - //_________________________________________________________________________ - // degenerated intersection - if( zeros > 0 ) - { - int npos = 0, nneg = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) continue ; - if( val[i] < 0 ) - ++nneg ; - else - ++npos ; - } - float def = (nneg>npos) ? (float)R_EPSILON : -(float)R_EPSILON ; - - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) val[i] = def ; - } - // continue ; - } - - //_________________________________________________________________________ - // Continuation method - int v0=-1, v1=-1 ; // current edge vertices - - // get the first intersection - static int edges[12][2] = { {0,1}, {0,2}, {0,4}, {1,3}, {1,5}, {2,3}, {2,6}, {3,7}, {4,5}, {4,6}, {5,7}, {6,7} } ; - for( int e = 0 ; e < 12 ; ++e ) - { - if( val[ edges[e][0] ] * val[ edges[e][1] ] < 0 ) - { - v0 = edges[e][0] ; - v1 = edges[e][1] ; - break ; - } - } - int ov0 = v0, ov1 = v1 ; - - - // equation of previous face adjacent to v0v1: v>>c & 1 == s (c-th coordinate equal to +/- 1) - int pf = -1 ; bool ps ; - if ( (v0 & 1) == (v1 & 1) ) { pf = 0 ; ps = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( (v0 & 2) == (v1 & 2) ) { pf = 1 ; ps = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( (v0 & 4) == (v1 & 4) )*/ { pf = 2 ; ps = ((v0 & 4) >> 2 ) == 1 ; } - - // printf( "cube %d %d %d %d %d %d %d %d, march : (%d,%d) ", val[0]>0, val[1]>0, val[2]>0, val[3]>0, val[4]>0, val[5]>0, val[6]>0, val[7]>0, v0, v1 ) ; - - //_________________________________________________________________________ - // marching - - GLfloat color = (GLfloat)fabs(*n / max_field()) ; - //cmap.gl_color( at(*n) ) ; - ::glBegin( GL_POLYGON ) ; - { - do - { - // equation of next face adjacent to v0v1 - int nf = -1 ; bool ns ; - if ( pf != 0 && ((v0 & 1) == (v1 & 1)) ) { nf = 0 ; ns = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( pf != 1 && ((v0 & 2) == (v1 & 2)) ) { nf = 1 ; ns = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( pf != 2 && ((v0 & 4) == (v1 & 4)) )*/ { nf = 2 ; ns = ((v0 & 4) >> 2 ) == 1 ; } - - /* equivalent construction - // get the direction perpendicular to v0v1 - int of = (v0 ^ v1) & 7 ; // only bit of difference - of = of==1 ? 0 : (of==2 ? 1 : 2) ; - - // compute the equation of the next face adjacent to v0v1 - int nf = 3 - (pf+of) ; // third option: {pf,nf,of}={0,1,2} - bool ns = (v0 >> nf) & 1 ; // value of the edge on that direction - */ - - // compute the two next vertices (invert the pf-th bit - int v2 = ps ? ( v0 & (~(1< 0) | ((val[v2] > 0) << 1) | ((val[v1] > 0) << 2) | ((val[v0] > 0) << 3) ; - if( c > 7 ) c = (~c)&7 ; // consider v0 as negative, and thus v1 as positive - /* - if( c < 4 ) - { // degenerated intesection - printf( "degenerated intersection %d!\n", c ) ; - } - */ - - //_______________________________________________________________________ - // method of continuity on the cube surface - switch( c ) - { - case 4 : v0 = v3 ; break ; - case 5 : v0 = v2 ; v1 = v3 ; break ; - case 6 : /* impossible case */ break ; - case 7 : v1 = v2 ; break ; - } - - - - - real cx = n.cx(); - real cy = n.cy(); - real cz = n.cz(); - real sz = sz_; - real a0 = val[v0]; - int i0 = v0; - real a1 = val[v1]; - int i1 = v1; - - real w0 = a1 / (a1-a0) ; - real w1 = a0 / (a0-a1) ; - - real x = cx + w0 * ((i0&1)?sz:-sz) + w1 * ((i1&1)?sz:-sz); - real y = cy + w0 * ((i0&2)?sz:-sz) + w1 * ((i1&2)?sz:-sz); - real z = cz + w0 * ((i0&4)?sz:-sz) + w1 * ((i1&4)?sz:-sz); - - ::glTexCoord1d( color ) ; - ::glVertex3d(x, y, z) ; - - // next face - pf = nf ; ps = ns ; - - // printf( "(%d,%d) ", v0, v1 ) ; - } while( v0 != ov0 || v1 != ov1 ) ; - // printf( "\n" ) ; - } - ::glEnd() ; // GL_POLYGON - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons, _hash ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/opt_octree.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/opt_octree.h deleted file mode 100644 index e6a90e93b0..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/opt_octree.h +++ /dev/null @@ -1,376 +0,0 @@ -/** - * \file opt_octree.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with hashtable and optimized operations - */ -//_____________________________________________________________________________ - - -#pragma once - - -#ifndef WIN32 -#pragma interface -#endif // WIN32 - - -#include "mlist.h" -#include "cube.h" -#include "hash.h" -#include "MarchingCubes.h" -#include "mc_draw.h" -#include "data_access.h" - - - -//_____________________________________________________________________________ -// OptOctree -/// \class OptOctree OptOctree.h -class OptOctree -//----------------------------------------------------------------------------- -{ -// forward declaration -public: - class geom_cell ; - class cell_iterator ; - class leaf_iterator ; - -// Elements -protected: - /// Octree cell data structure - typedef Hash HashField ; - - /// Hashtable of the octree nodes - HashField _hash ; - - /// Level distribution of the octree - uint _level_dist[MAX_LEVEL+1] ; - - /// Optimal level for direct search in the octree - Level _opt_level ; - - /// Maximal field of the octree - real _max_field ; - - /// Isosurface - MarchingCubes _mc ; - - /// Isosurface Draw - MC_Draw _mc_draw ; - -private : - /// Octree vertices data structure - typedef Hash HashVerts ; - /// Hashtable of the octree vertices - HashVerts _verts ; - -//----------------------------------------------------------------------------- -// Constructors -public: - /// Default constructor: Constructs a octree with and empty root - OptOctree() { init() ; } - - /// Destructor: Free memory - ~OptOctree() { clear() ; } - - - /// Create the root - void init() ; - - /// Memory cleaning - void clear() { clear_octree() ; _mc.clean_all() ; } - - /// Delete the content of the octree - void clear_octree() ; - - /// Compute the optimal level - void compute_opt_level() ; - - /// Check that only the leaves have data - bool check () ; - - /// Prints statistics about the octree - void stats() const ; - - /// Return the maximal level of the octree - Level max_level() const { Level lv = MAX_LEVEL ; while( lv > 0 && !_level_dist[lv] ) --lv ; return lv ; } - - /// Return the optimal level of the octree - Level opt_level() const { return _opt_level ; } - - /// Return the optimal level of the octree - Level &opt_level() { return _opt_level ; } - - /// Return the maximal field of the octree - real max_field() const { return _max_field ; } - - /// Return the isosurface - MarchingCubes &mc() { return _mc ; } - - /// Return the isosurface draw - MC_Draw &mc_draw() { return _mc_draw ; } - - /// set the values of each leaf from the implicit function - bool set_impl( data_access *ref = NULL ) ; - - /// Refine the octree according to the data access - bool refine( data_access *ref = NULL ) ; - - /// Adapt the octree according to the data access - bool adapt( data_access *ref = NULL ) ; - - /// Draw the octree with wireframe - bool draw_wire() ; - - /// Draw the octree with dots - bool draw_centers() ; - - /// Dual function type - typedef bool opt_dual_walker( OptOctree &fo, Key *keys ) ; - - /// Compute primal vertices - bool compute_primal_verts() ; - - /// Walk on the dual cubes - bool dual_cubes_walk( opt_dual_walker &walker ) ; - - /// Build the isosurface using dual marching cubes - bool build_isosurface( data_access *ref = NULL ) ; - - /// Draw the isosurface on-the-fly using dual marching cubes - bool direct_draw_isosurface( data_access *ref = NULL ) ; - - /// Draw the dual octree with wireframe - bool draw_dual() ; - - /// Do nothing, just for dual generation timing - bool dual_timing() ; - -//----------------------------------------------------------------------------- -// iterators -public: - /// Create an iterator traversing the tree from the root - inline cell_iterator cells_begin() { return cell_iterator( *this ) ; } - - /// Create an iterator traversing the leaves of the tree from the root - inline leaf_iterator leaves_begin() { return leaf_iterator( *this ) ; } - -//----------------------------------------------------------------------------- -// search operations -public: - /// Find cells of the octree at a given position - bool find_leaf( Key k, Level o_lv, geom_cell &cell ) const ; - bool find_leaf( Key k, geom_cell &cell ) const { return find_leaf( k, opt_level(), cell ) ; } - bool find_leaf( real x, real y, real z, geom_cell &cell ) const { return find_leaf( cube2key( Cube(x,y,z,MAX_LEVEL) ), opt_level(), cell ) ; } - - /// Find cells of the octree inside a given box of center x,y,z and half side r - bool find_radius( real x, real y, real z, real r, List &cells ) const ; - - /// Find adjacent cells of the octree to a given cell - bool adjacent( Key k, List &cells ) const ; - bool adjacent( const geom_cell &cell, List &cells ) const { return adjacent( cell.key(), cells ) ; } - - /// Leaf test based on the field value - bool is_leaf( const HashField::KeyData &kd ) const { return !is_inv( kd.data ) ; } - - /// Leaf test based on the field value - bool is_leaf( Key k, real &d ) const { const HashField::KeyData &kd = _hash[k] ; d = kd.data ; return is_leaf( kd ) ; } - - /// Leaf test based on the field value - bool is_leaf( Key k ) const { return is_leaf( _hash[k] ) ; } - - /// Node existence - bool node_exists( Key k, HashField::KeyData &kd ) const { kd = _hash[k] ; return kd.key != KEY_INV ; } - - //----------------------------------------------------------------------------- -// I/O -public: - - /// Draws the intersecting cells of a plane with the octree with color - void draw_plane ( real nx, real ny, real nz, real d ) ; - - /// Draws the intersection of a plane with the octree with color - void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ; - - /// Draws the isosurface of level l inside the dual graph - void draw_iso () { _mc.draw_surf() ; } - -//_____________________________________________________________________________ -// Iterator Cell -public : - /// Auxiliary structure to traverse the octree - class geom_cell : public Cube - //--------------------------------------------------------------------------- - { - friend class OptOctree ; - - protected: - Key _key ; ///< octree cell - real _field ; ///< field associated to the cell - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor - geom_cell( Key key_ = KEY_INV, real field_ = R_INV ) : Cube(key2cube(key_)), _key(key_), _field(field_) {} - - /// Default constructor - geom_cell( HashField::KeyData kd ) : Cube(key2cube(kd.key)), _key(kd.key), _field(kd.data) {} - - /// Destructor - ~geom_cell() {} - - /// Copy constructor - geom_cell( const geom_cell &i ) : Cube(i), _key(i._key), _field(i._field) {} - - /// Assignment operator - geom_cell &operator = ( const geom_cell &i ) - { Cube::operator=(i) ; _key = i._key ; _field = i._field ; return *this; } - - - //--------------------------------------------------------------------------- - // Public constant accessors - public : - /// key const accessor - inline Key key() const { return _key ; } - /// key accessor - inline Key &key() { return _key ; } - - /// id const accessor - inline real operator*() const { return _field ; } - - //--------------------------------------------------------------------------- - // Tests - public : - /// equality operator - inline bool operator ==( const geom_cell &i ) const { return key() == i.key() ; } - - /// inequality operator - inline bool operator !=( const geom_cell &i ) const { return key() != i.key() ; } - - /// leaf test - inline bool is_leaf() const { return !is_inv(*(*this)) ; } - - /// validation operator - inline bool operator ()() const { return key() != KEY_INV ; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// sons - inline bool sons( geom_cell *s /*[8]*/, const HashField &hash ) - { - if( is_leaf() ) return false ; - - Key k = _key << 3 ; - for( int i = 0 ; i < 8 ; ++i ) - { - s[i]._key = k | i ; - s[i]._field = hash[k|i].data ; - (Cube&)s[i] = key2cube(s[i]._key) ; - } - return true ; - } - }; - - const geom_cell geom_root() const { const Key root_key = 1 ; return geom_cell( root_key, _hash[root_key].data ) ; } - const geom_cell geom_key ( Key k ) const { return geom_cell( k, _hash[k].data ) ; } - - - -//_____________________________________________________________________________ -// Cell Iterator -public : - /// Octree cell iterator : Traverse the octree returning basic information on the cells - class cell_iterator - //--------------------------------------------------------------------------- - { - friend class OptOctree ; - - protected: - /// Octree traversal iterator - HashField::iterator _it ; - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor : Constructs an iterator from a cell - cell_iterator( OptOctree &o ) : _it( o._hash.begin() ) {} - - /// Destructor - ~cell_iterator() {} - - /// Copy constructor - cell_iterator( const cell_iterator &i ) : _it(i._it) {} - - /// Assignment operator - cell_iterator &operator = ( const cell_iterator &i ) - { _it = i._it; return *this; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// equality operator - inline bool operator ==( const cell_iterator &i ) const { return _it == i._it ; } - - /// inequality operator - inline bool operator !=( const cell_iterator &i ) const { return _it != i._it ; } - - /// validation operator - inline bool operator ()() const { return _it() ; } - - /// next position - inline cell_iterator &operator ++() { ++_it ; return *this ; } - - //--------------------------------------------------------------------------- - // Accessors - public : - // cell accessor - inline geom_cell top() const { return geom_cell( key(), *_it ) ; } - - /// id accessor - inline real &operator*() { return *_it ; } - - /// level accessor - inline Level lv() { return key_level(_it.key()) ; } - - /// size accessor - inline real sz() { return Cube(0,0,0,lv()).sz() ; } - - /// key accessor - inline Key key() const { return _it.key() ; } - - /// points accessor - inline bool is_leaf() const { return !is_inv(*_it) ; } - - /// Draws the cell wire with opengl - void draw_wire () const { top().draw_wire () ; } - - }; - - - /// Octree leaf iterator : Traverse the octree returning basic information on the leaves - class leaf_iterator : public cell_iterator - //--------------------------------------------------------------------------- - { - public : - leaf_iterator( OptOctree &o ) : cell_iterator( o ) - { if( (*this)() && !this->is_leaf() ) ++(*this) ; } - - - /// next position - inline leaf_iterator &operator ++() - { - cell_iterator &it = *this ; - do ++it ; while ( it() && !it.is_leaf() ) ; - return *this ; - } - } ; -} ; -//_____________________________________________________________________________ - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/perf_main.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/perf_main.cpp deleted file mode 100644 index 17c64fd125..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/perf_main.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/** - * \file perf_main.cpp - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree performances test - */ -//_____________________________________________________________________________ - - -/* -with pointers - level 10,12: hash 27, non hash 31 - level 8: hash 27, non hash 37 - -without pointers - level 10: hash 21, non hash 31 - level 8: hash 21, non hash 37/40 -*/ - - -#define OCTREE_SWITCH 2 - -#ifdef OCTREE_SWITCH -# if OCTREE_SWITCH==0 -# define OCTREE_PTR 1 -# elif OCTREE_SWITCH==1 -# define OCTREE_HASH 1 -# elif OCTREE_SWITCH==2 -# define OCTREE_OPT 1 -# elif OCTREE_SWITCH==3 -# define OCTREE_LEAF 1 -# elif OCTREE_SWITCH==4 -# define OCTREE_MEM 1 -# endif // OCTREE_SWITCH -#endif // OCTREE_SWITCH - - -// switch values between pointer and hash octree -#if !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM -// # define OCTREE_PTR 1 -// # define OCTREE_HASH 1 -# define OCTREE_OPT 1 -// # define OCTREE_LEAF 1 -// # define OCTREE_MEM 1 -#endif // !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM - - -#ifdef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_OPT -# undef OCTREE_LEAF -# undef OCTREE_MEM -# define OCTREE_STRING "0 pointer" -# include "ptr_octree.h" - /// octree type - typedef PtrOctree Octree ; -#endif //OCTREE_PTR - - -#ifdef OCTREE_HASH -# undef OCTREE_PTR -# undef OCTREE_OPT -# undef OCTREE_LEAF -# undef OCTREE_MEM -# define OCTREE_STRING "1 hash" -# include "hash_octree.h" - /// octree type - typedef HashOctree Octree ; -#endif //OCTREE_HASH - - -#ifdef OCTREE_OPT -# undef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_LEAF -# undef OCTREE_MEM -# define OCTREE_STRING "2 opt" -# include "opt_octree.h" - /// octree type - typedef OptOctree Octree ; -#endif //OCTREE_OPT - - -#ifdef OCTREE_LEAF -# undef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_OPT -# undef OCTREE_MEM -# define OCTREE_STRING "3 leaf" -# include "leaf_octree.h" -/// octree type -typedef LeafOctree Octree ; -#endif //OCTREE_LEAF - - -#ifdef OCTREE_MEM -# undef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_OPT -# undef OCTREE_LEAF -# define OCTREE_STRING "4 mem" -# include "mem_octree.h" -/// octree type -typedef MemOctree Octree ; -#endif //OCTREE_MEM - - -#ifndef NPOINTS -# define NPOINTS 100 -#endif // NPOINTS - -#ifndef RADIUS -# define RADIUS (0.003f) -#endif // RADIUS - -#ifndef NDUALS -# define NDUALS 10 -#endif // NDUALS - -#ifndef MLEVEL -# define MLEVEL 5 -#endif // MLEVEL - -#ifndef IMPLFUN // set to 0 for random -# define IMPLFUN 1 -#endif // IMPLFUN - -#ifndef ISOVAL -# define ISOVAL 0.5 -#endif // ISOVAL - - -#include "hash.h" -#include "implfuns.h" -#include - -//_____________________________________________________________________________ -// -int main( int argc , char* argv[] ) -//----------------------------------------------------------------------------- -{ -#if OCTREE_LEAF && !USE_HASH_PTR - return 0 ; -#endif // OCTREE_LEAF && !USE_HASH_PTR - - srand(77) ; -// Chrono::ResetClocks() ; - - printf( "\n\n\n-----------------------------------------------------------------------------\n" - OCTREE_STRING - "\n\thash\t%s\tpointers\n" - "\thash bits =\t%d\n" - "\tnon hash bits=\t%d\n" - "\tmax_level =\t%d\n" - "\tdensity =\t%f\n" - "\tnpoints =\t%d\n" - "\tradius =\t%f\n" - "\timplicit function =\t%s\n" - "\tisovalue =\t%f\n" - "\tnumber of duals=\t%d\n\n", - (USE_HASH_PTR ? "with" : "without"), HASH_BITS, NON_HASH_BITS, MLEVEL, RAND_THRES, NPOINTS, RADIUS, fun_list[IMPLFUN], ISOVAL, NDUALS ) ; - fflush(stdout); - - /// main data structure - Octree octree ; -#if IMPLFUN==0 - data_rand ref( MLEVEL ) ; - octree.refine( &ref ) ; -#else // IMPLFUN - data_func ref( MLEVEL, ISOVAL, fun_def[IMPLFUN] ) ; - octree.refine( &ref ) ; - octree.set_impl( &ref ) ; -#endif // IMPLFUN - fflush(stdout); - - -/* - //------------------------------------------------- - // search for random points - Chrono::ResetClocks() ; - printf( "\n\nRandom Points\n" ) ; - for( int i = 0 ; i < NPOINTS ; ++i ) - { - real x = (real)rand()/(real)RAND_MAX; - real y = (real)rand()/(real)RAND_MAX; - real z = (real)rand()/(real)RAND_MAX; - Octree::geom_cell gc ; - List gc_list ; - octree.find_leaf( x,y,z, gc ) ; - octree.find_radius( x,y,z, RADIUS, gc_list ) ; gc_list.clear() ; - octree.adjacent( gc, gc_list ) ; gc_list.clear() ; - } - Chrono::PrintClocks() ; - fflush(stdout); - //------------------------------------------------- - - - //------------------------------------------------- - // search for all leaves once - printf( "\nLeaves\n" ) ; - Chrono::ResetClocks() ; - for( Octree::leaf_iterator it = octree.leaves_begin() ; it() ; ++it ) - { - Octree::geom_cell g_it = it.top() ; - Octree::geom_cell gc ; - List gc_list ; - octree.find_leaf( g_it.cx(), g_it.cy(), g_it.cz(), gc ) ; - octree.find_radius( g_it.cx(), g_it.cy(), g_it.cz(), RADIUS, gc_list ) ; gc_list.clear() ; - octree.adjacent( gc, gc_list ) ; gc_list.clear() ; - } - Chrono::PrintClocks() ; - fflush(stdout); - //------------------------------------------------- - - - //------------------------------------------------- - // search for all points at the maximal level - printf( "\n\nGrid\n" ) ; - Level lv = octree.max_level() - 4 ; - real step = 1.0 / (1 << lv) ; - Chrono::ResetClocks() ; - for( real x = 0.0 ; x <= 1.0 ; x += step ) - { - for( real y = 0.0 ; y <= 1.0 ; y += step ) - { - for( real z = 0.0 ; z <= 1.0 ; z += step ) - { - Octree::geom_cell gc ; - List gc_list ; - octree.find_leaf( x,y,z, gc ) ; - octree.find_radius( x,y,z, RADIUS, gc_list ) ; gc_list.clear() ; - octree.adjacent( gc, gc_list ) ; gc_list.clear() ; - } - } - } - Chrono::PrintClocks() ; - fflush(stdout); - //------------------------------------------------- -*/ - - //------------------------------------------------- - // build many duals - printf( "\n\nDuals\n" ) ; -// Chrono::ResetClocks() ; - for( int i = 0 ; i < NDUALS ; ++i ) - { -#if IMPLFUN==0 - octree.dual_timing() ; -#else // IMPLFUN - octree.mc().clean_all() ; - octree.build_isosurface(&ref) ; -#endif // IMPLFUN - } -// Chrono::PrintClocks() ; - octree.stats() ; - fflush(stdout); - //------------------------------------------------- - - - return 0; -} -//_____________________________________________________________________________ - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/point.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/point.h deleted file mode 100644 index c2e82b863b..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/point.h +++ /dev/null @@ -1,289 +0,0 @@ -/** - * \file point.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * \brief (Point/Vector Class). - */ -/**------------------------------------------------------------------------------------*/ - - -#pragma once - -#include -#include // FLT_EPSILON -#include // nan -#ifdef UNIX -#include -#else -#include -#endif - - - -//------------------------------------------------ -/** real number type */ -typedef float real ; -typedef const real creal ; -#define R_PI ((creal)3.1415926535897932384626433832795) -#define R_EPSILON ((real)FLT_EPSILON) -inline bool is_inv( real x ) { return isnan(x) ; } -extern real R_INV ; - -/** integer number aliases */ -typedef signed char schar ; -typedef unsigned char uchar ; -typedef unsigned int uint ; -typedef const int cint ; -typedef const uint cuint ; - -/** \brief Axis Definition */ -enum Axis { X = 0, Y = 1, Z = 2 } ; -//------------------------------------------------ - - -/** \brief point with normal */ -class Point - { - protected : - real _x, _y, _z ; - - public : - Point() : _x(R_INV), _y(R_INV), _z(R_INV) {} - Point( creal x_, creal y_, creal z_ ) : _x(x_), _y(y_), _z(z_) {} - Point( const Point &p_ ) : _x(p_._x), _y(p_._y), _z(p_._z) {} - Point &operator = ( const Point &p_ ) - { _x=p_._x ; _y=p_._y ; _z=p_._z ; return *this; } - - - public : - inline real &x() { return _x ; } - inline real &y() { return _y ; } - inline real &z() { return _z ; } - inline creal x() const { return _x ; } - inline creal y() const { return _y ; } - inline creal z() const { return _z ; } - - inline creal &operator[] ( Axis a ) const - { switch( a ) { - case X : return _x ; - case Y : return _y ; - case Z : return _z ; - default: return R_INV ; - } } - inline real &operator[] ( Axis a ) - { switch( a ) { - case X : return _x ; - case Y : return _y ; - case Z : return _z ; - default: return R_INV ; - } } - - /**------------------------------------------------------------------------------------*/ - inline bool valid() - { - return - ( !is_inv( x() ) ) && - ( !is_inv( y() ) ) && - ( !is_inv( z() ) ) ; - } - inline bool invalid() - { - return - ( is_inv( x() ) ) || - ( is_inv( y() ) ) || - ( is_inv( z() ) ) ; - } - - - /**------------------------------------------------------------------------------------*/ - // Basic operations - - /// += - inline Point &operator+= ( const Point &p_ ) - { - x() += p_.x() ; y() += p_.y() ; z() += p_.z() ; - return *this ; - } - /// unary - - inline const Point operator- () - { - x() = -x() ; y() = -y() ; z() = -z() ; - return *this ; - } - /// -= - inline Point &operator-= ( const Point &p_ ) - { - x() -= p_.x() ; y() -= p_.y() ; z() -= p_.z() ; - return *this ; - } - /// *= scalar - inline Point &operator*= ( const real l ) - { - x() *= l ; y() *= l ; z() *= l ; - return *this ; - } - /// /= scalar - inline Point &operator/= ( const real l ) - { - if( fabs(l) < R_EPSILON ) return *this ; - real s = 1.0/l ; - return *this *= s ; - } - - - /**------------------------------------------------------------------------------------*/ - // Norms - inline real length () const - { - return hypot( hypot( x(), y() ), z() ) ; - } - inline real norm () const { return length() ; } - inline real dist ( const Point &p_ ) const { Point r = *this ; r -= p_ ; return r.length() ; } - - inline bool operator== ( const Point &p_ ) const { return dist( p_ ) < R_EPSILON ; } - inline bool operator!= ( const Point &p_ ) const { return !( *this == p_ ) ; } - - inline bool normalize() - { - real l = length() ; - if( l < R_EPSILON ) return false ; - *this /= l ; - return true ; - } - - /** replaces p by the by-coordinate minimum of p and p_ */ - inline void pmin( const Point &p_ ) - { - if( x() > p_.x() ) x() = p_.x() ; - if( y() > p_.y() ) y() = p_.y() ; - if( z() > p_.z() ) z() = p_.z() ; - } - - /** replaces p by the by-coordinate maximum of p and p_ */ - inline void pmax( const Point &p_ ) - { - if( x() < p_.x() ) x() = p_.x() ; - if( y() < p_.y() ) y() = p_.y() ; - if( z() < p_.z() ) z() = p_.z() ; - } - - //----------------------------------------------------------------------------- - // Drawing - public: - /// Draws the point with opengl - void draw () const { ::glVertex3f( (float)x(), (float)y(), (float)z() ) ; } - } ; - -// Valid point -extern Point P_INV ; - - -/**------------------------------------------------------------------------------------*/ -// Geometric Operations - -/// + -inline const Point operator+ ( const Point &p, const Point &p_ ) -{ - Point r = p ; - return (r += p_) ; -} -/// - -inline const Point operator- ( const Point &p, const Point &p_ ) -{ - Point r = p ; - return r -= p_ ; -} -/// * scalar -inline const Point operator* ( const Point &p, const real l ) -{ - Point r = p ; - return r *= l ; -} -/// * scalar -inline const Point operator* ( const real l, const Point &p ) -{ - return p * l ; -} -/// / scalar -inline const Point operator/ ( const Point &p, const real l ) -{ - Point r = p ; - return r /= l ; -} - -/// scalar (dot) product -inline real operator* ( const Point &p, const Point &p_ ) -{ - return p.x()*p_.x() + p.y()*p_.y() + p.z()*p_.z() ; -} -/// vector (cross) product -static inline const Point operator^ ( const Point &p, const Point &p_ ) -{ - Point r ; - r.x() = p.y() * p_.z() - p.z() * p_.y() ; - r.y() = p.z() * p_.x() - p.x() * p_.z() ; - r.z() = p.x() * p_.y() - p.y() * p_.x() ; - return r ; -} -static inline real det( const Point &p, const Point &q, const Point &r ) -{ - return - p.x()*q.y()*r.z() + p.y()*q.z()*r.x() + p.z()*q.x()*r.y() - - p.z()*q.y()*r.x() - p.x()*q.z()*r.y() - p.y()*q.x()*r.z() ; -} - - -/**------------------------------------------------------------------------------------*/ -// Geometric Operations - -inline real length ( const Point &p ) { return p.length() ; } -inline real norm ( const Point &p ) { return p.norm() ; } -inline real dist ( const Point &p, const Point &p_ ) { return p.dist(p_) ; } -inline real sqdist ( const Point &p, const Point &p_ ) { Point r = p-p_ ; return r*r ; } - -/** \brief Computes the normal of a triangle - * \param const Point &v0 - * \param const Point &v1 - * \param const Point &v2 */ -inline const Point normal (const Point & v0, const Point & v1, const Point & v2) -{ - Point n = ( v1-v0 ) ^ ( v2 - v0 ) ; - n.normalize() ; - return n ; -} - -/** \brief Computes the area of a triangle - * \param const Point &v0 - * \param const Point &v1 - * \param const Point &v2 */ -inline real area (const Point & v0, const Point & v1, const Point & v2) -{ - return 0.5 * norm( ( v1-v0 ) ^ ( v2 - v0 ) ); -} - -/** \brief Computes the cotangent of ange v v1,v v2 - * \param const Point &v - * \param const Point &v1 - * \param const Point &v2 */ -inline const real cotan (const Point & v, const Point & v1, const Point & v2) -{ - Point u = v1-v ; - Point w = v2-v ; - return (u*w) / norm( u ^ w ) ; -} - -/** \brief Computes the middle of an edge - * \param const Point &v0 - * \param const Point &v1 */ -inline const Point middle (const Point & v0, const Point & v1) -{ - return 0.5 * (v0+v1) ; -} - - -inline void pmin( Point &p, const Point &p_ ) { p.pmin( p_ ) ; } -inline void pmax( Point &p, const Point &p_ ) { p.pmax( p_ ) ; } - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/ptr_octree.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/ptr_octree.cpp deleted file mode 100644 index 8b3fa39d2d..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/ptr_octree.cpp +++ /dev/null @@ -1,1289 +0,0 @@ -/** - * \file ptr_octree.cpp - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with son-brother pointers - */ -//_____________________________________________________________________________ - - -#ifndef WIN32 -#pragma implementation -#endif // WIN32 - - -#include "ptr_octree.h" - - -//_____________________________________________________________________________ -// Create the root -void PtrOctree::init() -//----------------------------------------------------------------------------- -{ - _root.brother = NULL ; - _root.first_son = NULL ; - _root.field = 0.0 ; - - _max_level = 0 ; - _max_field = R_INV ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Check that each point scan or scribble is in the right node -bool PtrOctree::check () -//----------------------------------------------------------------------------- -{ - bool result = true ; - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Delete the branch below a given node -void PtrOctree::clear_branch( cell *b ) -//----------------------------------------------------------------------------- -{ - std::stack s ; - s.push( b ) ; - while( !s.empty() ) - { - cell *n = s.top() ; - cell *son = n->first_son ; - cell *prev = n ; - while( son != (cell*)NULL ) // look two levels to be able to update pointers - { - cell *next = son->brother ; - if( !son->first_son ) // son is a leaf - { - delete son ; - if( prev == n ) - n->first_son = next ; - else - prev->brother = next ; - } - else - { - prev = son ; - s.push( son ) ; - } - son = next ; - } - if( !n->first_son ) // now it is a leaf - s.pop() ; - } -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// set the values of each leaf from the implicit function -bool PtrOctree::set_impl( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - _max_field = -FLT_MAX ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - if( it.is_leaf() ) - { - real v = (*ref).value_at( it.top() ) ; - *it = v ; - v = fabs(v) ; - if( _max_field < v ) _max_field = v ; - } - else - *it = R_INV ; - } - -// printf( "max field: %f\n", max_field() ) ; - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool PtrOctree::refine( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - clear() ; init() ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it( &_root ) ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; - geom_cell sons[8] ; - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - for( int i = 0 ; i < 8 ; ++i ) - { - sons[i].cell () = new cell ; - sons[i].first_son() = (cell*)NULL ; - sons[i].brother () = (cell*)NULL ; - sons[i].cell()->field = 0.0 ; - - if( i == 0 ) it.first_son() = sons[i].cell() ; - else sons[i-1].brother() = sons[i].cell() ; - } - it.sons( sons ) ; - //if( _max_level < it.lv() ) _max_level = it.lv() ; - if( _max_level < sons[0].lv() ) _max_level = sons[0].lv() ; - - // recurse on the traversal - for( int i = 0 ; i < 8 ; ++i ) - s.push( sons[i] ) ; - } - - return refined ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Refine the octree according to the data access -bool PtrOctree::adapt( data_access *ref /*= NULL*/ ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - - _max_level = 0 ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - geom_cell it( &_root ) ; - std::stack< geom_cell > s ; - s.push( it ) ; - - // although it may refine only the leaves - // the leaf iterator may change during the refinement - bool refined = false ; - while( !s.empty() ) - { - it = s.top() ; s.pop() ; - geom_cell sons[8] ; - - // look for the leaves - if( !it.is_leaf() ) - { - if( !(*ref).need_refine( it ) ) - { - clear_branch( it.cell() ) ; - refined = true ; - continue ; - } - - it.sons( sons ) ; - for( int i = 0 ; i < 8 ; ++i ) - s.push( sons[i] ) ; - - if( _max_level < sons[0].lv() ) _max_level = sons[0].lv() ; - continue ; - } - - // test for subdivision - if( !(*ref).need_refine( it ) ) continue ; - refined = true ; - - //_____________________________________________________________________________ - // subdivides the cell in the tree - for( int i = 0 ; i < 8 ; ++i ) - { - sons[i].cell () = new cell ; - sons[i].first_son() = (cell*)NULL ; - sons[i].brother () = (cell*)NULL ; - sons[i].cell()->field = 0.0 ; - - if( i == 0 ) it.first_son() = sons[i].cell() ; - else sons[i-1].brother() = sons[i].cell() ; - } - it.sons( sons ) ; - //if( _max_level < it.lv() ) _max_level = it.lv() ; - if( _max_level < sons[0].lv() ) _max_level = sons[0].lv() ; - - // recurse on the traversal - for( int i = 0 ; i < 8 ; ++i ) - s.push( sons[i] ) ; - } - - return refined ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Draw the octree with wireframe -bool PtrOctree::draw_wire() -//----------------------------------------------------------------------------- -{ - for( leaf_iterator it = leaves_begin() ; it() ; ++it ) - it.draw_wire() ; - - return true ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draw the octree with dots -bool PtrOctree::draw_centers() -//----------------------------------------------------------------------------- -{ - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - ::glTexCoord1f( (GLfloat)fabs(*it / max_field()) ) ; - it.top().draw() ; - } - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Recursion structure -typedef struct -//----------------------------------------------------------------------------- -{ - enum { DUAL_VERTEX=0, DUAL_EDGE=1, DUAL_FACE=2, DUAL_CUBE=3 } type ; - PtrOctree::geom_cell cells[8] ; - int direction ; -} ptr_dual_iterator_struct ; -//----------------------------------------------------------------------------- -// edge pattern for cubes -// direction : x -> 0, y -> 1, z -> 2, other -> -1 -static const int dir_edges[19][3] = { - {0,1,0}, {0,2,1}, {0,4,2}, {1,3,1}, {1,5,2}, {2,3,0}, {2,6,2}, {3,7,2}, {4,5,0}, {4,6,1}, {5,7,1}, {6,7,0}, - {0,5,-1}, {0,6,-1}, {1,7,-1}, {2,7,-1}, {0,3,-1}, {4,7,-1}, {0,7,-1} } ; -//_____________________________________________________________________________ - - - -#define PRINT_DUAL_DEBUG 0 - -//_____________________________________________________________________________ -// Debug print -void print_final_cube( PtrOctree::geom_cell *cells, float M ) -{ -#if PRINT_DUAL_DEBUG - printf( "cube (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) \n", - (int)(cells[0].cx()*M), (int)(cells[0].cy()*M), (int)(cells[0].cz()*M), - (int)(cells[1].cx()*M), (int)(cells[1].cy()*M), (int)(cells[1].cz()*M), - (int)(cells[2].cx()*M), (int)(cells[2].cy()*M), (int)(cells[2].cz()*M), - (int)(cells[3].cx()*M), (int)(cells[3].cy()*M), (int)(cells[3].cz()*M), - (int)(cells[4].cx()*M), (int)(cells[4].cy()*M), (int)(cells[4].cz()*M), - (int)(cells[5].cx()*M), (int)(cells[5].cy()*M), (int)(cells[5].cz()*M), - (int)(cells[6].cx()*M), (int)(cells[6].cy()*M), (int)(cells[6].cz()*M), - (int)(cells[7].cx()*M), (int)(cells[7].cy()*M), (int)(cells[7].cz()*M) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_cube( const char*ori, PtrOctree::geom_cell *cells, float M ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->cube (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) \n", ori, - (int)(cells[0].cx()*M), (int)(cells[0].cy()*M), (int)(cells[0].cz()*M), - (int)(cells[1].cx()*M), (int)(cells[1].cy()*M), (int)(cells[1].cz()*M), - (int)(cells[2].cx()*M), (int)(cells[2].cy()*M), (int)(cells[2].cz()*M), - (int)(cells[3].cx()*M), (int)(cells[3].cy()*M), (int)(cells[3].cz()*M), - (int)(cells[4].cx()*M), (int)(cells[4].cy()*M), (int)(cells[4].cz()*M), - (int)(cells[5].cx()*M), (int)(cells[5].cy()*M), (int)(cells[5].cz()*M), - (int)(cells[6].cx()*M), (int)(cells[6].cy()*M), (int)(cells[6].cz()*M), - (int)(cells[7].cx()*M), (int)(cells[7].cy()*M), (int)(cells[7].cz()*M) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_face( const char*ori, PtrOctree::geom_cell *cells, float M ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->face (%d,%d,%d) (%d,%d,%d) (%d,%d,%d) (%d,%d,%d)\n", ori, - (int)(cells[0].cx()*M), (int)(cells[0].cy()*M), (int)(cells[0].cz()*M), - (int)(cells[1].cx()*M), (int)(cells[1].cy()*M), (int)(cells[1].cz()*M), - (int)(cells[2].cx()*M), (int)(cells[2].cy()*M), (int)(cells[2].cz()*M), - (int)(cells[3].cx()*M), (int)(cells[3].cy()*M), (int)(cells[3].cz()*M) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_edge( const char*ori, PtrOctree::geom_cell *cells, float M ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->edge (%d,%d,%d) (%d,%d,%d)\n", ori, - (int)(cells[0].cx()*M), (int)(cells[0].cy()*M), (int)(cells[0].cz()*M), - (int)(cells[1].cx()*M), (int)(cells[1].cy()*M), (int)(cells[1].cz()*M) ) ; -#endif // PRINT_DUAL_DEBUG -} -//----------------------------------------------------------------------------- -void print_dual_vertex( const char*ori, PtrOctree::geom_cell *cells, float M ) -{ -#if PRINT_DUAL_DEBUG - printf( "%s->vertex (%d,%d,%d)\n", ori, - (int)(cells[0].cx()*M), (int)(cells[0].cy()*M), (int)(cells[0].cz()*M) ) ; -#endif // PRINT_DUAL_DEBUG -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Rebuild the octree dual -bool PtrOctree::dual_cubes_walk( ptr_dual_walker &walker ) -//----------------------------------------------------------------------------- -{ - bool result = true ; - - float M = 1 << (max_level()+1) ; - - - // face pattern for a cube - // direction : yz -> 0, zx -> 1, xy -> 2 - static const int faces[6][5] = { - {0,1,2,3, 2}, {4,5,6,7, 2}, {0,1,4,5, 1}, {2,3,6,7, 1}, {0,2,4,6, 0}, {1,3,5,7, 0} } ; - - // traversal stack: iterator has a pre-ordered stack, and cannot be recursed on - ptr_dual_iterator_struct dual_it ; - dual_it.type = ptr_dual_iterator_struct::DUAL_VERTEX ; - dual_it.cells[0] = geom_cell( &_root ) ; - std::stack< ptr_dual_iterator_struct > s ; - s.push( dual_it ) ; - - _dual_temp_memory = s.size() ; - while( !s.empty() ) - { - int s_size = s.size() ; - if( s_size > _dual_temp_memory ) _dual_temp_memory = s_size ; - - dual_it = s.top() ; s.pop() ; - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // vertex case - if( dual_it.type == ptr_dual_iterator_struct::DUAL_VERTEX ) - { - if( dual_it.cells[0].is_leaf() ) continue ; - - geom_cell sons[8] ; - dual_it.cells[0].sons( sons ) ; - - //_____________________________________________________________________________ - // vertex - dual_it.type = ptr_dual_iterator_struct::DUAL_VERTEX ; - for( int i = 0 ; i < 8 ; ++i ) - { - dual_it.cells[0] = sons[i] ; - s.push( dual_it ) ; - print_dual_vertex( "vertex", dual_it.cells, M ) ; - } - - //_____________________________________________________________________________ - // edge - dual_it.type = ptr_dual_iterator_struct::DUAL_EDGE ; - for( int i = 0 ; i < 12 ; ++i ) - { - dual_it.cells[0] = sons[ dir_edges[i][0] ] ; - dual_it.cells[1] = sons[ dir_edges[i][1] ] ; - dual_it.direction = dir_edges[i][2] ; - s.push( dual_it ) ; - print_dual_edge( "vertex", dual_it.cells, M ) ; - } - - //_____________________________________________________________________________ - // face - dual_it.type = ptr_dual_iterator_struct::DUAL_FACE ; - for( int i = 0 ; i < 6 ; ++i ) - { - dual_it.cells[0] = sons[ faces[i][0] ] ; - dual_it.cells[1] = sons[ faces[i][1] ] ; - dual_it.cells[2] = sons[ faces[i][2] ] ; - dual_it.cells[3] = sons[ faces[i][3] ] ; - dual_it.direction = faces[i][4] ; - s.push( dual_it ) ; - print_dual_face( "vertex", dual_it.cells, M ) ; - } - - //_____________________________________________________________________________ - // cube - dual_it.type = ptr_dual_iterator_struct::DUAL_CUBE ; - for( int i = 0 ; i < 8 ; ++i ) dual_it.cells[i] = sons[i] ; - s.push( dual_it ) ; - print_dual_cube( "vertex", dual_it.cells, M ) ; - - continue ; - } - - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // edge case - else if( dual_it.type == ptr_dual_iterator_struct::DUAL_EDGE ) - { - geom_cell all_sons[2][8] ; - if( dual_it.cells[0].is_leaf() ) - { - if( dual_it.cells[1].is_leaf() ) - continue ; - - // repeat father - for( int i = 0 ; i < 8 ; ++i ) - all_sons[0][i] = dual_it.cells[0] ; - - dual_it.cells[1].sons( all_sons[1] ) ; - } - else - { - dual_it.cells[0].sons( all_sons[0] ) ; - - if( dual_it.cells[1].is_leaf() ) - { - // repeat father - for( int i = 0 ; i < 8 ; ++i ) - all_sons[1][i] = dual_it.cells[1] ; - } - else - dual_it.cells[1].sons( all_sons[1] ) ; - } - - - //_____________________________________________________________________________ - // local cube - geom_cell sons[8] ; - int dir = dual_it.direction ; - switch( dir ) - { - // x-aligned edge - case 0 : - sons[0] = all_sons[0][1] ; - sons[1] = all_sons[1][0] ; - sons[2] = all_sons[0][3] ; - sons[3] = all_sons[1][2] ; - sons[4] = all_sons[0][5] ; - sons[5] = all_sons[1][4] ; - sons[6] = all_sons[0][7] ; - sons[7] = all_sons[1][6] ; - break ; - - // y-aligned edge - case 1 : - sons[0] = all_sons[0][2] ; - sons[1] = all_sons[0][3] ; - sons[2] = all_sons[1][0] ; - sons[3] = all_sons[1][1] ; - sons[4] = all_sons[0][6] ; - sons[5] = all_sons[0][7] ; - sons[6] = all_sons[1][4] ; - sons[7] = all_sons[1][5] ; - break ; - - // z-aligned edge - case 2 : - sons[0] = all_sons[0][4] ; - sons[1] = all_sons[0][5] ; - sons[2] = all_sons[0][6] ; - sons[3] = all_sons[0][7] ; - sons[4] = all_sons[1][0] ; - sons[5] = all_sons[1][1] ; - sons[6] = all_sons[1][2] ; - sons[7] = all_sons[1][3] ; - break ; - } - - //_____________________________________________________________________________ - // edge - dual_it.direction = dir ; // same direction - dual_it.type = ptr_dual_iterator_struct::DUAL_EDGE ; - for( int i = 0 ; i < 12 ; ++i ) - { - if( dir_edges[i][2] != dir ) continue ; - dual_it.cells[0] = sons[ dir_edges[i][0] ] ; - dual_it.cells[1] = sons[ dir_edges[i][1] ] ; - s.push( dual_it ) ; - print_dual_edge( "edge", dual_it.cells, M ) ; - } - - //_____________________________________________________________________________ - // face - dual_it.type = ptr_dual_iterator_struct::DUAL_FACE ; - for( int i = 0 ; i < 6 ; ++i ) - { - if( faces[i][4] == dir ) continue ; - dual_it.cells[0] = sons[ faces[i][0] ] ; - dual_it.cells[1] = sons[ faces[i][1] ] ; - dual_it.cells[2] = sons[ faces[i][2] ] ; - dual_it.cells[3] = sons[ faces[i][3] ] ; - dual_it.direction = faces[i][4] ; - s.push( dual_it ) ; - print_dual_face( "edge", dual_it.cells, M ) ; - } - - //_____________________________________________________________________________ - // cube - dual_it.type = ptr_dual_iterator_struct::DUAL_CUBE ; - for( int i = 0 ; i < 8 ; ++i ) dual_it.cells[i] = sons[i] ; - s.push( dual_it ) ; - print_dual_cube( "edge", dual_it.cells, M ) ; - - continue ; - } - - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // face case - else if( dual_it.type == ptr_dual_iterator_struct::DUAL_FACE ) - { - geom_cell all_sons[4][8] ; - bool leaf = true ; - for( int i = 0 ; i < 4 ; ++i ) - { - if( dual_it.cells[i].is_leaf() ) - { - // repeat father - for( int j = 0 ; j < 8 ; ++j ) - all_sons[i][j] = dual_it.cells[i] ; - } - else - { - leaf = false ; - dual_it.cells[i].sons( all_sons[i] ) ; - } - } - if( leaf ) continue ; - - - //_____________________________________________________________________________ - // local cube - geom_cell sons[8] ; - int dir = dual_it.direction ; - switch( dir ) - { - // yz-aligned face - case 0 : - sons[0] = all_sons[0][6] ; - sons[1] = all_sons[0][7] ; - sons[2] = all_sons[1][4] ; - sons[3] = all_sons[1][5] ; - sons[4] = all_sons[2][2] ; - sons[5] = all_sons[2][3] ; - sons[6] = all_sons[3][0] ; - sons[7] = all_sons[3][1] ; - break ; - - // zx-aligned edge - case 1 : - sons[0] = all_sons[0][5] ; - sons[1] = all_sons[1][4] ; - sons[2] = all_sons[0][7] ; - sons[3] = all_sons[1][6] ; - sons[4] = all_sons[2][1] ; - sons[5] = all_sons[3][0] ; - sons[6] = all_sons[2][3] ; - sons[7] = all_sons[3][2] ; - break ; - - // xy-aligned edge - case 2 : - sons[0] = all_sons[0][3] ; - sons[1] = all_sons[1][2] ; - sons[2] = all_sons[2][1] ; - sons[3] = all_sons[3][0] ; - sons[4] = all_sons[0][7] ; - sons[5] = all_sons[1][6] ; - sons[6] = all_sons[2][5] ; - sons[7] = all_sons[3][4] ; - break ; - } - - //_____________________________________________________________________________ - // face - // same direction - dual_it.direction = dir ; - dual_it.type = ptr_dual_iterator_struct::DUAL_FACE ; - for( int i = 0 ; i < 6 ; ++i ) - { - if( faces[i][4] != dir ) continue ; - dual_it.cells[0] = sons[ faces[i][0] ] ; - dual_it.cells[1] = sons[ faces[i][1] ] ; - dual_it.cells[2] = sons[ faces[i][2] ] ; - dual_it.cells[3] = sons[ faces[i][3] ] ; - // dual_it.direction = faces[i][4] ; - s.push( dual_it ) ; - print_dual_face( "face", dual_it.cells, M ) ; - } - - //_____________________________________________________________________________ - // cube - dual_it.type = ptr_dual_iterator_struct::DUAL_CUBE ; - for( int i = 0 ; i < 8 ; ++i ) dual_it.cells[i] = sons[i] ; - s.push( dual_it ) ; - print_dual_cube( "face", dual_it.cells, M ) ; - - continue ; - } - - - //_____________________________________________________________________________ - //_____________________________________________________________________________ - // cube case - else if( dual_it.type == ptr_dual_iterator_struct::DUAL_CUBE ) - { - bool leaf = true ; - - //_____________________________________________________________________________ - // cube - for( int i = 0 ; i < 8 ; ++i ) - { - // copy father - if( dual_it.cells[i].is_leaf() ) - continue ; - - // else - leaf = false ; - geom_cell sons[8] ; - dual_it.cells[i].sons( sons ) ; - dual_it.cells[i] = sons[ 7-i ] ; - } - - // finally add dual cube - if( leaf ) - { - result &= walker( *this, dual_it.cells ) ; - print_final_cube( dual_it.cells, M ) ; - } - else - { - s.push( dual_it ) ; - print_dual_cube( "cube", dual_it.cells, M ) ; - } - - continue ; - } - - } - - return result ; -} -//_____________________________________________________________________________ - - - - - -#include "morton.h" -//_____________________________________________________________________________ -// Isosurface walker -bool ptr_isosurface_walker( PtrOctree &fo, PtrOctree::geom_cell *cells ) -//----------------------------------------------------------------------------- -{ - MarchingCubes &mc = fo.mc() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - /** indexes of the cube */ - Key *indexes = mc.indexes() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const PtrOctree::geom_cell &c = cells[j] ; - cube[i] = c.cell()->field ; - - space[i] = (Point&)c ; - indexes[i] = cube2key((Cube&)c) ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool PtrOctree::build_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc.dat_access() = ref ; - - printf( "Build isosurface... " ) ; - bool result = false ; - - //_________________________________________________________________________ - // Dual Marching Cubes - - _mc.init_all() ; - - result = dual_cubes_walk( ptr_isosurface_walker ) ; - - _mc.clean_temps() ; - - printf( "generated %d vertices and %d faces!\n", _mc.nverts(), _mc.ntrigs() ) ; - - return result ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Isosurface drawing walker -bool ptr_direct_isosurface_walker( PtrOctree &fo, PtrOctree::geom_cell *cells ) -//----------------------------------------------------------------------------- -{ - MC_Draw &mc = fo.mc_draw() ; - - /** isovalues at the cube vertices */ - real *cube = mc.cube() ; - /** geometry of the cube */ - Point *space = mc.space() ; - - for( int j = 0 ; j < 8 ; ++j ) - { - int i = (j==2)?3:(j==3)?2:(j==7)?6:(j==6)?7:j ; - const PtrOctree::geom_cell &c = cells[j] ; - cube[i] = c.cell()->field ; - - space[i] = (Point&)c ; - } - - mc.tesselate_cube( 0.0 ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Build the isosurface using dual marching cubes -bool PtrOctree::direct_draw_isosurface( data_access *ref ) -//----------------------------------------------------------------------------- -{ - if( !ref ) return false ; - _mc_draw.dat_access() = ref ; - - bool result = false ; - - // Dual Marching Cubes - ::glBegin( GL_TRIANGLES ) ; - { - result = dual_cubes_walk( ptr_direct_isosurface_walker ) ; - } - ::glEnd() ; // GL_TRIANGLES - - return result ; -} -//_____________________________________________________________________________ - - - - - - -//_____________________________________________________________________________ -// Draw walker -bool ptr_draw_walker( PtrOctree &fo, PtrOctree::geom_cell *cells ) -//----------------------------------------------------------------------------- -{ - ((Point)cells[0]).draw() ; - ((Point)cells[1]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[3]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[2]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[0]).draw() ; - - ((Point)cells[4]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[5]).draw() ; - ((Point)cells[7]).draw() ; - - ((Point)cells[7]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[6]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[0]).draw() ; - ((Point)cells[4]).draw() ; - - ((Point)cells[1]).draw() ; - ((Point)cells[5]).draw() ; - - ((Point)cells[2]).draw() ; - ((Point)cells[6]).draw() ; - - ((Point)cells[3]).draw() ; - ((Point)cells[7]).draw() ; - - return true ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Draw the dual octree with wireframe -bool PtrOctree::draw_dual() -//----------------------------------------------------------------------------- -{ - ::glBegin( GL_LINES ) ; - bool result = dual_cubes_walk( ptr_draw_walker ) ; - ::glEnd() ; // GL_LINES - - return result ; -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// Do nothing walker, just for dual generation timing -bool ptr_timing_walker( PtrOctree &fo, PtrOctree::geom_cell *cells ) -//----------------------------------------------------------------------------- -{ - return true ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// Do nothing, just for dual generation timing -bool PtrOctree::dual_timing() -//----------------------------------------------------------------------------- -{ - return dual_cubes_walk( ptr_timing_walker ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Prints statistics about the octree -void PtrOctree::stats() -//----------------------------------------------------------------------------- -{ - uint level_dist[MAX_LEVEL+1] ; - memset( level_dist, 0, (MAX_LEVEL+1)*sizeof(uint) ) ; - - int s = 0 ; - for( cell_iterator it = cells_begin() ; it() ; ++it ) - { - ++s ; - if( it.is_leaf() ) level_dist[ it.lv() ] ++ ; - } - - printf( " number of nodes:\t%d\n", s ) ; - printf( " total memory:\t%d\n", (int) ( s * sizeof(cell) ) ) ; - - printf( " leaves' levels:\t" ) ; - for( Level l = 0 ; l <= MAX_LEVEL; ++l ) - printf( "\t%d", level_dist[l] ) ; - printf( "\n" ) ; - - printf( " max size of the stack:\t%d\n", _dual_temp_memory ) ; - printf( " total memory of stack:\t%d\n", (int) ( _dual_temp_memory * sizeof(ptr_dual_iterator_struct) ) ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// search operations - - -//_____________________________________________________________________________ -// Find cells of the octree at a given position -bool PtrOctree::find_leaf( real x, real y, real z, geom_cell &n ) -//----------------------------------------------------------------------------- -{ - - n = geom_cell( &_root ) ; - - while( !n.is_leaf() ) - { - ++n.lv() ; - real sz = n.sz() ; - - // side test : - // 0->back lower left, 1->back lower right, 2->back upper left, 3->back upper right - // 4->front lower left, 5->front lower right, 6->front upper left, 7->front upper right - int i = ( (n.cz() < z) << 2 ) | ( (n.cy() < y) << 1 ) | (n.cx() < x) ; - n.cx() += (i&1) ? +sz : -sz ; - n.cy() += (i&2) ? +sz : -sz ; - n.cz() += (i&4) ? +sz : -sz ; - - n.cell() = n.first_son() ; - while( --i > -1 ) n.cell() = n.brother() ; - } - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find cells of the octree inside a given box of center x,y and half side r -bool PtrOctree::find_radius( real x, real y, real z, real r, List &cells ) -//----------------------------------------------------------------------------- -{ - - cells.clear() ; - - geom_cell n( &_root ) ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - while( !s.empty() ) - { - n = s.top() ; s.pop() ; -// printf( "%d\t%.4f\t%.4f\t%.4f\n", (int)n.lv(), n.x(), n.y(), n.z() ) ; - if( n.is_leaf() ) - { - cells.insert( n ) ; - continue ; - } - - geom_cell sons[8] ; - n.sons( sons ) ; - real sz_ = sons[0].sz() + r ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( (fabs( sons[i].cx() - x ) < sz_ ) && - (fabs( sons[i].cy() - y ) < sz_ ) && - (fabs( sons[i].cz() - z ) < sz_ ) ) - s.push( sons[i] ) ; - } - } -// printf( "\n" ) ; - - return true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// Find neighbor cells of the octree to a given cell -bool PtrOctree::adjacent( const geom_cell &cell, List &cells ) -//----------------------------------------------------------------------------- -{ - return find_radius( cell.cx(), cell.cy(), cell.cz(), cell.sz() + (real) 0.5 / (1 << max_level() ) , cells ) ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ -// I/O - -//_____________________________________________________________________________ -// Draws the intersecting cells of a plane with the octree with color -void PtrOctree::draw_plane ( real nx, real ny, real nz, real d ) -//----------------------------------------------------------------------------- -{ - geom_cell n( &_root ) ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - //_____________________________________________________________________________ - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - //_____________________________________________________________________________ - - ::glLineWidth( (GLfloat)1.0 ) ; - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - - if( n.is_leaf() ) - { - - ::glTexCoord1f( (GLfloat)fabs(*n/max_field()) ) ; - ::glBegin( GL_LINES ) ; - n.draw_wire() ; - ::glEnd() ; // GL_LINES - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// Draws the intersection of a plane with the octree with color -void PtrOctree::draw_slice ( real nx, real ny, real nz, real d, float alpha ) -//----------------------------------------------------------------------------- -{ - geom_cell n( &_root ) ; - - std::stack< geom_cell > s ; - s.push( n ) ; - - // retrieve the index of the most positive cube corner - bool fx = nx >= 0 ; - bool fy = ny >= 0 ; - bool fz = nz >= 0 ; - - - - //_____________________________________________________________________________ - - ::glDisable( GL_LIGHTING ) ; - - real px,py,pz, mx,my,mz ; - while( !s.empty() ) - { - n = s.top() ; s.pop() ; - if( n.is_leaf() ) - { - // retrieves the signs of each cube corner - real val[8] ; - real v = nx * n.cx() + ny * n.cy() + nz * n.cz() + d ; - real sz_ = n.sz() ; - int zeros = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - val[i] = v + nx * ((i&1)?sz_:-sz_) + ny * ((i&2)?sz_:-sz_) + nz * ((i&4)?sz_:-sz_) ; - if( fabs(val[i]) < R_EPSILON ) { val[i] = R_EPSILON ; ++zeros ; } - } - - //_________________________________________________________________________ - // degenerated intersection - if( zeros > 0 ) - { - int npos = 0, nneg = 0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) continue ; - if( val[i] < 0 ) - ++nneg ; - else - ++npos ; - } - float def = (nneg>npos) ? (GLfloat)R_EPSILON : (GLfloat)-R_EPSILON ; - - for( int i = 0 ; i < 8 ; ++i ) - { - if( fabs(val[i]) < R_EPSILON ) val[i] = def ; - } - // continue ; - } - - //_________________________________________________________________________ - // Continuation method - int v0=-1, v1=-1 ; // current edge vertices - - // get the first intersection - static int edges[12][2] = { {0,1}, {0,2}, {0,4}, {1,3}, {1,5}, {2,3}, {2,6}, {3,7}, {4,5}, {4,6}, {5,7}, {6,7} } ; - for( int e = 0 ; e < 12 ; ++e ) - { - if( val[ edges[e][0] ] * val[ edges[e][1] ] < 0 ) - { - v0 = edges[e][0] ; - v1 = edges[e][1] ; - break ; - } - } - int ov0 = v0, ov1 = v1 ; - - - // equation of previous face adjacent to v0v1: v>>c & 1 == s (c-th coordinate equal to +/- 1) - int pf = -1 ; bool ps ; - if ( (v0 & 1) == (v1 & 1) ) { pf = 0 ; ps = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( (v0 & 2) == (v1 & 2) ) { pf = 1 ; ps = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( (v0 & 4) == (v1 & 4) )*/ { pf = 2 ; ps = ((v0 & 4) >> 2 ) == 1 ; } - - // printf( "cube %d %d %d %d %d %d %d %d, march : (%d,%d) ", val[0]>0, val[1]>0, val[2]>0, val[3]>0, val[4]>0, val[5]>0, val[6]>0, val[7]>0, v0, v1 ) ; - - //_________________________________________________________________________ - // marching - - GLfloat color = (GLfloat)fabs(*n / max_field()) ; - ::glBegin( GL_POLYGON ) ; - { - do - { - // equation of next face adjacent to v0v1 - int nf = -1 ; bool ns ; - if ( pf != 0 && ((v0 & 1) == (v1 & 1)) ) { nf = 0 ; ns = ((v0 & 1) /*>> 0*/) == 1 ; } - else if( pf != 1 && ((v0 & 2) == (v1 & 2)) ) { nf = 1 ; ns = ((v0 & 2) >> 1 ) == 1 ; } - else /*if( pf != 2 && ((v0 & 4) == (v1 & 4)) )*/ { nf = 2 ; ns = ((v0 & 4) >> 2 ) == 1 ; } - - /* equivalent construction - // get the direction perpendicular to v0v1 - int of = (v0 ^ v1) & 7 ; // only bit of difference - of = of==1 ? 0 : (of==2 ? 1 : 2) ; - - // compute the equation of the next face adjacent to v0v1 - int nf = 3 - (pf+of) ; // third option: {pf,nf,of}={0,1,2} - bool ns = (v0 >> nf) & 1 ; // value of the edge on that direction - */ - - // compute the two next vertices (invert the pf-th bit - int v2 = ps ? ( v0 & (~(1< 0) | ((val[v2] > 0) << 1) | ((val[v1] > 0) << 2) | ((val[v0] > 0) << 3) ; - if( c > 7 ) c = (~c)&7 ; // consider v0 as negative, and thus v1 as positive - /* - if( c < 4 ) - { // degenerated intesection - printf( "degenerated intersection %d!\n", c ) ; - } - */ - - //_______________________________________________________________________ - // method of continuity on the cube surface - switch( c ) - { - case 4 : v0 = v3 ; break ; - case 5 : v0 = v2 ; v1 = v3 ; break ; - case 6 : /* impossible case */ break ; - case 7 : v1 = v2 ; break ; - } - - - - - real cx = n.cx(); - real cy = n.cy(); - real cz = n.cz(); - real sz = sz_; - real a0 = val[v0]; - int i0 = v0; - real a1 = val[v1]; - int i1 = v1; - - real w0 = a1 / (a1-a0) ; - real w1 = a0 / (a0-a1) ; - - real x = cx + w0 * ((i0&1)?sz:-sz) + w1 * ((i1&1)?sz:-sz); - real y = cy + w0 * ((i0&2)?sz:-sz) + w1 * ((i1&2)?sz:-sz); - real z = cz + w0 * ((i0&4)?sz:-sz) + w1 * ((i1&4)?sz:-sz); - - ::glTexCoord1d( color ) ; - ::glVertex3d(x, y, z) ; - - // next face - pf = nf ; ps = ns ; - - // printf( "(%d,%d) ", v0, v1 ) ; - } while( v0 != ov0 || v1 != ov1 ) ; - // printf( "\n" ) ; - } - ::glEnd() ; // GL_POLYGON - - continue ; - } - - //___________________________________________________________________________ - // recursion - geom_cell sons[8] ; - n.sons( sons ) ; - real sz_ = sons[0].sz() ; - for( int i = 0 ; i < 8 ; ++i ) - { - // get the coordinates of the extremum vertices - if( fx ) { px = sons[i].cx() + sz_ ; mx = sons[i].cx() - sz_ ; } - else { px = sons[i].cx() - sz_ ; mx = sons[i].cx() + sz_ ; } - if( fy ) { py = sons[i].cy() + sz_ ; my = sons[i].cy() - sz_ ; } - else { py = sons[i].cy() - sz_ ; my = sons[i].cy() + sz_ ; } - if( fz ) { pz = sons[i].cz() + sz_ ; mz = sons[i].cz() - sz_ ; } - else { pz = sons[i].cz() - sz_ ; mz = sons[i].cz() + sz_ ; } - - // plane/cube intersection test - if( (nx * px + ny * py + nz * pz + d >= 0.0) && (nx * mx + ny * my + nz * mz + d <= 0.0) ) - s.push( sons[i] ) ; - } - } -} -//_____________________________________________________________________________ - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/ptr_octree.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/ptr_octree.h deleted file mode 100644 index 7907e2865c..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/ptr_octree.h +++ /dev/null @@ -1,400 +0,0 @@ -/** - * \file ptr_octree.h - * \author Thomas Lewiner - * \author Matmidia Lab, Math Dept, PUC-Rio - * \date 10/01/2010 - * - * Octree structure with son-brother pointers - */ -//_____________________________________________________________________________ - - -#pragma once - - -#ifndef WIN32 -#pragma interface -#endif // WIN32 - - -#include -#include "mlist.h" -#include "cube.h" -#include "MarchingCubes.h" -#include "mc_draw.h" -#include "data_access.h" - - -//_____________________________________________________________________________ -// PtrOctree -/// \class PtrOctree PtrOctree.h -class PtrOctree -//----------------------------------------------------------------------------- -{ -// forward declaration -public: - class geom_cell ; - class cell_iterator ; - class leaf_iterator ; - -// Elements -protected: - /// Octree cell data structure - typedef struct cell - { - struct cell *brother ; ///< next brother of the cell - struct cell *first_son ; ///< first son of the cell - real field ; ///< field supported by the cell - } cell ; - - /// Root of the octree - cell _root ; - - /// Maximal level of the octree (for find_adjacent) - Level _max_level ; - - /// Maximal field of the octree - real _max_field ; - - /// Isosurface - MarchingCubes _mc ; - - /// Isosurface Draw - MC_Draw _mc_draw ; - - /// Dual run memory consumption - uint _dual_temp_memory ; - - //----------------------------------------------------------------------------- -// Constructors -public: - /// Default constructor: Constructs a octree with and empty root - PtrOctree() { init() ; } - - /// Destructor: Free memory - ~PtrOctree() { clear() ; } - - - /// Create the root - void init() ; - - /// Memory cleaning - void clear() { clear_octree() ; _mc.clean_all() ; } - - /// Delete the branch below a given node - void clear_branch( cell *b ) ; - - /// Delete the content of the octree - void clear_octree() { clear_branch( &_root ) ; } - - /// Check that only the leaves have data - bool check () ; - - /// Prints statistics about the octree - void stats() ; - - - /// Return the maximal level of the octree - Level max_level() const { return _max_level ; } - - /// Return the maximal field of the octree - real max_field() const { return _max_field ; } - - /// Return the isosurface - MarchingCubes &mc() { return _mc ; } - - /// Return the isosurface draw - MC_Draw &mc_draw() { return _mc_draw ; } - - /// set the values of each leaf from the implicit function - bool set_impl( data_access *ref = NULL ) ; - - /// Refine the octree according to the data access - bool refine( data_access *ref = NULL ) ; - - /// Adapt the octree according to the data access - bool adapt( data_access *ref = NULL ) ; - - /// Draw the octree with wireframe - bool draw_wire() ; - - /// Draw the octree with dots - bool draw_centers() ; - - /// Dual function type - typedef bool ptr_dual_walker( PtrOctree &fo, geom_cell *cells ) ; - - /// Walk on the dual cubes - bool dual_cubes_walk( ptr_dual_walker &walker ) ; - - /// Build the isosurface using dual marching cubes - bool build_isosurface( data_access *ref = NULL ) ; - - /// Draw the isosurface on-the-fly using dual marching cubes - bool direct_draw_isosurface( data_access *ref = NULL ) ; - - /// Draw the dual octree with wireframe - bool draw_dual() ; - - /// Do nothing, just for dual generation timing - bool dual_timing() ; - -//----------------------------------------------------------------------------- -// iterators -public: - /// Create an iterator traversing the tree from the root - inline cell_iterator cells_begin() { return cell_iterator( &_root ) ; } - - /// Create an iterator traversing the leaves of the tree from the root - inline leaf_iterator leaves_begin() { return leaf_iterator( &_root ) ; } - -//----------------------------------------------------------------------------- -// search operations -public: - /// Find cells of the octree at a given position - bool find_leaf( real x, real y, real z, geom_cell &cell ) ; - - /// Find cells of the octree inside a given box of center x,y,z and half side r - bool find_radius( real x, real y, real z, real r, List &cells ) ; - - /// Find adjacent cells of the octree to a given cell - bool adjacent( const geom_cell &cell, List &cells ) ; - - -//----------------------------------------------------------------------------- -// I/O -public: - - /// Draws the intersecting cells of a plane with the octree with color - void draw_plane ( real nx, real ny, real nz, real d ) ; - - /// Draws the intersection of a plane with the octree with color - void draw_slice ( real nx, real ny, real nz, real d, float alpha ) ; - - /// Draws the isosurface of level l inside the dual graph - void draw_iso () { _mc.draw_surf() ; } - -//_____________________________________________________________________________ -// Iterator Cell -public : - /// Auxiliary structure to traverse the octree - class geom_cell : public Cube - //--------------------------------------------------------------------------- - { - friend class PtrOctree ; - - protected: - PtrOctree::cell *_cell ; ///< octree cell - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor: Constructs an iterator from a cell - geom_cell( PtrOctree::cell *cell_ = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 ) - : Cube(cx_,cy_,cz_,lv_), _cell(cell_) {} - - /// Destructor - ~geom_cell() {} - - - /// Copy constructor - geom_cell( const geom_cell &i ) - : Cube(i), _cell(i._cell) {} - - /// Assignment operator - geom_cell &operator = ( const geom_cell &i ) - { Cube::operator=(i); _cell=i._cell; return *this; } - - //--------------------------------------------------------------------------- - // Public constant accessors - public : - /// cell const accessor - inline const PtrOctree::cell * cell() const { return _cell ; } - /// cell accessor - inline PtrOctree::cell *&cell() { return _cell ; } - - /// first son const accessor - inline const PtrOctree::cell * first_son() const { return _cell->first_son ; } - /// first son accessor - inline PtrOctree::cell *&first_son() { return _cell->first_son ; } - - /// brother const accessor - inline const PtrOctree::cell * brother() const { return _cell->brother ; } - /// brother accessor - inline PtrOctree::cell *&brother() { return _cell->brother ; } - - /// id const accessor - inline real operator*() const { return cell()->field ; } - /// id accessor - inline real &operator*() { return cell()->field ; } - - //--------------------------------------------------------------------------- - // Tests - public : - /// equality operator - inline bool operator ==( const geom_cell &i ) const { return cell() == i.cell() ; } - - /// inequality operator - inline bool operator !=( const geom_cell &i ) const { return cell() != i.cell() ; } - - /// leaf test - inline bool is_leaf() const { return first_son() == NULL ; } - - /// validation operator - inline bool operator ()() const { return cell() != NULL ; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// sons - inline bool sons( geom_cell *s /*[8]*/ ) - { - if( !first_son() ) return false ; - - int level_ = lv() + 1 ; - real sz_ = sz() / 2.0 ; - for( int i = 0 ; i < 8 ; ++i ) - { - s[i].cell () = (i==0) ? first_son() : s[i-1].brother() ; - s[i].lv () = level_ ; - s[i].cx () = (i&1) ? cx() + sz_ : cx() - sz_ ; - s[i].cy () = (i&2) ? cy() + sz_ : cy() - sz_ ; - s[i].cz () = (i&4) ? cz() + sz_ : cz() - sz_ ; - } - return true ; - } - - /// get son from side i - inline bool son( int i , geom_cell &s ) - { - if( is_leaf() ) return false ; - - real sz_ = s.sz() / 2.0 ; - ++s.lv() ; - s.cx() = (i&1) ? cx() + sz_ : cx() - sz_ ; - s.cy() = (i&2) ? cy() + sz_ : cy() - sz_ ; - s.cz() = (i&4) ? cz() + sz_ : cz() - sz_ ; - - s.cell() = first_son() ; - while( --i > -1 ) s.cell() = s.brother() ; - - return true ; - } - }; - - -//_____________________________________________________________________________ -// Cell Iterator -public : - /// Octree cell iterator : Traverse the octree returning basic information on the cells - class cell_iterator - //--------------------------------------------------------------------------- - { - friend class PtrOctree ; - - protected: - /// Octree traversal stack - std::stack _s ; - - //--------------------------------------------------------------------------- - // Constructors - public: - /// Default constructor : Constructs an iterator from a cell - cell_iterator( PtrOctree::cell *root = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 ) - { if( root ) _s.push( geom_cell( root, cx_, cy_, cz_, lv_ ) ) ; } - - /// Destructor - ~cell_iterator() {} - - /// Copy constructor - cell_iterator( const cell_iterator &i ) : _s(i._s) {} - - /// Assignment operator - cell_iterator &operator = ( const cell_iterator &i ) - { _s = i._s; return *this; } - - //--------------------------------------------------------------------------- - // Operations - public : - /// validation operator - inline bool operator ()() const { return !_s.empty() ; } - - /// next position - inline cell_iterator &operator ++() - { - if( _s.empty() ) return *this ; - geom_cell n = _s.top() ; _s.pop() ; - if( n.is_leaf() ) return *this ; - - // depth first search - geom_cell sons[8] ; - n.sons( sons ) ; - for( int i = 0 ; i < 8 ; ++i ) - _s.push( sons[i] ) ; - - return *this ; - } - - //--------------------------------------------------------------------------- - // Accessors - public : - /// geom_cell accessor - inline geom_cell &top() { return _s.top() ; } - - /// id accessor - inline real &operator*() { return * _s.top() ; } - - /// level accessor - inline Level &lv() { return _s.top().lv() ; } - - /// center x position accessor - inline real &cx() { return _s.top().cx() ; } - - /// center y position accessor - inline real &cy() { return _s.top().cy() ; } - - /// center y position accessor - inline real &cz() { return _s.top().cz() ; } - - /// size accessor - inline real sz() { return _s.top().sz() ; } - - /// points accessor - inline bool is_leaf() const { return _s.top().is_leaf() ; } - - /// inside test - inline bool contains( real x, real y, real z ) const { return _s.top().contains( x,y,z ) ; } - - /// get son from its side: - inline bool son( int i , geom_cell &s_ ) { return _s.top().son(i,s_) ; } - - /// Draws the cell wire with opengl - void draw_wire () const { _s.top().draw_wire () ; } - - protected : - /// stack accessor for ad hoc iterations - inline std::stack< geom_cell > &s() { return _s ; } - }; - - - /// Octree leaf iterator : Traverse the octree returning basic information on the leaves - class leaf_iterator : public cell_iterator - //--------------------------------------------------------------------------- - { - public : - leaf_iterator( PtrOctree::cell *root = NULL, real cx_ = 0.5, real cy_ = 0.5, real cz_ = 0.5, Level lv_ = 0 ) : cell_iterator( root, cx_,cy_,cz_,lv_ ) - { if( root && !this->is_leaf() ) ++(*this) ; } - - - /// next position - inline leaf_iterator &operator ++() - { - cell_iterator &it = *this ; - do ++it ; while ( it() && !it.is_leaf() ) ; - return *this ; - } - } ; -} ; -//_____________________________________________________________________________ - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_cmdline.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_cmdline.cpp deleted file mode 100644 index 5625ab45bf..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_cmdline.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file glui_cmdline.cpp - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.1 - * @date 20/08/2007 - * - * @brief Example Graphical interface: command line parser - */ -//________________________________________________ - - -#ifndef WIN32 -#pragma implementation "viz_glui_defs.h" -#endif // WIN32 - -#include "viz_glui_defs.h" - - -//_____________________________________________________________________________ -// parse command line -bool parse_command_line(int argc, char* argv[]) -//----------------------------------------------------------------------------- -{ - bool quit = false ; - - for( int i = 1 ; i < argc ; ++i ) - { - if ( !strcmp( argv[i], "-lv" ) ) - { - if( ++i != argc ) { max_level = atoi( argv[i] ) ; } - } - - else if( !strcmp( argv[i], "+ortho" ) ) - { - ortho = true ; - } - else if( !strcmp( argv[i], "-ortho" ) ) - { - ortho = false ; - } - else if( !strcmp( argv[i], "-pos" ) ) - { - if( ++i != argc ) { obj_pos[0] = atof( argv[i] ) ; } - if( ++i != argc ) { obj_pos[1] = atof( argv[i] ) ; } - if( ++i != argc ) { obj_pos[2] = atof( argv[i] ) ; } - } - else if( !strcmp( argv[i], "-rot" ) ) - { - for( int j = 0 ; j < 16 ; ++j ) - if( ++i != argc ) { view_rotate[j] = atof( argv[i] ) ; } - } - else if( !strcmp( argv[i], "-view" ) ) - { - control_cb( LOAD_VIEWPORT_ID ) ; - } - else if( !strcmp( argv[i], "-q" ) ) - { - quit = true ; - } - else if( !strcmp( argv[i], "-h" ) ) - { - printf( "usage %s [-in file.xyz] [-q]\n", argv[0] ) ; - } - } - // glui_side ->sync_live() ; - glui_bottom->sync_live() ; - - return quit ; -} -//_____________________________________________________________________________ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_controls.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_controls.cpp deleted file mode 100644 index 55c9fc35d2..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_controls.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/** - * @file glui_controls.cpp - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.1 - * @date 30/05/2006 - * - * @brief Octree graphical interface: interface controls - */ -//________________________________________________ - - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma implementation "viz_glui_defs.h" -#endif // WIN32 - - -#include "viz_glui_defs.h" -#include "implfuns.h" - - -//_____________________________________________________________________________ -// declarations of this file - -// main object: octree -Octree octree ; - -// switch between implicit funciont or volumetric data -int impl_data = SWITCH_DATA ; - -// octree implicit data wrapper -data_func *dat_func = NULL ; - -// octree data file wrapper -data_file *dat_data = NULL ; - - -// maximal level of the tree -int max_level = 4; - -// isovalue -float iso_val = 0.0 ; - -// curvature threshold -float curv_thres = 0.5 ; - -// selected implicit function -int curr_fun = 0 ; - - -//----------------------------------------------------------------------------- - -// main glui class: (right) side panel -GLUI *glui_side = NULL ; - -// bottom panel -GLUI *glui_bottom = NULL ; - -// name of the import file -GLUI_FileBrowser *file_browser ; - -// iso file -GLUI_String filename ; - -// formula of the implicit function -GLUI_String impl_fun ; - -//----------------------------------------------------------------------------- - -// control events callback -void control_cb( int control ) ; - -// create side panel -void create_side_panel() ; - -// create bottom panel -void create_bottom_panel() ; - -/// set file extension -int set_ext( const char ext[4] ) ; - -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// control events callback -void control_cb( int control ) -//----------------------------------------------------------------------------- -{ - data_access *ref = NULL ; - switch( impl_data ) - { - case SWITCH_IMPL : ref = dat_func ; break ; - case SWITCH_DATA : ref = dat_data ; break ; - } - - switch( control ) - { - case SET_IMPL_DATA_ID : - switch( impl_data ) - { - case SWITCH_IMPL : delete dat_func ; dat_func = new data_func ( max_level, iso_val, impl_fun ) ; break ; - case SWITCH_DATA : delete dat_data ; dat_data = new data_file ( max_level, iso_val, filename.c_str() ) ; break ; - } - break ; - - case SET_VAL_ID : - if( !ref ) break ; - ref->_max_level = max_level ; - ref->_iso_val = iso_val ; - octree.set_impl( ref ) ; - octree.check() ; - break ; - - case REFINE_ID : - if( !ref ) break ; - ref->_max_level = max_level ; - ref->_iso_val = iso_val ; - octree.clear() ; - octree.refine( ref ) ; - octree.set_impl( ref ) ; - octree.check() ; - break ; - - case ADAPT_ID : - if( !ref ) break ; - ref->_max_level = max_level ; - ref->_iso_val = iso_val ; - octree.adapt( ref ) ; - octree.set_impl( ref ) ; - octree.check() ; - break ; - - case ISO_BUILD_ID : - if( !ref ) break ; - ref->_iso_val = iso_val ; - octree.build_isosurface(ref) ; - octree.mc().writeOFF("iso.off") ; - octree.check() ; - break ; - - // set implicit function - case FUN_ID : - if( curr_fun == 0 ) break ; - impl_fun.clear() ; - impl_fun = fun_def[curr_fun] ; - control_cb( SET_IMPL_DATA_ID ) ; - control_cb( ADAPT_ID ) ; - glui_bottom->sync_live() ; - break ; - - - // load/save viewpoint - case SAVE_VIEWPORT_ID : save_viewport() ; break ; - - case LOAD_VIEWPORT_ID : load_viewport() ; glui_bottom->sync_live() ; break ; - - // reset rotation - case RESET_ROTATION_ID : - view_rotate[ 0] = view_rotate[ 5] = view_rotate[10] = view_rotate[15] = 1.0f ; - view_rotate[ 1] = view_rotate[ 2] = view_rotate[ 3] = view_rotate[ 4] = 0.0f ; - view_rotate[ 6] = view_rotate[ 7] = view_rotate[ 8] = view_rotate[ 9] = 0.0f ; - view_rotate[11] = view_rotate[12] = view_rotate[13] = view_rotate[14] = 0.0f ; - break ; - - // reset translation - case RESET_TRANSLATION_ID : obj_pos[0] = obj_pos[1] = 0.0f ; break ; - // reset zoom - case RESET_ZOOM_ID : obj_pos[2] = 0.0f ; break ; - - // changed a parameter - case REDRAW_ID : break ; - - // changed a parameter - case FILENAME_ID : filename = file_browser->current_dir + file_browser->get_file() ; - - // orthographic/perspective projection - case PROJ_ID : reshape (0,0) ; break ; - - case EXIT_ID : - delete dat_func ; - delete dat_data ; - octree.clear() ; - exit(0) ; - break ; - - default : break ; - } - - ::glutPostRedisplay(); -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// create side panel -void create_side_panel() -//----------------------------------------------------------------------------- -{ - glui_side = NULL ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// create bottom panel -void create_bottom_panel() -//----------------------------------------------------------------------------- -{ - GLUI_Rollout *roll ; - GLUI_EditText *text ; - GLUI_Rotation *rot ; - GLUI_Translation *trans; - GLUI_RadioGroup *radio; - GLUI_Listbox *list ; - GLUI_Scrollbar *sb ; - - glui_bottom = GLUI_Master.create_glui("controls") ; //create_glui_subwindow( main_window, GLUI_SUBWINDOW_BOTTOM ); - - //--------------------------------------------------// - - file_browser = new GLUI_FileBrowser( glui_bottom, "iso file", false, FILENAME_ID, control_cb ) ; - file_browser->current_dir = "data" ; - file_browser->fbreaddir( "data" ) ; - - filename = "data/engine.iso.gz"; - text = glui_bottom ->add_edittext( "iso file" , filename ) ; - text->set_w( 200 ) ; - - list = glui_bottom->add_listbox( "Implicit Functions:", &curr_fun, FUN_ID, control_cb ); - for( int i=0; iadd_item( i, fun_list[i] ); - - impl_fun = ""; - text = glui_bottom ->add_edittext( "impl fun" , impl_fun ) ; - text->set_w( 200 ) ; - - - //--------------------------------------------------// - // - roll = glui_bottom ->add_rollout( "iso value", true ); - sb = new GLUI_Scrollbar( roll, "iso value in [-1,1]",GLUI_SCROLL_HORIZONTAL, &iso_val, ADAPT_ID,control_cb); - sb->set_float_limits(-1,1); - sb->set_speed( .005f ); - - roll = glui_bottom ->add_rollout( "level in [2,7]", true ); - sb = new GLUI_Scrollbar( roll, "level", GLUI_SCROLL_HORIZONTAL, &max_level, ADAPT_ID, control_cb); - sb->set_int_limits(2,7); - sb->set_speed( .005f ); - - //--------------------------------------------------// - glui_bottom->add_column( true ); - radio = glui_bottom->add_radiogroup( &impl_data, SET_IMPL_DATA_ID, control_cb ) ; - glui_bottom->add_radiobutton_to_group( radio, "Implicit function" ) ; - glui_bottom->add_radiobutton_to_group( radio, "Direct data file" ) ; - - //--------------------------------------------------// - - - glui_bottom ->add_button ( "load" , SET_IMPL_DATA_ID, control_cb ) ; - glui_bottom ->add_button ( "set values", SET_VAL_ID , control_cb ) ; - glui_bottom ->add_button ( "refine" , REFINE_ID, control_cb ) ; - glui_bottom ->add_button ( "adapt" , ADAPT_ID , control_cb ) ; - - - //--------------------------------------------------// - // display element - glui_bottom->add_checkbox( "ortho" , &ortho , PROJ_ID , control_cb ); - glui_bottom->add_checkbox( "octree" , &show_octree , REDRAW_ID, control_cb ); - glui_bottom->add_checkbox( "nodes" , &show_nodes , REDRAW_ID, control_cb ); - glui_bottom->add_checkbox( "dual" , &show_dual , REDRAW_ID, control_cb ); - glui_bottom->add_checkbox( "surface" , &show_iso , REDRAW_ID, control_cb ); - glui_bottom->add_checkbox( "dir surf" , &show_direct_iso , SET_VAL_ID, control_cb ); - glui_bottom->add_checkbox( "dir sur w", &show_direct_iso_wire, SET_VAL_ID, control_cb ); - - - glui_bottom ->add_button ( "Isosurface", ISO_BUILD_ID, control_cb ) ; - -// glui_bottom->add_button( "Redraw", REDRAW_ID, control_cb ) ; - - glui_bottom ->add_button( "Open View", LOAD_VIEWPORT_ID, control_cb ) ; - glui_bottom ->add_button( "Save View", SAVE_VIEWPORT_ID, control_cb ) ; - glui_bottom ->add_button( "Quit", EXIT_ID, control_cb ); - glui_bottom->add_column( true ); - - - glui_bottom->add_column( true ); - - //--------------------------------------------------// - // position - roll = glui_bottom ->add_rollout( "3D position", true ); - objects_rot = glui_bottom->add_rotation_to_panel( roll, "Objects", view_rotate ); - objects_rot->set_spin( 1.0f ); - glui_bottom->add_button_to_panel( roll, "Reset", RESET_ROTATION_ID, control_cb ) ; - glui_bottom->add_column_to_panel( roll, false ); - - objects_mv = glui_bottom->add_translation_to_panel( roll, "Objects XY", GLUI_TRANSLATION_XY, obj_pos ); - objects_mv->set_speed( .005f ); - glui_bottom->add_button_to_panel( roll, "Reset", RESET_TRANSLATION_ID, control_cb ) ; - glui_bottom->add_column_to_panel( roll, false ); - - objects_zm = glui_bottom->add_translation_to_panel( roll, "Objects Z", GLUI_TRANSLATION_Z, &obj_pos[2] ); - objects_zm->set_speed( .005f ); - glui_bottom->add_button_to_panel( roll, "Reset", RESET_ZOOM_ID, control_cb ) ; - - - //--------------------------------------------------// - // Lights - roll = glui_bottom->add_rollout( "Lights", true ); - rot = glui_bottom->add_rotation_to_panel( roll, "Blue Light", light0_rotation ); - rot->set_spin( .82f ); - - rot = glui_bottom->add_rotation_to_panel( roll, "Orange Light", light1_rotation ); - rot->set_spin( .82f ); - - - glui_bottom->add_column_to_panel( roll, false ); - - glui_bottom->add_checkbox_to_panel( roll, "On", &light0_enabled ); - text = glui_bottom->add_edittext_to_panel( roll, "Id (%)", GLUI_EDITTEXT_INT, &light0_intensity ); - text->set_int_limits( 0, 100 ); - text->set_w(4) ; - text = glui_bottom->add_edittext_to_panel( roll, "Is (%)", GLUI_EDITTEXT_INT, &light0_intensity2 ); - text->set_int_limits( 0, 100 ); - text->set_w(4) ; - - glui_bottom->add_checkbox_to_panel( roll, "On", &light1_enabled ); - text = glui_bottom->add_edittext_to_panel( roll, "Id (%)", GLUI_EDITTEXT_INT, &light1_intensity ); - text->set_int_limits( 0, 100 ); - text->set_w(4) ; - text = glui_bottom->add_edittext_to_panel( roll, "Is (%)", GLUI_EDITTEXT_INT, &light1_intensity2 ); - text->set_int_limits( 0, 100 ); - text->set_w(4) ; -} -//_____________________________________________________________________________ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_defs.h b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_defs.h deleted file mode 100644 index b9760f9b81..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_defs.h +++ /dev/null @@ -1,361 +0,0 @@ -/** - * @file glui_defs.h - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.1 - * @date 30/05/2006 - * - * @brief Octree graphical interface - */ -//________________________________________________ - - -#pragma once - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma interface -#endif // WIN32 - - -#include // openGL user interface - - -#define OCTREE_SWITCH 4 - -//_____________________________________________________________________________ -// octree switch -#ifdef OCTREE_SWITCH -# if OCTREE_SWITCH==0 -# define OCTREE_PTR 1 -# elif OCTREE_SWITCH==1 -# define OCTREE_HASH 1 -# elif OCTREE_SWITCH==2 -# define OCTREE_OPT 1 -# elif OCTREE_SWITCH==3 -# define OCTREE_LEAF 1 -# elif OCTREE_SWITCH==4 -# define OCTREE_MEM 1 -# endif // OCTREE_SWITCH -#endif // OCTREE_SWITCH - - -// switch values between pointer and hash octree -#if !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM -// # define OCTREE_PTR 1 -// # define OCTREE_HASH 1 -# define OCTREE_OPT 1 -// # define OCTREE_LEAF 1 -// # define OCTREE_MEM 1 -#endif // !OCTREE_PTR && !OCTREE_HASH && !OCTREE_OPT && !OCTREE_LEAF && !OCTREE_MEM - - -#ifdef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_OPT -# undef OCTREE_LEAF -# undef OCTREE_MEM -# define OCTREE_STRING "pointer octree" -# include "ptr_octree.h" -/// octree type -typedef PtrOctree Octree ; -#endif //OCTREE_PTR - - -#ifdef OCTREE_HASH -# undef OCTREE_PTR -# undef OCTREE_OPT -# undef OCTREE_LEAF -# undef OCTREE_MEM -# define OCTREE_STRING "hash octree" -# include "hash_octree.h" -/// octree type -typedef HashOctree Octree ; -#endif //OCTREE_HASH - - -#ifdef OCTREE_OPT -# undef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_LEAF -# undef OCTREE_MEM -# define OCTREE_STRING "optimized octree" -# include "opt_octree.h" -/// octree type -typedef OptOctree Octree ; -#endif //OCTREE_OPT - - -#ifdef OCTREE_LEAF -# undef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_OPT -# undef OCTREE_MEM -# define OCTREE_STRING "leaf octree" -# include "leaf_octree.h" -/// octree type -typedef LeafOctree Octree ; -#endif //OCTREE_LEAF - - -#ifdef OCTREE_MEM -# undef OCTREE_PTR -# undef OCTREE_HASH -# undef OCTREE_OPT -# undef OCTREE_LEAF -# define OCTREE_STRING "mem octree" -# include "mem_octree.h" -/// octree type -typedef MemOctree Octree ; -#endif //OCTREE_MEM - - - -#ifdef _DEBUG -#define PRINT_GL_DEBUG { if( ::glGetError() != GL_NO_ERROR ) printf( "openGL watch at line %d: %s\n", __LINE__, ::gluErrorString( ::glGetError() ) ) ; } -#else // _DEBUG -#define PRINT_GL_DEBUG {} -#endif // _DEBUG - - - -//_____________________________________________________________________________ -// Main objects - - /// main object: octree - extern Octree octree ; - - /// switch between implicit funciont or volumetric data - extern int impl_data ; - - /// switch values between implicit funciont or volumetric data - enum { SWITCH_IMPL = 0, SWITCH_DATA = 1 } ; - - /// octree implicit data wrapper - extern data_func *dat_func ; - - /// octree data file wrapper - extern data_file *dat_data ; - - /// maximal level of the tree - extern int max_level ; - - /// isovalue - extern float iso_val ; - - -//----------------------------------------------------------------------------- -// Display elements - - /// display element switch: octree wireframe - extern int show_octree ; - /// display element switch: octree cells' centers - extern int show_nodes ; - /// display element switch: octree dual - extern int show_dual ; - /// display element switch: isosurface of the field - extern int show_iso ; - /// display element switch: direct drawing isosurface of the field - extern int show_direct_iso ; - /// display element switch: direct drawing wire isosurface of the field - extern int show_direct_iso_wire ; - - -//----------------------------------------------------------------------------- -// GLUI windows - - /// main window id - extern int main_window ; - - /// main glui class: (right) side panel - extern GLUI *glui_side ; - - /// bottom panel - extern GLUI *glui_bottom ; - - -/// create side panel -void create_side_panel() ; - -/// create bottom panel -void create_bottom_panel() ; - -/// control events callback -void control_cb( int control ) ; - -/// parse command line -bool parse_command_line(int argc, char* argv[]) ; - - -//----------------------------------------------------------------------------- -// Lights - - /// enable blue light - extern int light0_enabled ; - - /// enable orange light - extern int light1_enabled ; - - /// blue light intensity - extern int light0_intensity ; - - /// orange light intensity - extern int light1_intensity ; - - /// blue light intensity (specular) - extern int light0_intensity2 ; - - /// orange light intensity (specular) - extern int light1_intensity2 ; - - /// blue light diffuse color - extern float light0_diffuse[4] ; - - /// orange light diffuse color - extern float light1_diffuse[4] ; - - /// blue light position - extern float light0_rotation[16] ; - - /// orange light position - extern float light1_rotation[16] ; - - -//----------------------------------------------------------------------------- -// mouse and object movements - - /// motion type (-1 -> no motion, 0 -> rotate, 1 -> zoom, 2 -> translate) - extern int motion_type ; - - /// window trackball - extern GLUI_Rotation mouse_rot ; - /// panel trackball - extern GLUI_Rotation *objects_rot ; - /// window translation - extern GLUI_Translation mouse_mv ; - /// panel translation - extern GLUI_Translation *objects_mv ; - /// window zoom - extern GLUI_Translation mouse_zm ; - /// panel zoom - extern GLUI_Translation *objects_zm ; - - /// number of calls for updating the GLUI control - extern int ncalls ; - - /// export movie switch - extern int export_movie ; - - /// automatic rotation - extern int auto_rotate ; - - /// automatic x translation - extern int auto_translate_x ; - - /// automatic y translation - extern int auto_translate_y ; - - /// automatic zoom - extern int auto_zoom ; - - /// automatic plane - extern int auto_translate_d ; - - /// mouse x position - extern int mouse_x ; - - /// mouse y position - extern int mouse_y ; - -/// init mouse and window controls -void init_trackballs() ; - -/// mouse events tracking -void mouse(int button, int button_state, int x, int y ) ; - -/// mouse motion tracking -void motion(int x, int y ) ; - -/// keyboard events -void keyboard(unsigned char key, int x, int y); - -//----------------------------------------------------------------------------- -// implicit function - - /// implicit function formula - extern GLUI_String impl_fun ; - - -//----------------------------------------------------------------------------- -// i/o filenames - - /// iso file - extern GLUI_String filename ; - - /// file browser - extern GLUI_FileBrowser *file_browser ; - - - -//----------------------------------------------------------------------------- -// drawing parameters - - /// orthographic / perspective projection switch - extern int ortho ; - /// object rotation - extern float view_rotate[16] ; - /// object translation - extern float obj_pos [3 ] ; - - /// point size - extern int point_size; - -/// 3D projection matrix -void project( int o, float sx, float sy, int &tx, int &ty, int &tw, int &th ) ; - -/// window resizing -void reshape( int x, int y ) ; - -/// main drawing function -void display() ; - -/// print screen -void export_png() ; - -/// load viewport -void load_viewport() ; -/// save viewport -void save_viewport() ; - - -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -/// Callback ids -enum -{ - SET_IMPL_DATA_ID , - SET_VAL_ID , - REFINE_ID , - ADAPT_ID , - ISO_BUILD_ID , - SEARCH_ID , - FUN_ID , - - SAVE_VIEWPORT_ID , - LOAD_VIEWPORT_ID , - - RESET_ROTATION_ID , - RESET_TRANSLATION_ID , - RESET_ZOOM_ID , - - REDRAW_ID , - FILENAME_ID , - PROJ_ID , - - EXIT_ID -}; -//_____________________________________________________________________________ - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_draws.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_draws.cpp deleted file mode 100644 index 5a8662d386..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_draws.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/** - * @file glui_draws.cpp - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.1 - * @date 30/05/2006 - * - * @brief Octree graphical interface: drawing commands - */ -//________________________________________________ - - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma implementation "viz_glui_defs.h" -#endif // WIN32 - - -#include "viz_glui_defs.h" - - -//_____________________________________________________________________________ -// declarations of this file - - -// display element switches -int show_octree = 1 ; -int show_nodes = 0 ; -int show_dual = 0 ; -int show_iso = 0 ; -int show_direct_iso = 0 ; -int show_direct_iso_wire = 0 ; - -// orthographic / perspective projection -int ortho = 0 ; - -// object transformation -float view_rotate[16] = { 1.0f,0.0f,0.0f,0.0f, 0.0f,1.0f,0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f, 0.0f,0.0f,0.0f,1.0f }; -float obj_pos [3 ] = { 0.0f, 0.0f, 0.0f }; - - -//----------------------------------------------------------------------------- -// lights -int light0_enabled = 1 ; -int light1_enabled = 0 ; -int light0_intensity = 100 ; -int light1_intensity = 60 ; -int light0_intensity2 = 50 ; -int light1_intensity2 = 30 ; -GLfloat light0_diffuse [ 4] = {.7f, .7f, 1.0f, 1.0f}; -GLfloat light1_diffuse [ 4] = {.9f, .7f, 0.2f, 1.0f}; -GLfloat light0_position[ 4] = {.5f, .5f, 10.0f, 0.0f}; -GLfloat light1_position[ 4] = {-1.0f, -1.0f, 10.0f, 0.0f}; -GLfloat light0_rotation[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; -GLfloat light1_rotation[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; - -//----------------------------------------------------------------------------- - -// 3D projection matrix -void project( int o, float sx, float sy, int &tx, int &ty, int &tw, int &th ) ; - -// window resizing -void reshape( int x, int y ) ; - -// main drawing function -void display() ; - -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// 3D projection matrix -void project( int o, float sx, float sy, int &tx, int &ty, int &tw, int &th ) -//----------------------------------------------------------------------------- -{ - // get viewport - GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th ); - - tw = (int)( tw * sx ); - th = (int)( th * sy ); - ::glViewport( tx, ty, tw, th ); - - // sets the projection matrix - ::glMatrixMode(GL_PROJECTION); - ::glLoadIdentity(); - - // sets the viewport - if( o ) - { - if( th > tw ) - ::glOrtho( -1.2, 1.2, -1.2*(double)th/tw, 1.2*(double)th/tw, 0.0, 10.0 ) ; - else - ::glOrtho( -1.2*(double)tw/th, 1.2*(double)tw/th, -1.2, 1.2, 0.0, 10.0 ) ; - } - else - ::gluPerspective( 45.0, th>0?(double)tw/th:1.0, 0.5, 10.0 ); - - ::gluLookAt( 0.0f,0.0f,3.0f, 0.0f,0.0f,0.5f, 0.0f,1.0f,0.0f ) ; - - // switch to the modelview matrix - ::glMatrixMode( GL_MODELVIEW ); - ::glLoadIdentity(); -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// window resizing -void reshape( int x, int y ) -//----------------------------------------------------------------------------- -{ - ::glutSetWindow(main_window); - - int tx, ty, tw, th; - project( ortho, 1.0f, 1.0f, tx, ty, tw, th ) ; - - // sets the window trackball - mouse_rot.set_w( tw ) ; - mouse_rot.set_h( th ) ; - mouse_mv .set_w( tw ) ; - mouse_mv .set_h( th ) ; - mouse_zm .set_w( tw ) ; - mouse_zm .set_h( th ) ; - - // redisplay - ::glutPostRedisplay(); -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// main drawing function -void display() -//----------------------------------------------------------------------------- -{ - ::glutSetWindow(main_window); - - // clear screen - ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - if( !true ) { ::glutSwapBuffers(); return ; } - - int tx, ty, tw, th ; - project( ortho, 1.0f, 1.0f, tx, ty, tw, th ) ; - - ::glEnable( GL_DEPTH_TEST ); - ::glShadeModel(GL_SMOOTH); - ::glEnable(GL_LIGHTING); - - //::glDisable (GL_LIGHTING); - float val[3] ; - if ( light0_enabled ) - { - ::glEnable( GL_LIGHT0 ) ; - - val[0] = light0_diffuse[0] * light0_intensity / 100 ; - val[1] = light0_diffuse[1] * light0_intensity / 100 ; - val[2] = light0_diffuse[2] * light0_intensity / 100 ; - ::glLightfv(GL_LIGHT0, GL_DIFFUSE, val ); - - val[0] = light0_diffuse[0] * light0_intensity2 / 100 ; - val[1] = light0_diffuse[1] * light0_intensity2 / 100 ; - val[2] = light0_diffuse[2] * light0_intensity2 / 100 ; - ::glLightfv(GL_LIGHT0, GL_SPECULAR, val ); - const GLfloat light0_ambient[4] = {0.1f, 0.1f, 0.3f, 1.0f}; - ::glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); - - - ::glLoadIdentity(); - ::glMultMatrixf( light0_rotation ); - ::glLightfv(GL_LIGHT0, GL_POSITION, light0_position); - - } - else - ::glDisable( GL_LIGHT0 ); - - if ( light1_enabled ) - { - ::glEnable( GL_LIGHT1 ); - - val[0] = light1_diffuse[0] * light1_intensity / 100 ; - val[1] = light1_diffuse[1] * light1_intensity / 100 ; - val[2] = light1_diffuse[2] * light1_intensity / 100 ; - ::glLightfv(GL_LIGHT1, GL_DIFFUSE, val ); - - val[0] = light1_diffuse[0] * light1_intensity2 / 100 ; - val[1] = light1_diffuse[1] * light1_intensity2 / 100 ; - val[2] = light1_diffuse[2] * light1_intensity2 / 100 ; - ::glLightfv(GL_LIGHT1, GL_SPECULAR, val ); - const GLfloat light1_ambient[4] = {0.1f, 0.1f, 0.3f, 1.0f}; - ::glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); - - ::glLoadIdentity(); - ::glMultMatrixf( light1_rotation ); - ::glLightfv(GL_LIGHT1, GL_POSITION, light1_position); - - } - else - ::glDisable( GL_LIGHT1 ); - - // transformation matrix - ::glLoadIdentity(); - ::glTranslatef( obj_pos[0], obj_pos[1], obj_pos[2] ); - if( ortho ) - { - ::glScalef( 1.0+obj_pos[2], 1.0+obj_pos[2], 1.0+obj_pos[2] ) ; - ::glEnable( GL_NORMALIZE ); - } - else - { - ::glDisable( GL_NORMALIZE ); - } - - ::glMultMatrixf( view_rotate ); - ::glTranslatef( -0.5f, -0.5f, -0.5f ); - PRINT_GL_DEBUG ; - -//----------------------------------------------------------------------------- -// 3D display - - data_access *ref = NULL ; - switch( impl_data ) - { - case SWITCH_IMPL : ref = dat_func ; break ; - case SWITCH_DATA : ref = dat_data ; break ; - } - if( ref ) - ::glScalef( ref->_sx, ref->_sy, ref->_sz ) ; - - // octree wireframe - if( show_octree ) - { - ::glDisable( GL_TEXTURE_1D ) ; - ::glLineWidth( 0.5 ) ; - ::glColor3f( 0.3f, 0.3f, 0.5f ) ; - ::glBegin( GL_LINES ) ; - { - octree.draw_wire() ; - } - ::glEnd() ; // GL_LINES - } - - - // cells' centers - if( show_nodes ) - { - ::glEnable( GL_TEXTURE_1D ) ; - ::glPointSize( 4.0 ) ; - ::glColor3f( 0.0f, 0.8f, 0.2f ) ; - ::glBegin( GL_POINTS ) ; - { - octree.draw_centers() ; - } - ::glEnd() ; // GL_POINTS - } - - // octree dual - if( show_dual ) - { - ::glDisable( GL_TEXTURE_1D ) ; - ::glDisable(GL_LIGHTING); - octree.draw_dual() ; - ::glEnable(GL_LIGHTING); - } - - // isosurface of the field - if( show_iso ) - { - ::glDisable( GL_TEXTURE_1D ) ; - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) ; - ::glColor3f( 0.3f, 0.3f, 0.5f ) ; - ::glBegin( GL_TRIANGLES ) ; - octree.draw_iso() ; - ::glEnd() ; // GL_TRIANGLES - - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ; - ::glColor3f( 0.6f, 0.6f, 0.7f ) ; - ::glBegin( GL_TRIANGLES ) ; - octree.draw_iso() ; - ::glEnd() ; // GL_TRIANGLES - } - - if( ref && show_direct_iso_wire ) - { - ::glDisable( GL_TEXTURE_1D ) ; - - ::glDisable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) ; - ::glColor3f( 0.3f, 0.3f, 0.5f ) ; - ::glBegin( GL_TRIANGLES ) ; - octree.direct_draw_isosurface(ref) ; - ::glEnd() ; // GL_TRIANGLES - } - - if( ref && show_direct_iso ) - { - ::glDisable( GL_TEXTURE_1D ) ; - - ::glEnable(GL_LIGHTING); - ::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) ; - ::glColor3f( 0.6f, 0.6f, 0.7f ) ; - ::glBegin( GL_TRIANGLES ) ; - octree.direct_draw_isosurface(ref) ; - ::glEnd() ; // GL_TRIANGLES - } - - PRINT_GL_DEBUG ; - - // next frame - ::glutSwapBuffers(); -} -//_____________________________________________________________________________ - - - - - diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_export.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_export.cpp deleted file mode 100644 index 948cae6ebe..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_export.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/** - * @file glui_export.cpp - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.1 - * @date 20/08/2007 - * - * @brief Example Graphical interface: screen image exporatation - */ -//________________________________________________ - - -#ifndef WIN32 -#pragma implementation "viz_glui_defs.h" -#endif // WIN32 - -#include -#include -#include "viz_glui_defs.h" - - - -//_____________________________________________________________________________ -// declarations of this file - -// set file extension of filename -int set_ext( const char ext[3], char *fn ) ; - -// PPM export -void export_ppm() ; - -// PNG image export -void export_png() ; - -// Viewport save -void save_viewport() ; - -// Viewport load -void load_viewport() ; - -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// set file extension of filename -int set_ext( const char ext[3], char *fn ) -//----------------------------------------------------------------------------- -{ - strcpy( fn, filename.c_str() ) ; - int l = (int)strlen(fn) ; - if( l == 0 ) return 0 ; - if( fn[l-4] != '.' ) - { - strcat( fn, "." ) ; - strcat( fn, ext ) ; - } - else if( strcmp( fn + l-3, ext ) ) - { - fn[l-3] = ext[0] ; - fn[l-2] = ext[1] ; - fn[l-1] = ext[2] ; - } - - return l ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// PPM export -void export_ppm() -//----------------------------------------------------------------------------- -{ - char fn[1024] ; - set_ext( "ppm", fn ) ; - FILE *fp = fopen( fn, "w" ) ; - if( !fp ) return ; - - int tx, ty, tw, th; - glutSetWindow(main_window); - GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th ); - - // read openGL buffer - int buf_size = (tw * th * 3); - unsigned char *buffer = new unsigned char[buf_size] ; - memset(buffer, 0, buf_size * sizeof(unsigned char)) ; - display() ; - glFinish() ; - glPixelStorei( GL_PACK_ALIGNMENT, 1 ); // Force 1-byte alignment - glPixelStorei( GL_PACK_ROW_LENGTH, 0 ); - glPixelStorei( GL_PACK_SKIP_ROWS, 0 ); - glPixelStorei( GL_PACK_SKIP_PIXELS,0 ); - glReadPixels(tx, ty, tw, th, GL_RGB, GL_UNSIGNED_BYTE, buffer); - - // write the header - fprintf(fp, "P6\n%d %d\n", tw, th); - fprintf(fp, "# %s (Affine Surface by Thomas Lewiner)\n", fn ) ; - fprintf(fp, "255\n"); - - // write file - for (int i = 0; i < buf_size; ++i) - fputc( buffer[i], fp ) ; - - delete [] buffer ; - - fclose(fp); - printf( "exported image to PPM file %s\n", fn ) ; - -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// -void export_tga() -//----------------------------------------------------------------------------- -{ - char fn[1024] ; - set_ext("tga", fn) ; - FILE *fp = fopen( fn, "w" ) ; - if (!fp) - return ; - - int tx, ty, tw, th; - glutSetWindow(main_window); - GLUI_Master.get_viewport_area(&tx, &ty, &tw, &th); - - int buf_size = 18 + (tw* th * 3); // HEADER_SIZE ==> 18 - unsigned char* buffer = new unsigned char[buf_size] ; - memset(buffer, 0, buf_size * sizeof(unsigned char)) ; - - // Header - buffer[2] = 2; // Non-compressed - buffer[12] = tw & 255; - buffer[13] = (tw >> 8) & 255 ; - buffer[14] = th & 255; - buffer[15] = (th >> 8) & 255 ; - buffer[16] = 24; // 24 bits per pixel - - // Read openGL buffer - display() ; - glFinish() ; - glPixelStorei(GL_PACK_ALIGNMENT, 1); // Force 1-byte alignment - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_SKIP_ROWS, 0); - glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - glReadPixels(tx, ty, tw, th, GL_RGB, GL_UNSIGNED_BYTE, buffer + 18); - - // Conversion from RGB to BGR - for (int i = 18; i < buf_size; i += 3) - { - unsigned char temp = buffer[i]; - buffer[i] = buffer[i + 2]; - buffer[i + 2] = temp; - } - - // Write file - fwrite(buffer, sizeof(unsigned char), buf_size, fp); - fclose(fp); - delete[] buffer ; - printf("exported image to TGA file %s\n", fn ) ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// -void save_viewport() -//----------------------------------------------------------------------------- -{ - char fn[1024] ; - set_ext( "view", fn ) ; - FILE *fp = fopen( fn, "w" ) ; - if( !fp ) return ; - fprintf( fp, "rotate:\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n", - view_rotate[ 0], view_rotate[ 1], view_rotate[ 2], view_rotate[ 3], - view_rotate[ 4], view_rotate[ 5], view_rotate[ 6], view_rotate[ 7], - view_rotate[ 8], view_rotate[ 9], view_rotate[10], view_rotate[11], - view_rotate[12], view_rotate[13], view_rotate[14], view_rotate[15] ) ; - fprintf( fp, "translate:\t%f %f %f\n", obj_pos[0], obj_pos[1], obj_pos[2] ) ; - - fprintf( fp, "plane rotate:\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f\n\n", - 1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0, 0.0 ) ; - - fprintf( fp, "corner size:\t%f %f\n", 0.0,0.0 ) ; - fprintf( fp, "corner trans:\t%f %f %f\n", 0.0,0.0,1.0 ) ; - - - fprintf( fp, "light 0:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n", - light0_enabled, light0_intensity, light0_intensity2, - light0_diffuse [ 0], light0_diffuse [ 1], light0_diffuse [ 2], light0_diffuse [ 3], - light0_rotation[ 0], light0_rotation[ 1], light0_rotation[ 2], light0_rotation[ 3], - light0_rotation[ 4], light0_rotation[ 5], light0_rotation[ 6], light0_rotation[ 7], - light0_rotation[ 8], light0_rotation[ 9], light0_rotation[10], light0_rotation[11], - light0_rotation[12], light0_rotation[13], light0_rotation[14], light0_rotation[15] ) ; - - fprintf( fp, "light 1:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n", - light1_enabled, light1_intensity, light1_intensity2, - light1_diffuse [ 0], light1_diffuse [ 1], light1_diffuse [ 2], light1_diffuse [ 3], - light1_rotation[ 0], light1_rotation[ 1], light1_rotation[ 2], light1_rotation[ 3], - light1_rotation[ 4], light1_rotation[ 5], light1_rotation[ 6], light1_rotation[ 7], - light1_rotation[ 8], light1_rotation[ 9], light1_rotation[10], light1_rotation[11], - light1_rotation[12], light1_rotation[13], light1_rotation[14], light1_rotation[15] ) ; - - fclose( fp ) ; - - printf("saved viewport to file %s\n", fn ) ; -} -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// -void load_viewport() -//----------------------------------------------------------------------------- -{ - char fn[1024] ; - set_ext("view",fn) ; - FILE* fp = fopen( fn, "r" ) ; - if( !fp ) return ; - fscanf( fp, "rotate: %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f ", - view_rotate + 0, view_rotate + 1, view_rotate + 2, view_rotate + 3, - view_rotate + 4, view_rotate + 5, view_rotate + 6, view_rotate + 7, - view_rotate + 8, view_rotate + 9, view_rotate + 10, view_rotate + 11, - view_rotate + 12, view_rotate + 13, view_rotate + 14, view_rotate + 15 ) ; - fscanf( fp, "translate: %f %f %f ", obj_pos + 0, obj_pos + 1, obj_pos + 2 ) ; - - fscanf ( fp, "plane rotate:\n\t%*f %*f %*f %*f\n\t%*f %*f %*f %*f\n\t%*f %*f %*f %*f\n\t%*f %*f %*f %*f\n\t%*f\n\n" ) ; - - fscanf ( fp, "corner size:\t%*f %*f\n" ) ; - fscanf ( fp, "corner trans:\t%*f %*f %*f\n" ) ; - - - fscanf ( fp, "light 0:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n", - &light0_enabled, &light0_intensity, &light0_intensity2, - light0_diffuse + 0, light0_diffuse + 1, light0_diffuse + 2, light0_diffuse + 3, - light0_rotation + 0, light0_rotation + 1, light0_rotation + 2, light0_rotation + 3, - light0_rotation + 4, light0_rotation + 5, light0_rotation + 6, light0_rotation + 7, - light0_rotation + 8, light0_rotation + 9, light0_rotation + 10, light0_rotation + 11, - light0_rotation + 12, light0_rotation + 13, light0_rotation + 14, light0_rotation + 15 ) ; - - fscanf ( fp, "light 1:\n\t%d %d %d\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\t%f %f %f %f\n\n\n", - &light1_enabled, &light1_intensity, &light1_intensity2, - light1_diffuse + 0, light1_diffuse + 1, light1_diffuse + 2, light1_diffuse + 3, - light1_rotation + 0, light1_rotation + 1, light1_rotation + 2, light1_rotation + 3, - light1_rotation + 4, light1_rotation + 5, light1_rotation + 6, light1_rotation + 7, - light1_rotation + 8, light1_rotation + 9, light1_rotation + 10, light1_rotation + 11, - light1_rotation + 12, light1_rotation + 13, light1_rotation + 14, light1_rotation + 15 ) ; - - fclose( fp ) ; - - printf("loaded viewport from file %s\n", fn ) ; -} -//_____________________________________________________________________________ - - - - - - -//_____________________________________________________________________________ -// PNG export -void export_png() -//----------------------------------------------------------------------------- -{ - char fn[1024] ; - set_ext( "png", fn ) ; - FILE *fp = fopen( fn, "wb" ) ; - if( !fp ) return ; - - int tx, ty, tw, th; - glutSetWindow(main_window); - GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th ); - - // read openGL buffer - int buf_size = (tw * th * 3); - unsigned char *buffer = new unsigned char[buf_size] ; - memset(buffer, 0, buf_size * sizeof(unsigned char)) ; - display() ; - glFinish() ; - glPixelStorei( GL_PACK_ALIGNMENT, 1 ); // Force 1-byte alignment - glPixelStorei( GL_PACK_ROW_LENGTH, 0 ); - glPixelStorei( GL_PACK_SKIP_ROWS, 0 ); - glPixelStorei( GL_PACK_SKIP_PIXELS,0 ); - glReadPixels(tx, ty, tw, th, GL_RGB, GL_UNSIGNED_BYTE, buffer); - - - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL); - png_infop info_ptr = png_create_info_struct(png_ptr); - if (setjmp(png_jmpbuf(png_ptr))) - { - png_destroy_write_struct(&png_ptr, &info_ptr); - fclose(fp); - return; - } - png_init_io(png_ptr, fp); - png_set_IHDR(png_ptr, info_ptr, tw, th, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - png_write_info(png_ptr, info_ptr); - for (int i=0; i - * @author Math Dept, PUC-Rio - * @version 0.1 - * @date 30/05/2006 - * - * @brief Octree graphical interface: commandline parser and main pipeline - */ -//________________________________________________ - - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma implementation "viz_glui_defs.h" -#endif // WIN32 - -#if WIN32 && _DEBUG -#include -#endif // WIN32 && _DEBUG - -#include "viz_glui_defs.h" -#include "hash.h" - - -//_____________________________________________________________________________ -// declarations of this file - -// main window id -int main_window = -1 ; - -// export movie switch -int export_movie = 0 ; - -//----------------------------------------------------------------------------- - -// idle behaviour: redraw constantly -void idle() ; - -//_____________________________________________________________________________ - - - - - -//_____________________________________________________________________________ -// idel behaviour: redraw constantly -void idle() -//----------------------------------------------------------------------------- -{ - if ( ::glutGetWindow() != main_window ) ::glutSetWindow(main_window); - - - if( auto_rotate ) - { - objects_rot->iaction_mouse_down_handler( 0,0 ) ; - objects_rot->iaction_mouse_held_down_handler( 0,0, 1 ) ; - objects_rot->iaction_mouse_held_down_handler( 1,0, 1 ) ; - objects_rot->iaction_mouse_up_handler( 1,0, 1 ) ; - } - - if( auto_translate_x ) - { - obj_pos[0] += auto_translate_x * 0.01f ; - objects_mv->sync_live(0,1) ; - } - - if( auto_translate_y ) - { - obj_pos[1] += auto_translate_y * 0.01f ; - objects_mv->sync_live(0,1) ; - } - - if( auto_zoom ) - { - obj_pos[2] += auto_zoom * 0.01f ; - objects_zm->sync_live(0,1) ; - } - - if( export_movie ) export_png() ; - ::glutPostRedisplay(); -} -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// main -int main(int argc, char* argv[]) -//----------------------------------------------------------------------------- -{ - printf( OCTREE_STRING " (hash %s pointers, %d bits) visualization with:\n\n", (USE_HASH_PTR ? "with" : "without"), HASH_BITS ) ; - - // create main window - ::glutInit( &argc, argv ) ; - ::glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); - ::glutInitWindowPosition( 50, 50 ); - ::glutInitWindowSize( 800, 600 ); - main_window = ::glutCreateWindow( "Dual Octree" ); - - - - //--------------------------------------------------// - // Create the side and bottom subwindow -#ifdef WIN32 - create_bottom_panel() ; - create_side_panel () ; -#else // WIN32 - create_side_panel () ; - create_bottom_panel() ; -#endif // WIN32 - - //--------------------------------------------------// - // set callback functions - ::glutMouseFunc ( mouse ); - ::glutMotionFunc ( motion ); - ::glutDisplayFunc ( display ); - ::glutKeyboardFunc ( keyboard ); - GLUI_Master.set_glutIdleFunc ( idle ); - GLUI_Master.set_glutReshapeFunc( reshape ); - - //--------------------------------------------------// - // init trackball - init_trackballs() ; - - - //--------------------------------------------------// - - ::glEnable( GL_DEPTH_TEST ); - ::glEnable(GL_COLOR_MATERIAL); - ::glDisable(GL_NORMALIZE); - - ::glPolygonOffset( 1.0f, -0.1f ); - ::glEnable(GL_POLYGON_OFFSET_FILL) ; - /* - ::glEnable(GL_ALPHA_TEST); - ::glEnable(GL_BLEND ) ; - ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ; -*/ - ::glClearColor( 1,1,1,1 ); - - ::glEnable(GL_LIGHTING); - const GLfloat light0_ambient[4] = {0.1f, 0.1f, 0.3f, 1.0f}; - ::glEnable(GL_LIGHT0); - ::glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); - ::glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); - - const GLfloat light1_ambient[4] = {0.1f, 0.1f, 0.3f, 1.0f}; - ::glEnable(GL_LIGHT1); - ::glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); - ::glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); - - ::glShadeModel(GL_SMOOTH); - - //--------------------------------------------------// - // texture color map - GLuint colormap_texture; - - // allocate a texture name - ::glGenTextures( 1, &colormap_texture ); - - // select our current texture - ::glBindTexture( GL_TEXTURE_1D, colormap_texture ); - - // select modulate to mix texture with color for shading - ::glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); - - // when texture area is small, bilinear filter the closest mipmap - ::glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - // when texture area is large, bilinear filter the original - ::glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - - // the texture wraps over at the edges (repeat) - ::glTexParameterf( GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP ); - - GLfloat color_jet[3 * 256] = { 0.000000f, 0.000000f, 0.515625f, 0.000000f, 0.000000f, 0.531250f, 0.000000f, 0.000000f, 0.546875f, 0.000000f, 0.000000f, 0.562500f, 0.000000f, 0.000000f, 0.578125f, 0.000000f, 0.000000f, 0.593750f, 0.000000f, 0.000000f, 0.609375f, 0.000000f, 0.000000f, 0.625000f, 0.000000f, 0.000000f, 0.640625f, 0.000000f, 0.000000f, 0.656250f, 0.000000f, 0.000000f, 0.671875f, 0.000000f, 0.000000f, 0.687500f, 0.000000f, 0.000000f, 0.703125f, 0.000000f, 0.000000f, 0.718750f, 0.000000f, 0.000000f, 0.734375f, 0.000000f, 0.000000f, 0.750000f, 0.000000f, 0.000000f, 0.765625f, 0.000000f, 0.000000f, 0.781250f, 0.000000f, 0.000000f, 0.796875f, 0.000000f, 0.000000f, 0.812500f, 0.000000f, 0.000000f, 0.828125f, 0.000000f, 0.000000f, 0.843750f, 0.000000f, 0.000000f, 0.859375f, 0.000000f, 0.000000f, 0.875000f, 0.000000f, 0.000000f, 0.890625f, 0.000000f, 0.000000f, 0.906250f, 0.000000f, 0.000000f, 0.921875f, 0.000000f, 0.000000f, 0.937500f, 0.000000f, 0.000000f, 0.953125f, 0.000000f, 0.000000f, 0.968750f, 0.000000f, 0.000000f, 0.984375f, 0.000000f, 0.000000f, 1.000000f, 0.000000f, 0.015625f, 1.000000f, 0.000000f, 0.031250f, 1.000000f, 0.000000f, 0.046875f, 1.000000f, 0.000000f, 0.062500f, 1.000000f, 0.000000f, 0.078125f, 1.000000f, 0.000000f, 0.093750f, 1.000000f, 0.000000f, 0.109375f, 1.000000f, 0.000000f, 0.125000f, 1.000000f, 0.000000f, 0.140625f, 1.000000f, 0.000000f, 0.156250f, 1.000000f, 0.000000f, 0.171875f, 1.000000f, 0.000000f, 0.187500f, 1.000000f, 0.000000f, 0.203125f, 1.000000f, 0.000000f, 0.218750f, 1.000000f, 0.000000f, 0.234375f, 1.000000f, 0.000000f, 0.250000f, 1.000000f, 0.000000f, 0.265625f, 1.000000f, 0.000000f, 0.281250f, 1.000000f, 0.000000f, 0.296875f, 1.000000f, 0.000000f, 0.312500f, 1.000000f, 0.000000f, 0.328125f, 1.000000f, 0.000000f, 0.343750f, 1.000000f, 0.000000f, 0.359375f, 1.000000f, 0.000000f, 0.375000f, 1.000000f, 0.000000f, 0.390625f, 1.000000f, 0.000000f, 0.406250f, 1.000000f, 0.000000f, 0.421875f, 1.000000f, 0.000000f, 0.437500f, 1.000000f, 0.000000f, 0.453125f, 1.000000f, 0.000000f, 0.468750f, 1.000000f, 0.000000f, 0.484375f, 1.000000f, 0.000000f, 0.500000f, 1.000000f, 0.000000f, 0.515625f, 1.000000f, 0.000000f, 0.531250f, 1.000000f, 0.000000f, 0.546875f, 1.000000f, 0.000000f, 0.562500f, 1.000000f, 0.000000f, 0.578125f, 1.000000f, 0.000000f, 0.593750f, 1.000000f, 0.000000f, 0.609375f, 1.000000f, 0.000000f, 0.625000f, 1.000000f, 0.000000f, 0.640625f, 1.000000f, 0.000000f, 0.656250f, 1.000000f, 0.000000f, 0.671875f, 1.000000f, 0.000000f, 0.687500f, 1.000000f, 0.000000f, 0.703125f, 1.000000f, 0.000000f, 0.718750f, 1.000000f, 0.000000f, 0.734375f, 1.000000f, 0.000000f, 0.750000f, 1.000000f, 0.000000f, 0.765625f, 1.000000f, 0.000000f, 0.781250f, 1.000000f, 0.000000f, 0.796875f, 1.000000f, 0.000000f, 0.812500f, 1.000000f, 0.000000f, 0.828125f, 1.000000f, 0.000000f, 0.843750f, 1.000000f, 0.000000f, 0.859375f, 1.000000f, 0.000000f, 0.875000f, 1.000000f, 0.000000f, 0.890625f, 1.000000f, 0.000000f, 0.906250f, 1.000000f, 0.000000f, 0.921875f, 1.000000f, 0.000000f, 0.937500f, 1.000000f, 0.000000f, 0.953125f, 1.000000f, 0.000000f, 0.968750f, 1.000000f, 0.000000f, 0.984375f, 1.000000f, 0.000000f, 1.000000f, 1.000000f, 0.015625f, 1.000000f, 1.000000f, 0.031250f, 1.000000f, 0.984375f, 0.046875f, 1.000000f, 0.968750f, 0.062500f, 1.000000f, 0.953125f, 0.078125f, 1.000000f, 0.937500f, 0.093750f, 1.000000f, 0.921875f, 0.109375f, 1.000000f, 0.906250f, 0.125000f, 1.000000f, 0.890625f, 0.140625f, 1.000000f, 0.875000f, 0.156250f, 1.000000f, 0.859375f, 0.171875f, 1.000000f, 0.843750f, 0.187500f, 1.000000f, 0.828125f, 0.203125f, 1.000000f, 0.812500f, 0.218750f, 1.000000f, 0.796875f, 0.234375f, 1.000000f, 0.781250f, 0.250000f, 1.000000f, 0.765625f, 0.265625f, 1.000000f, 0.750000f, 0.281250f, 1.000000f, 0.734375f, 0.296875f, 1.000000f, 0.718750f, 0.312500f, 1.000000f, 0.703125f, 0.328125f, 1.000000f, 0.687500f, 0.343750f, 1.000000f, 0.671875f, 0.359375f, 1.000000f, 0.656250f, 0.375000f, 1.000000f, 0.640625f, 0.390625f, 1.000000f, 0.625000f, 0.406250f, 1.000000f, 0.609375f, 0.421875f, 1.000000f, 0.593750f, 0.437500f, 1.000000f, 0.578125f, 0.453125f, 1.000000f, 0.562500f, 0.468750f, 1.000000f, 0.546875f, 0.484375f, 1.000000f, 0.531250f, 0.500000f, 1.000000f, 0.515625f, 0.515625f, 1.000000f, 0.500000f, 0.531250f, 1.000000f, 0.484375f, 0.546875f, 1.000000f, 0.468750f, 0.562500f, 1.000000f, 0.453125f, 0.578125f, 1.000000f, 0.437500f, 0.593750f, 1.000000f, 0.421875f, 0.609375f, 1.000000f, 0.406250f, 0.625000f, 1.000000f, 0.390625f, 0.640625f, 1.000000f, 0.375000f, 0.656250f, 1.000000f, 0.359375f, 0.671875f, 1.000000f, 0.343750f, 0.687500f, 1.000000f, 0.328125f, 0.703125f, 1.000000f, 0.312500f, 0.718750f, 1.000000f, 0.296875f, 0.734375f, 1.000000f, 0.281250f, 0.750000f, 1.000000f, 0.265625f, 0.765625f, 1.000000f, 0.250000f, 0.781250f, 1.000000f, 0.234375f, 0.796875f, 1.000000f, 0.218750f, 0.812500f, 1.000000f, 0.203125f, 0.828125f, 1.000000f, 0.187500f, 0.843750f, 1.000000f, 0.171875f, 0.859375f, 1.000000f, 0.156250f, 0.875000f, 1.000000f, 0.140625f, 0.890625f, 1.000000f, 0.125000f, 0.906250f, 1.000000f, 0.109375f, 0.921875f, 1.000000f, 0.093750f, 0.937500f, 1.000000f, 0.078125f, 0.953125f, 1.000000f, 0.062500f, 0.968750f, 1.000000f, 0.046875f, 0.984375f, 1.000000f, 0.031250f, 1.000000f, 1.000000f, 0.015625f, 1.000000f, 1.000000f, 0.000000f, 1.000000f, 0.984375f, 0.000000f, 1.000000f, 0.968750f, 0.000000f, 1.000000f, 0.953125f, 0.000000f, 1.000000f, 0.937500f, 0.000000f, 1.000000f, 0.921875f, 0.000000f, 1.000000f, 0.906250f, 0.000000f, 1.000000f, 0.890625f, 0.000000f, 1.000000f, 0.875000f, 0.000000f, 1.000000f, 0.859375f, 0.000000f, 1.000000f, 0.843750f, 0.000000f, 1.000000f, 0.828125f, 0.000000f, 1.000000f, 0.812500f, 0.000000f, 1.000000f, 0.796875f, 0.000000f, 1.000000f, 0.781250f, 0.000000f, 1.000000f, 0.765625f, 0.000000f, 1.000000f, 0.750000f, 0.000000f, 1.000000f, 0.734375f, 0.000000f, 1.000000f, 0.718750f, 0.000000f, 1.000000f, 0.703125f, 0.000000f, 1.000000f, 0.687500f, 0.000000f, 1.000000f, 0.671875f, 0.000000f, 1.000000f, 0.656250f, 0.000000f, 1.000000f, 0.640625f, 0.000000f, 1.000000f, 0.625000f, 0.000000f, 1.000000f, 0.609375f, 0.000000f, 1.000000f, 0.593750f, 0.000000f, 1.000000f, 0.578125f, 0.000000f, 1.000000f, 0.562500f, 0.000000f, 1.000000f, 0.546875f, 0.000000f, 1.000000f, 0.531250f, 0.000000f, 1.000000f, 0.515625f, 0.000000f, 1.000000f, 0.500000f, 0.000000f, 1.000000f, 0.484375f, 0.000000f, 1.000000f, 0.468750f, 0.000000f, 1.000000f, 0.453125f, 0.000000f, 1.000000f, 0.437500f, 0.000000f, 1.000000f, 0.421875f, 0.000000f, 1.000000f, 0.406250f, 0.000000f, 1.000000f, 0.390625f, 0.000000f, 1.000000f, 0.375000f, 0.000000f, 1.000000f, 0.359375f, 0.000000f, 1.000000f, 0.343750f, 0.000000f, 1.000000f, 0.328125f, 0.000000f, 1.000000f, 0.312500f, 0.000000f, 1.000000f, 0.296875f, 0.000000f, 1.000000f, 0.281250f, 0.000000f, 1.000000f, 0.265625f, 0.000000f, 1.000000f, 0.250000f, 0.000000f, 1.000000f, 0.234375f, 0.000000f, 1.000000f, 0.218750f, 0.000000f, 1.000000f, 0.203125f, 0.000000f, 1.000000f, 0.187500f, 0.000000f, 1.000000f, 0.171875f, 0.000000f, 1.000000f, 0.156250f, 0.000000f, 1.000000f, 0.140625f, 0.000000f, 1.000000f, 0.125000f, 0.000000f, 1.000000f, 0.109375f, 0.000000f, 1.000000f, 0.093750f, 0.000000f, 1.000000f, 0.078125f, 0.000000f, 1.000000f, 0.062500f, 0.000000f, 1.000000f, 0.046875f, 0.000000f, 1.000000f, 0.031250f, 0.000000f, 1.000000f, 0.015625f, 0.000000f, 1.000000f, 0.000000f, 0.000000f, 0.984375f, 0.000000f, 0.000000f, 0.968750f, 0.000000f, 0.000000f, 0.953125f, 0.000000f, 0.000000f, 0.937500f, 0.000000f, 0.000000f, 0.921875f, 0.000000f, 0.000000f, 0.906250f, 0.000000f, 0.000000f, 0.890625f, 0.000000f, 0.000000f, 0.875000f, 0.000000f, 0.000000f, 0.859375f, 0.000000f, 0.000000f, 0.843750f, 0.000000f, 0.000000f, 0.828125f, 0.000000f, 0.000000f, 0.812500f, 0.000000f, 0.000000f, 0.796875f, 0.000000f, 0.000000f, 0.781250f, 0.000000f, 0.000000f, 0.765625f, 0.000000f, 0.000000f, 0.750000f, 0.000000f, 0.000000f, 0.734375f, 0.000000f, 0.000000f, 0.718750f, 0.000000f, 0.000000f, 0.703125f, 0.000000f, 0.000000f, 0.687500f, 0.000000f, 0.000000f, 0.671875f, 0.000000f, 0.000000f, 0.656250f, 0.000000f, 0.000000f, 0.640625f, 0.000000f, 0.000000f, 0.625000f, 0.000000f, 0.000000f, 0.609375f, 0.000000f, 0.000000f, 0.593750f, 0.000000f, 0.000000f, 0.578125f, 0.000000f, 0.000000f, 0.562500f, 0.000000f, 0.000000f, 0.546875f, 0.000000f, 0.000000f, 0.531250f, 0.000000f, 0.000000f, 0.515625f, 0.000000f, 0.000000f }; - ::glTexImage1D( GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_RGB, GL_FLOAT, color_jet ) ; - - //--------------------------------------------------// - // Parse command line - bool quit = parse_command_line(argc, argv) ; - - //--------------------------------------------------// - // GLUT main loop - if( !quit ) ::glutMainLoop(); - - return 0 ; -} -//_____________________________________________________________________________ diff --git a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_mouse.cpp b/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_mouse.cpp deleted file mode 100644 index b46fe65f7f..0000000000 --- a/applications/utilities/mesh/generation/cvMesh/cvMeshSurfaceSimplify/fastdualoctree_sgp/viz_glui_mouse.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/** - * @file glui_mouse.cpp - * @author Thomas Lewiner - * @author Math Dept, PUC-Rio - * @version 0.1 - * @date 30/05/2006 - * - * @brief Octree Graphical interface: mouse controls - */ -//________________________________________________ - - -#if !defined(WIN32) || defined(__CYGWIN__) -#pragma implementation "viz_glui_defs.h" -#endif // WIN32 - - -#include "viz_glui_defs.h" - - -//_____________________________________________________________________________ -// declarations of this file - -// motion type (-1 -> no motion, 0 -> rotate, 1 -> zoom, 2 -> translate) -int motion_type = -1 ; - -// panel and window trackballs and sliders -GLUI_Rotation mouse_rot, *objects_rot, *plane_rot ; -GLUI_Translation mouse_mv , *objects_mv , *plane_trans ; -GLUI_Translation mouse_zm , *objects_zm ; - -// number of calls for updating the GLUI control -int ncalls = 0 ; - -//----------------------------------------------------------------------------- - -// init mouse and window controls -void init_trackballs() ; - -// mouse events tracking -void mouse(int button, int button_state, int x, int y ) ; - -// mouse motion tracking -void motion(int x, int y ) ; - -// automatic rotation -int auto_rotate = 0 ; - -// automatic x translation -int auto_translate_x = 0 ; - -// automatic y translation -int auto_translate_y = 0 ; - -// automatic zoom -int auto_zoom = 0 ; - -// automatic plane -int auto_translate_d = 0 ; - -// mouse x position -int mouse_x = 0 ; - -// mouse y position -int mouse_y = 0 ; - - -//_____________________________________________________________________________ - - - - -//_____________________________________________________________________________ -// init mouse and window controls -void init_trackballs() -//----------------------------------------------------------------------------- -{ - // init trackball - - int tx,ty,tw,th ; - GLUI_Master.get_viewport_area( &tx, &ty, &tw, &th ); - - mouse_rot.set_spin(0.05f) ; - mouse_rot.set_w( tw ) ; - mouse_rot.set_h( th ) ; - mouse_rot.set_ptr_val( view_rotate ); - mouse_rot.init_live() ; - - mouse_mv.set_speed(0.005f) ; - mouse_mv.set_w( tw ) ; - mouse_mv.set_h( th ) ; - mouse_mv.set_ptr_val( obj_pos ); - mouse_mv.init_live() ; - - mouse_mv.trans_type = GLUI_TRANSLATION_XY; - mouse_mv.float_array_size = 2 ; - mouse_mv.hidden = true ; - - mouse_zm.set_speed(0.01f) ; - mouse_zm.set_w( tw ) ; - mouse_zm.set_h( th ) ; - mouse_zm.set_ptr_val( &obj_pos[2] ); - mouse_zm.init_live() ; - - mouse_zm.trans_type = GLUI_TRANSLATION_Z ; - mouse_zm.float_array_size = 1 ; - mouse_zm.hidden = true ; -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// mouse events -void mouse(int button, int button_state, int x, int y ) -//----------------------------------------------------------------------------- -{ - mouse_x = x ; - mouse_y = y ; - - // determine motion type - if ( glutGetModifiers() & GLUT_ACTIVE_CTRL ) motion_type = 1 ; - else if( glutGetModifiers() & GLUT_ACTIVE_SHIFT ) motion_type = 2 ; - else if( glutGetModifiers() & GLUT_ACTIVE_ALT ) motion_type = 3 ; - else motion_type = 0 ; - - switch( motion_type ) - { - // rotation - case 0 : - // line selection - if ( button == GLUT_LEFT_BUTTON){ - if (button_state == GLUT_DOWN ) - { - mouse_rot.init_live() ; - mouse_rot.mouse_down_handler(x,y) ; - } - if ( button_state != GLUT_DOWN ) - { - mouse_rot.mouse_up_handler(x,y,1) ; - motion_type = -1 ; - } - objects_rot->sync_live(0,1) ; - } - if ( button == GLUT_RIGHT_BUTTON && button_state == GLUT_DOWN) - { - } - break ; - - // zoom - case 1 : - if ( button == GLUT_LEFT_BUTTON && button_state == GLUT_DOWN ) - { - mouse_zm.init_live() ; - mouse_zm.glui = glui_bottom ; - mouse_zm.mouse_down_handler(x,y) ; - mouse_zm.glui = NULL ; - - } - if ( button_state != GLUT_DOWN ) - { - mouse_zm.glui = glui_bottom ; - mouse_zm.mouse_up_handler(x,y,1) ; - mouse_zm.glui = NULL ; - motion_type = -1 ; - } - objects_zm->sync_live(0,1) ; - break ; - - // translation - case 2 : - if ( button == GLUT_LEFT_BUTTON && button_state == GLUT_DOWN ) - { - mouse_mv.init_live() ; - mouse_mv.glui = glui_bottom ; - mouse_mv.mouse_down_handler(x,y) ; - mouse_mv.glui = NULL ; - } - if ( button_state != GLUT_DOWN ) - { - mouse_mv.glui = glui_bottom ; - mouse_mv.mouse_up_handler(x,y,1) ; - mouse_mv.glui = NULL ; - motion_type = -1 ; - } - objects_mv->sync_live(0,1) ; - break ; - - // no movement - default : - break ; - } - ncalls = 0 ; -} -//_____________________________________________________________________________ - - -//_____________________________________________________________________________ -// keyboard -void keyboard(unsigned char key, int x, int y) -{ - switch(key) - { - case 's': - export_png(); - break; - - case 'S': - export_movie = !export_movie; - break; - - case 'r' : - if( auto_rotate == -1 ) auto_rotate = 0 ; - else auto_rotate = -1 ; - break ; - - case 'R' : - if( auto_rotate == +1 ) auto_rotate = 0 ; - else auto_rotate = +1 ; - break ; - - case 'D' : - if( auto_translate_d == -1 ) auto_translate_d = 0 ; - else auto_translate_d = -1 ; - break ; - - case 'd' : - if( auto_translate_d == +1 ) auto_translate_d = 0 ; - else auto_translate_d = +1 ; - break ; - - case 'X' : - if( auto_translate_x == -1 ) auto_translate_x = 0 ; - else auto_translate_x = -1 ; - break ; - - case 'x' : - if( auto_translate_x == +1 ) auto_translate_x = 0 ; - else auto_translate_x = +1 ; - break ; - - case 'Y' : - if( auto_translate_y == -1 ) auto_translate_y = 0 ; - else auto_translate_y = -1 ; - break ; - - case 'y' : - if( auto_translate_y == +1 ) auto_translate_y = 0 ; - else auto_translate_y = +1 ; - break ; - - case 'Z' : - if( auto_zoom == -1 ) auto_zoom = 0 ; - else auto_zoom = -1 ; - break ; - - case 'z' : - if( auto_zoom == +1 ) auto_zoom = 0 ; - else auto_zoom = +1 ; - break ; - - default: - break; - } -} -//_____________________________________________________________________________ - - - -//_____________________________________________________________________________ -// motion -void motion(int x, int y ) -//----------------------------------------------------------------------------- -{ - mouse_x = x ; - mouse_y = y ; - - switch( motion_type ) - { - // rotation - case 0 : - mouse_rot.glui = glui_bottom ; - mouse_rot.iaction_mouse_held_down_handler(x,y,1); - mouse_rot.glui = NULL ; - if( ++ncalls > 10 ) { objects_rot->sync_live(0,1) ; ncalls = 0 ; } - break ; - - // zoom - case 1 : - mouse_zm.glui = glui_bottom ; - mouse_zm.iaction_mouse_held_down_handler(x,y,1); - mouse_zm.glui = NULL ; - - if( ++ncalls > 10 ) { objects_zm->sync_live(0,1) ; ncalls = 0 ; } - break ; - - // translation - case 2 : - mouse_mv.glui = glui_bottom ; - mouse_mv.iaction_mouse_held_down_handler(x,y,1); - mouse_mv.glui = NULL ; - - if( ++ncalls > 10 ) { objects_mv->sync_live(0,1) ; ncalls = 0 ; } - break ; - - // no movement - default : - break ; - } - ::glutPostRedisplay() ; -} -//_____________________________________________________________________________